Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
number of tests, all because of the codecs/_multibytecodecs issue described
here (it's not a Py3K issue, just something Py3K discovers):
http://mail.python.org/pipermail/python-dev/2006-April/064051.html

Hye-Shik Chang promised to look for a fix, so no need to fix it here. The
tests that are expected to break are:

test_codecencodings_cn
test_codecencodings_hk
test_codecencodings_jp
test_codecencodings_kr
test_codecencodings_tw
test_codecs
test_multibytecodec

This merge fixes an actual test failure (test_weakref) in this branch,
though, so I believe merging is the right thing to do anyway.
diff --git a/Tools/bgen/bgen/bgenObjectDefinition.py b/Tools/bgen/bgen/bgenObjectDefinition.py
index a802f93..6f9bd53 100644
--- a/Tools/bgen/bgen/bgenObjectDefinition.py
+++ b/Tools/bgen/bgen/bgenObjectDefinition.py
@@ -383,6 +383,8 @@
         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()
@@ -395,7 +397,6 @@
         if self.output_tp_initBody:
             Output("static int %s_tp_init(PyObject *_self, PyObject *_args, PyObject *_kwds)", self.prefix)
             OutLbrace()
-            self.output_tp_initBody_basecall()
             self.output_tp_initBody()
             OutRbrace()
         else:
@@ -425,7 +426,7 @@
         if self.basetype:
             Output("if (%s.tp_new)", self.basetype)
             OutLbrace()
-            Output("if ( (*%s.tp_init)(_self, _args, _kwds) == NULL) return NULL;", self.basetype)
+            Output("if ( (*%s.tp_new)(type, _args, _kwds) == NULL) return NULL;", self.basetype)
             Dedent()
             Output("} else {")
             Indent()
diff --git a/Tools/buildbot/build.bat b/Tools/buildbot/build.bat
index e3b77be..e96323c 100644
--- a/Tools/buildbot/build.bat
+++ b/Tools/buildbot/build.bat
@@ -1,4 +1,5 @@
 @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
diff --git a/Tools/buildbot/external.bat b/Tools/buildbot/external.bat
index 1b032ae..c6d252d 100644
--- a/Tools/buildbot/external.bat
+++ b/Tools/buildbot/external.bat
@@ -12,3 +12,24 @@
 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

 )

+

+@rem OpenSSL

+if not exist openssl-0.9.8a svn export http://svn.python.org/projects/external/openssl-0.9.8a

+

+@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

+)

+

+@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

diff --git a/Tools/buildbot/kill_python.bat b/Tools/buildbot/kill_python.bat
new file mode 100644
index 0000000..d78b6d4
--- /dev/null
+++ b/Tools/buildbot/kill_python.bat
@@ -0,0 +1,3 @@
+cd Tools\buildbot
+nmake /C /S /f kill_python.mak
+kill_python.exe
diff --git a/Tools/buildbot/kill_python.c b/Tools/buildbot/kill_python.c
new file mode 100644
index 0000000..ebc9aa4
--- /dev/null
+++ b/Tools/buildbot/kill_python.c
@@ -0,0 +1,56 @@
+/* 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); */
+		if (strstr(path, "build\\pcbuild\\python_d.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);
+	}
+}
diff --git a/Tools/buildbot/kill_python.mak b/Tools/buildbot/kill_python.mak
new file mode 100644
index 0000000..6027d3f
--- /dev/null
+++ b/Tools/buildbot/kill_python.mak
@@ -0,0 +1,2 @@
+kill_python.exe:	kill_python.c
+		cl -nologo -o kill_python.exe kill_python.c psapi.lib
diff --git a/Tools/i18n/msgfmt.py b/Tools/i18n/msgfmt.py
index b4ae3e9..6433131 100755
--- a/Tools/i18n/msgfmt.py
+++ b/Tools/i18n/msgfmt.py
@@ -127,7 +127,7 @@
             section = None
             fuzzy = 0
         # Record a fuzzy mark
-        if l[:2] == '#,' and l.find('fuzzy'):
+        if l[:2] == '#,' and 'fuzzy' in l:
             fuzzy = 1
         # Skip comments
         if l[0] == '#':
diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py
index 6665d36..efa1696 100644
--- a/Tools/msi/msi.py
+++ b/Tools/msi/msi.py
@@ -6,6 +6,7 @@
 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
@@ -23,6 +24,8 @@
 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 *
@@ -62,30 +65,6 @@
 upgrade_code_snapshot='{92A24481-3ECB-40FC-8836-04B7966EC0D5}'
 upgrade_code='{65E6DE48-A358-434D-AA4F-4AF72DB4718F}'
 
-# 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
-}
-
 if snapshot:
     current_version = "%s.%s.%s" % (major, minor, int(time.time()/3600/24))
     product_code = msilib.gen_uuid()
@@ -109,14 +88,10 @@
     '_tkinter.pyd',
     '_msi.pyd',
     '_ctypes.pyd',
-    '_ctypes_test.pyd'
+    '_ctypes_test.pyd',
+    '_sqlite3.pyd'
 ]
 
-if major+minor <= "24":
-    extensions.extend([
-    'zlib.pyd',
-    ])
-
 # Well-known component UUIDs
 # These are needed for SharedDLLs reference counter; if
 # a different UUID was used for each incarnation of, say,
@@ -392,7 +367,7 @@
               ("VerdanaRed9", "Verdana", 9, 255, 0),
              ])
 
-    compileargs = r"-Wi [TARGETDIR]Lib\compileall.py -f -x badsyntax [TARGETDIR]Lib"
+    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
@@ -491,7 +466,7 @@
     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")
+    c.condition("Hide", "NOT Version9X")
 
     exit_dialog.text("Description", 135, 235, 220, 20, 0x30003,
                "Click the Finish button to exit the Installer.")
@@ -914,7 +889,7 @@
                 continue
             tcltk.set_current()
         elif dir in ['test', 'tests', 'data', 'output']:
-            # test: Lib, Lib/email, Lib/bsddb
+            # test: Lib, Lib/email, Lib/bsddb, Lib/ctypes, Lib/sqlite3
             # tests: Lib/distutils
             # data: Lib/email/test
             # output: Lib/test
@@ -941,6 +916,8 @@
             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':
@@ -990,6 +967,14 @@
             tcldir = os.path.normpath(srcdir+"/../tcltk/bin")
             for f in glob.glob1(tcldir, "*.dll"):
                 lib.add_file(f, src=os.path.join(tcldir, 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")
     # check whether there are any unknown extensions
     for f in glob.glob1(srcdir+"/PCBuild", "*.pyd"):
         if f.endswith("_d.pyd"): continue # debug version
diff --git a/Tools/msi/uuids.py b/Tools/msi/uuids.py
new file mode 100644
index 0000000..ce7e604
--- /dev/null
+++ b/Tools/msi/uuids.py
@@ -0,0 +1,33 @@
+# 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.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
+}
diff --git a/Tools/pybench/Arithmetic.py b/Tools/pybench/Arithmetic.py
new file mode 100644
index 0000000..e95c30a
--- /dev/null
+++ b/Tools/pybench/Arithmetic.py
@@ -0,0 +1,778 @@
+from pybench import Test
+
+class SimpleIntegerArithmetic(Test):
+
+    version = 0.3
+    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 = 0.3
+    operations = 5 * (3 + 5 + 5 + 3 + 3 + 3)
+    rounds = 100000
+
+    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 = 0.3
+    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 = 0.3
+    operations = 5 * (3 + 5 + 5 + 3 + 3 + 3)
+    rounds = 30000
+
+    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 = 0.3
+    operations = 5 * (3 + 5 + 5 + 3 + 3 + 3)
+    rounds = 40000
+
+    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
+
diff --git a/Tools/pybench/Calls.py b/Tools/pybench/Calls.py
new file mode 100644
index 0000000..82e7a91
--- /dev/null
+++ b/Tools/pybench/Calls.py
@@ -0,0 +1,410 @@
+from pybench import Test
+
+class PythonFunctionCalls(Test):
+
+    version = 0.3
+    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 = 0.4
+    operations = 5*(2+5+5+5)
+    rounds = 30000
+
+    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 = 0.3
+    operations = 5*(6 + 5 + 4)
+    rounds = 20000
+
+    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 = 0.3
+    operations = 5
+    rounds = 50000
+
+    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
+
diff --git a/Tools/pybench/CommandLine.py b/Tools/pybench/CommandLine.py
new file mode 100644
index 0000000..fb7e07b
--- /dev/null
+++ b/Tools/pybench/CommandLine.py
@@ -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@lemburg.com)
+Copyright (c), 2000-2006, eGenix.com Software GmbH (info@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'
+            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()
diff --git a/Tools/pybench/Constructs.py b/Tools/pybench/Constructs.py
new file mode 100644
index 0000000..aba888f
--- /dev/null
+++ b/Tools/pybench/Constructs.py
@@ -0,0 +1,565 @@
+from pybench import Test
+
+class IfThenElse(Test):
+
+    version = 0.31
+    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 = 0.3
+    operations = 1000*10*5
+    rounds = 150
+
+    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 = 0.1
+    operations = 5 * 5
+    rounds = 8000
+
+    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
+
diff --git a/Tools/pybench/Dict.py b/Tools/pybench/Dict.py
new file mode 100644
index 0000000..207d88f
--- /dev/null
+++ b/Tools/pybench/Dict.py
@@ -0,0 +1,503 @@
+from pybench import Test
+
+class DictCreation(Test):
+
+    version = 0.3
+    operations = 5*(5 + 5)
+    rounds = 60000
+
+    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 = 0.1
+    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 = 0.1
+    operations = 5*(6 + 6)
+    rounds = 200000
+
+    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 = 0.1
+    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 = 0.3
+    operations = 5*(6 + 6 + 6 + 6)
+    rounds = 50000
+
+    def test(self):
+
+        d = {}
+
+        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]
+
+            d.has_key(0)
+            d.has_key(2)
+            d.has_key(4)
+            d.has_key(6)
+            d.has_key(8)
+            d.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]
+
+            d.has_key(0)
+            d.has_key(2)
+            d.has_key(4)
+            d.has_key(6)
+            d.has_key(8)
+            d.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]
+
+            d.has_key(0)
+            d.has_key(2)
+            d.has_key(4)
+            d.has_key(6)
+            d.has_key(8)
+            d.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]
+
+            d.has_key(0)
+            d.has_key(2)
+            d.has_key(4)
+            d.has_key(6)
+            d.has_key(8)
+            d.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]
+
+            d.has_key(0)
+            d.has_key(2)
+            d.has_key(4)
+            d.has_key(6)
+            d.has_key(8)
+            d.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 = {}
+
+        for i in xrange(self.rounds):
+            pass
+
diff --git a/Tools/pybench/Exceptions.py b/Tools/pybench/Exceptions.py
new file mode 100644
index 0000000..295c83a
--- /dev/null
+++ b/Tools/pybench/Exceptions.py
@@ -0,0 +1,681 @@
+from pybench import Test
+
+class TryRaiseExcept(Test):
+
+    version = 0.1
+    operations = 2 + 3
+    rounds = 60000
+
+    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
+
+    def calibrate(self):
+
+        error = ValueError
+
+        for i in xrange(self.rounds):
+            pass
+            
+
+class TryExcept(Test):
+
+    version = 0.1
+    operations = 15 * 10
+    rounds = 200000
+
+    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
+            
+
diff --git a/Tools/pybench/Imports.py b/Tools/pybench/Imports.py
new file mode 100644
index 0000000..eb458b4
--- /dev/null
+++ b/Tools/pybench/Imports.py
@@ -0,0 +1,139 @@
+from pybench import Test
+
+# First imports:
+import os
+import package.submodule
+
+class SecondImport(Test):
+
+    version = 0.1
+    operations = 5 * 5
+    rounds = 20000
+
+    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 = 0.1
+    operations = 5 * 5
+    rounds = 20000
+
+    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 = 0.1
+    operations = 5 * 5
+    rounds = 20000
+
+    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
+            
diff --git a/Tools/pybench/Instances.py b/Tools/pybench/Instances.py
new file mode 100644
index 0000000..7663e23
--- /dev/null
+++ b/Tools/pybench/Instances.py
@@ -0,0 +1,68 @@
+from pybench import Test
+
+class CreateInstances(Test):
+
+    version = 0.2
+    operations = 3 + 7 + 4
+    rounds = 60000
+
+    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
+
+
diff --git a/Tools/pybench/LICENSE b/Tools/pybench/LICENSE
new file mode 100644
index 0000000..17c6a6b
--- /dev/null
+++ b/Tools/pybench/LICENSE
@@ -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@lemburg.com)
+Copyright (c), 2000-2006, eGenix.com Software GmbH (info@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 !
diff --git a/Tools/pybench/Lists.py b/Tools/pybench/Lists.py
new file mode 100644
index 0000000..a06b44c
--- /dev/null
+++ b/Tools/pybench/Lists.py
@@ -0,0 +1,292 @@
+from pybench import Test
+
+class SimpleListManipulation(Test):
+
+    version = 0.3
+    operations = 5* (6 + 6 + 6)
+    rounds = 60000
+
+    def test(self):
+
+        l = []
+
+        for i in xrange(self.rounds):
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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]
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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]
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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]
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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]
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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 = []
+
+        for i in xrange(self.rounds):
+            pass
+
+class ListSlicing(Test):
+
+    version = 0.4
+    operations = 25*(3+1+2+1)
+    rounds = 400
+
+    def test(self):
+
+        n = range(100)
+        r = range(25)
+
+        for i in xrange(self.rounds):
+
+            l = range(100)
+
+            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):
+
+            l = range(100)
+
+            for j in r:
+                pass
+
+class SmallLists(Test):
+
+    version = 0.3
+    operations = 5*(1+ 6 + 6 + 3 + 1)
+    rounds = 60000
+
+    def test(self):
+
+        for i in xrange(self.rounds):
+
+            l = []
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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 = []
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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 = []
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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 = []
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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 = []
+
+            l.append(2)
+            l.append(3)
+            l.append(4)
+            l.append(2)
+            l.append(3)
+            l.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):
+            l = []
+
diff --git a/Tools/pybench/Lookups.py b/Tools/pybench/Lookups.py
new file mode 100644
index 0000000..fbbc0ed
--- /dev/null
+++ b/Tools/pybench/Lookups.py
@@ -0,0 +1,946 @@
+from pybench import Test
+
+class SpecialClassAttribute(Test):
+
+    version = 0.3
+    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 = 0.3
+    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 = 0.3
+    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 = 0.3
+    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 = 0.3
+    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
+
diff --git a/Tools/pybench/Numbers.py b/Tools/pybench/Numbers.py
new file mode 100644
index 0000000..75cf2ed
--- /dev/null
+++ b/Tools/pybench/Numbers.py
@@ -0,0 +1,784 @@
+from pybench import Test
+
+class CompareIntegers(Test):
+
+    version = 0.1
+    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 = 0.1
+    operations = 30 * 5
+    rounds = 60000
+
+    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 = 0.1
+    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 = 0.1
+    operations = 30 * 5
+    rounds = 60000
+
+    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
diff --git a/Tools/pybench/README b/Tools/pybench/README
new file mode 100644
index 0000000..634e41b
--- /dev/null
+++ b/Tools/pybench/README
@@ -0,0 +1,372 @@
+________________________________________________________________________
+
+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 just let the benchmark suite do it's thing and
+'pybench.py -f <file>' to have it store the results in a file too.
+
+This is the current output of pybench.py --help:
+
+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 ()
+  -S               show statistics of benchmarks (0)
+  -w arg           set warp factor to arg (20)
+  -d               hide noise in compares (0)
+  --no-gc          disable garbage collection (0)
+  -v               generate verbose output
+  -h               show this help text
+  --help           show this help text
+  --debug          enable debugging
+  --copyright      show copyright
+  --examples       show examples of usage
+
+Version:
+ 1.3
+
+The normal operation is to run the suite and display the
+results. Use -f to save them for later reuse or comparisms.
+
+Examples:
+
+python1.5 pybench.py -w 100 -f p15
+python1.4 pybench.py -w 100 -f p14
+python pybench.py -s p15 -c p14
+
+
+License
+-------
+
+See LICENSE file.
+
+
+Sample output
+-------------
+
+PYBENCH 1.3
+
+Machine Details:
+   Platform ID:  Linux-2.6.8-24.19-default-x86_64-with-SuSE-9.2-x86-64
+   Executable:   /home/lemburg/projects/Python/Installation/bin/python
+   Python:       2.5a1.0
+   Compiler:     GCC 3.3.4 (pre 3.3.5 20040809)
+   Build:        Apr  9 2006 01:50:57 (#trunk)
+
+Searching for tests...
+   BuiltinFunctionCalls
+   BuiltinMethodLookup
+   CompareFloats
+   CompareFloatsIntegers
+   CompareIntegers
+   CompareInternedStrings
+   CompareLongs
+   CompareStrings
+   CompareUnicode
+   ConcatStrings
+   ConcatUnicode
+   CreateInstances
+   CreateStringsWithConcat
+   CreateUnicodeWithConcat
+   DictCreation
+   DictWithFloatKeys
+   DictWithIntegerKeys
+   DictWithStringKeys
+   ForLoops
+   IfThenElse
+   ListSlicing
+   NestedForLoops
+   NormalClassAttribute
+   NormalInstanceAttribute
+   PythonFunctionCalls
+   PythonMethodCalls
+   Recursion
+   SecondImport
+   SecondPackageImport
+   SecondSubmoduleImport
+   SimpleComplexArithmetic
+   SimpleDictManipulation
+   SimpleFloatArithmetic
+   SimpleIntFloatArithmetic
+   SimpleIntegerArithmetic
+   SimpleListManipulation
+   SimpleLongArithmetic
+   SmallLists
+   SmallTuples
+   SpecialClassAttribute
+   SpecialInstanceAttribute
+   StringMappings
+   StringPredicates
+   StringSlicing
+   TryExcept
+   TryRaiseExcept
+   TupleSlicing
+   UnicodeMappings
+   UnicodePredicates
+   UnicodeProperties
+   UnicodeSlicing
+
+Running 10 round(s) of the suite:
+
+...
+
+ Round 10                         real   abs    overhead
+          BuiltinFunctionCalls:   0.030r 0.030a 0.000o
+           BuiltinMethodLookup:   0.059r 0.060a 0.001o
+                 CompareFloats:   0.050r 0.050a 0.000o
+         CompareFloatsIntegers:   0.050r 0.050a 0.000o
+               CompareIntegers:   0.070r 0.070a 0.000o
+        CompareInternedStrings:   0.039r 0.040a 0.001o
+                  CompareLongs:   0.050r 0.050a 0.000o
+                CompareStrings:   0.060r 0.060a 0.000o
+                CompareUnicode:   0.060r 0.060a 0.000o
+                 ConcatStrings:   0.040r 0.040a 0.000o
+                 ConcatUnicode:   0.050r 0.050a 0.000o
+               CreateInstances:   0.050r 0.050a 0.000o
+       CreateStringsWithConcat:   0.029r 0.030a 0.001o
+       CreateUnicodeWithConcat:   0.060r 0.060a 0.000o
+                  DictCreation:   0.040r 0.040a 0.000o
+             DictWithFloatKeys:   0.089r 0.090a 0.000o
+           DictWithIntegerKeys:   0.059r 0.060a 0.001o
+            DictWithStringKeys:   0.070r 0.070a 0.001o
+                      ForLoops:   0.050r 0.050a 0.000o
+                    IfThenElse:   0.070r 0.070a 0.000o
+                   ListSlicing:   0.030r 0.030a 0.000o
+                NestedForLoops:   0.030r 0.030a 0.000o
+          NormalClassAttribute:   0.060r 0.060a 0.000o
+       NormalInstanceAttribute:   0.060r 0.060a 0.000o
+           PythonFunctionCalls:   0.060r 0.060a 0.000o
+             PythonMethodCalls:   0.050r 0.050a 0.000o
+                     Recursion:   0.050r 0.050a 0.000o
+                  SecondImport:   0.030r 0.030a 0.000o
+           SecondPackageImport:   0.030r 0.030a 0.000o
+         SecondSubmoduleImport:   0.040r 0.040a 0.000o
+       SimpleComplexArithmetic:   0.030r 0.030a 0.000o
+        SimpleDictManipulation:   0.040r 0.040a 0.000o
+         SimpleFloatArithmetic:   0.050r 0.050a 0.001o
+      SimpleIntFloatArithmetic:   0.060r 0.060a 0.000o
+       SimpleIntegerArithmetic:   0.060r 0.060a 0.000o
+        SimpleListManipulation:   0.030r 0.030a 0.000o
+          SimpleLongArithmetic:   0.030r 0.030a 0.000o
+                    SmallLists:   0.050r 0.050a 0.000o
+                   SmallTuples:   0.050r 0.050a 0.000o
+         SpecialClassAttribute:   0.060r 0.060a 0.000o
+      SpecialInstanceAttribute:   0.079r 0.080a 0.001o
+                StringMappings:   0.060r 0.060a 0.000o
+              StringPredicates:   0.049r 0.050a 0.001o
+                 StringSlicing:   0.039r 0.040a 0.000o
+                     TryExcept:   0.079r 0.080a 0.001o
+                TryRaiseExcept:   0.059r 0.060a 0.001o
+                  TupleSlicing:   0.050r 0.050a 0.000o
+               UnicodeMappings:   0.070r 0.070a 0.001o
+             UnicodePredicates:   0.059r 0.060a 0.001o
+             UnicodeProperties:   0.059r 0.060a 0.001o
+                UnicodeSlicing:   0.050r 0.050a 0.000o
+                                 ----------------------
+            Average round time:      2.937 seconds
+
+
+Tests:                              per run    per oper.   overhead
+------------------------------------------------------------------------
+          BuiltinFunctionCalls:      29.85 ms    0.23 us    0.00 ms
+           BuiltinMethodLookup:      66.85 ms    0.13 us    0.50 ms
+                 CompareFloats:      43.00 ms    0.10 us    0.00 ms
+         CompareFloatsIntegers:      51.80 ms    0.12 us    0.00 ms
+               CompareIntegers:      70.70 ms    0.08 us    0.50 ms
+        CompareInternedStrings:      41.40 ms    0.08 us    0.50 ms
+                  CompareLongs:      47.90 ms    0.11 us    0.00 ms
+                CompareStrings:      58.50 ms    0.12 us    0.50 ms
+                CompareUnicode:      56.55 ms    0.15 us    0.50 ms
+                 ConcatStrings:      44.75 ms    0.30 us    0.00 ms
+                 ConcatUnicode:      54.55 ms    0.36 us    0.50 ms
+               CreateInstances:      50.95 ms    1.21 us    0.00 ms
+       CreateStringsWithConcat:      28.85 ms    0.14 us    0.50 ms
+       CreateUnicodeWithConcat:      53.75 ms    0.27 us    0.00 ms
+                  DictCreation:      41.90 ms    0.28 us    0.00 ms
+             DictWithFloatKeys:      88.50 ms    0.15 us    0.50 ms
+           DictWithIntegerKeys:      62.55 ms    0.10 us    0.50 ms
+            DictWithStringKeys:      60.50 ms    0.10 us    0.50 ms
+                      ForLoops:      46.90 ms    4.69 us    0.00 ms
+                    IfThenElse:      60.55 ms    0.09 us    0.00 ms
+                   ListSlicing:      29.90 ms    8.54 us    0.00 ms
+                NestedForLoops:      33.95 ms    0.10 us    0.00 ms
+          NormalClassAttribute:      62.75 ms    0.10 us    0.50 ms
+       NormalInstanceAttribute:      61.80 ms    0.10 us    0.50 ms
+           PythonFunctionCalls:      60.00 ms    0.36 us    0.00 ms
+             PythonMethodCalls:      50.00 ms    0.67 us    0.00 ms
+                     Recursion:      46.85 ms    3.75 us    0.00 ms
+                  SecondImport:      35.00 ms    1.40 us    0.00 ms
+           SecondPackageImport:      32.00 ms    1.28 us    0.00 ms
+         SecondSubmoduleImport:      38.00 ms    1.52 us    0.00 ms
+       SimpleComplexArithmetic:      26.85 ms    0.12 us    0.00 ms
+        SimpleDictManipulation:      40.85 ms    0.14 us    0.00 ms
+         SimpleFloatArithmetic:      48.70 ms    0.09 us    0.50 ms
+      SimpleIntFloatArithmetic:      57.70 ms    0.09 us    0.00 ms
+       SimpleIntegerArithmetic:      58.75 ms    0.09 us    0.50 ms
+        SimpleListManipulation:      34.80 ms    0.13 us    0.00 ms
+          SimpleLongArithmetic:      30.95 ms    0.19 us    0.50 ms
+                    SmallLists:      47.60 ms    0.19 us    0.00 ms
+                   SmallTuples:      48.80 ms    0.20 us    0.50 ms
+         SpecialClassAttribute:      61.70 ms    0.10 us    0.00 ms
+      SpecialInstanceAttribute:      76.70 ms    0.13 us    0.50 ms
+                StringMappings:      58.70 ms    0.47 us    0.00 ms
+              StringPredicates:      50.00 ms    0.18 us    1.00 ms
+                 StringSlicing:      39.65 ms    0.23 us    0.50 ms
+                     TryExcept:      84.45 ms    0.06 us    0.50 ms
+                TryRaiseExcept:      61.75 ms    4.12 us    0.50 ms
+                  TupleSlicing:      48.95 ms    0.47 us    0.00 ms
+               UnicodeMappings:      71.50 ms    3.97 us    0.50 ms
+             UnicodePredicates:      52.75 ms    0.23 us    1.00 ms
+             UnicodeProperties:      61.90 ms    0.31 us    1.00 ms
+                UnicodeSlicing:      53.75 ms    0.31 us    0.50 ms
+------------------------------------------------------------------------
+            Average round time:    2937.00 ms
+
+________________________________________________________________________
+
+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
+    # 20-50 seconds.
+    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.
+
+
+Have fun,
+--
+Marc-Andre Lemburg
+mal@lemburg.com
diff --git a/Tools/pybench/Setup.py b/Tools/pybench/Setup.py
new file mode 100644
index 0000000..906a2a9
--- /dev/null
+++ b/Tools/pybench/Setup.py
@@ -0,0 +1,35 @@
+#!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 = 20
+
+# Import tests
+from Arithmetic import *
+from Calls import *
+from Constructs import *
+from Lookups import *
+from Instances import *
+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
diff --git a/Tools/pybench/Strings.py b/Tools/pybench/Strings.py
new file mode 100644
index 0000000..5ab458e
--- /dev/null
+++ b/Tools/pybench/Strings.py
@@ -0,0 +1,564 @@
+from pybench import Test
+from string import join
+
+class ConcatStrings(Test):
+
+    version = 0.1
+    operations = 10 * 5
+    rounds = 60000
+
+    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 = 0.2
+    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 = 0.1
+    operations = 10 * 5
+    rounds = 200000
+
+    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 = 0.1
+    operations = 10 * 5
+    rounds = 80000
+
+    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 = 0.1
+    operations = 5 * 7
+    rounds = 100000
+
+    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 = 0.1
+        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 = 0.1
+        operations = 10 * 7
+        rounds = 80000
+
+        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]
+
+
diff --git a/Tools/pybench/Tuples.py b/Tools/pybench/Tuples.py
new file mode 100644
index 0000000..7854def
--- /dev/null
+++ b/Tools/pybench/Tuples.py
@@ -0,0 +1,365 @@
+from pybench import Test
+
+class TupleSlicing(Test):
+
+    version = 0.31
+    operations = 3 * 25 * 10 * 7
+    rounds = 400
+
+    def test(self):
+
+        r = range(25)
+
+        for i in xrange(self.rounds):
+
+            t = tuple(range(100))
+
+            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)
+
+        for i in xrange(self.rounds):
+
+            t = tuple(range(100))
+
+            for j in r:
+                
+                pass
+
+class SmallTuples(Test):
+
+    version = 0.3
+    operations = 5*(1 + 3 + 6 + 2)
+    rounds = 80000
+
+    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
+
diff --git a/Tools/pybench/Unicode.py b/Tools/pybench/Unicode.py
new file mode 100644
index 0000000..855fcf2
--- /dev/null
+++ b/Tools/pybench/Unicode.py
@@ -0,0 +1,542 @@
+try:
+    unicode
+except NameError:
+    raise ImportError
+
+from pybench import Test
+from string import join
+
+class ConcatUnicode(Test):
+
+    version = 0.1
+    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 = 0.1
+    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 = 0.1
+    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 = 0.1
+    operations = 5 * 7
+    rounds = 100000
+
+    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 = 0.1
+    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 = 0.1
+    operations = 5 * 9
+    rounds = 100000
+
+    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 = 0.1
+        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]
diff --git a/Tools/pybench/package/__init__.py b/Tools/pybench/package/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tools/pybench/package/__init__.py
diff --git a/Tools/pybench/package/submodule.py b/Tools/pybench/package/submodule.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tools/pybench/package/submodule.py
diff --git a/Tools/pybench/pybench.py b/Tools/pybench/pybench.py
new file mode 100755
index 0000000..6f10bd1
--- /dev/null
+++ b/Tools/pybench/pybench.py
@@ -0,0 +1,461 @@
+#!/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@lemburg.com)
+Copyright (c), 2000-2006, eGenix.com Software GmbH (info@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 !
+"""
+
+# Version number
+__version__ = '1.3'
+
+#
+# NOTE: Use xrange for all test loops unless you want to face 
+#       a 20MB process !
+#
+# All tests should have rounds set to values so that a run()
+# takes between 20-50 seconds. This is to get fairly good
+# clock() values. You can use option -w to speedup the tests
+# by a fixed integer factor (the "warp factor").
+#
+
+import sys,time,operator
+from CommandLine import *
+
+try:
+    import cPickle
+    pickle = cPickle
+except ImportError:
+    import pickle
+
+### 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 = 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 = 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
+    # 20-50 seconds.
+    rounds = 100000
+
+    ### Internal variables
+
+    # Mark this class as implementing a test
+    is_a_test = 1
+
+    # Misc. internal variables
+    last_timing = (0,0,0) # last timing (real,run,calibration)
+    warp = 1            # warp factor this test uses
+    cruns = 20          # number of calibration runs
+    overhead = None     # list of calibration timings
+
+    def __init__(self,warp=1):
+
+        if warp > 1:
+            self.rounds = self.rounds / warp
+            self.warp = warp
+        self.times = []
+        self.overhead = []
+        # 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 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
+        calibrate = self.calibrate
+        clock = time.clock
+        cruns = self.cruns
+        # first calibrate
+        offset = 0.0
+        for i in range(cruns):
+            t = clock()
+            calibrate()
+            t = clock() - t
+            offset = offset + t
+        offset = offset / cruns
+        # now the real thing
+        t = clock() 
+        test()
+        t = clock() - t
+        self.last_timing = (t-offset,t,offset)
+        self.times.append(t-offset)
+
+    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.
+
+        """
+        # do some tests
+        return
+    
+    def stat(self):
+
+        """ Returns two value: average time per run and average per
+            operation.
+            
+        """
+        runs = len(self.times)
+        if runs == 0:
+            return 0,0
+        totaltime = reduce(operator.add,self.times,0.0)
+        avg = totaltime / float(runs)
+        op_avg = totaltime / float(runs * self.rounds * self.operations)
+        if self.overhead:
+            totaloverhead = reduce(operator.add,self.overhead,0.0)
+            ov_avg = totaloverhead / float(runs)
+        else:
+            # use self.last_timing - not too accurate
+            ov_avg = self.last_timing[2]
+        return avg,op_avg,ov_avg
+
+### 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 = '?'                  # Name of the benchmark
+    rounds = 1                  # Number of rounds to run
+    warp = 1                    # Warp factor
+    roundtime = 0               # Average round time
+    version = None              # Benchmark version number (see __init__)
+                                # as float x.yy
+    starttime = None		# Benchmark start time
+
+    def __init__(self):
+
+        self.tests = {}
+        self.version = 0.31
+
+    def load_tests(self,setupmod,warp=1):
+
+        self.warp = warp
+        tests = self.tests
+        print 'Searching for tests...'
+        setupmod.__dict__.values()
+        for c in setupmod.__dict__.values():
+            if hasattr(c,'is_a_test') and c.__name__ != 'Test':
+                tests[c.__name__] = c(warp)
+        l = tests.keys()
+        l.sort()
+        for t in l:
+            print '  ',t
+        print
+
+    def run(self):
+
+        tests = self.tests.items()
+        tests.sort()
+        clock = time.clock
+        print 'Running %i round(s) of the suite: ' % self.rounds
+        print
+        self.starttime = time.time()
+        roundtime = clock()
+        for i in range(self.rounds):
+            print ' Round %-25i  real   abs    overhead' % (i+1)
+            for j in range(len(tests)):
+                name,t = tests[j]
+                print '%30s:' % name,
+                t.run()
+                print '  %.3fr %.3fa %.3fo' % t.last_timing
+            print '                                 ----------------------'
+            print '            Average round time:      %.3f seconds' % \
+                  ((clock() - roundtime)/(i+1))
+            print
+        self.roundtime = (clock() - roundtime) / self.rounds
+        print
+    
+    def print_stat(self, compare_to=None, hidenoise=0):
+
+        if not compare_to:
+            print '%-30s      per run    per oper.   overhead' % 'Tests:'
+            print '-'*72
+            tests = self.tests.items()
+            tests.sort()
+            for name,t in tests:
+                avg,op_avg,ov_avg = t.stat()
+                print '%30s: %10.2f ms %7.2f us %7.2f ms' % \
+                      (name,avg*1000.0,op_avg*1000000.0,ov_avg*1000.0)
+            print '-'*72
+            print '%30s: %10.2f ms' % \
+                  ('Average round time',self.roundtime * 1000.0)
+
+        else:
+            print '%-30s      per run    per oper.    diff *)' % \
+                  'Tests:'
+            print '-'*72
+            tests = self.tests.items()
+            tests.sort()
+            compatible = 1
+            for name,t in tests:
+                avg,op_avg,ov_avg = t.stat()
+                try:
+                    other = compare_to.tests[name]
+                except KeyError:
+                    other = None
+                if other and other.version == t.version and \
+                   other.operations == t.operations:
+                    avg1,op_avg1,ov_avg1 = other.stat()
+                    qop_avg = (op_avg/op_avg1-1.0)*100.0
+                    if hidenoise and abs(qop_avg) < 10:
+                        qop_avg = ''
+                    else:
+                        qop_avg = '%+7.2f%%' % qop_avg
+                else:
+                    qavg,qop_avg = 'n/a', 'n/a'
+                    compatible = 0
+                print '%30s: %10.2f ms %7.2f us  %8s' % \
+                      (name,avg*1000.0,op_avg*1000000.0,qop_avg)
+            print '-'*72
+            if compatible and compare_to.roundtime > 0 and \
+               compare_to.version == self.version:
+                print '%30s: %10.2f ms             %+7.2f%%' % \
+                      ('Average round time',self.roundtime * 1000.0,
+                       ((self.roundtime*self.warp)/
+                        (compare_to.roundtime*compare_to.warp)-1.0)*100.0)
+            else:
+                print '%30s: %10.2f ms                  n/a' % \
+                      ('Average round time',self.roundtime * 1000.0)
+            print
+            print '*) measured against: %s (rounds=%i, warp=%i)' % \
+                  (compare_to.name,compare_to.rounds,compare_to.warp)
+        print
+
+def print_machine():
+
+    import platform
+    print 'Machine Details:'
+    print '   Platform ID:  %s' % platform.platform()
+    print '   Executable:   %s' % sys.executable
+    # There's a bug in Python 2.2b1+...
+    if sys.version[:6] == '2.2b1+':
+        return
+    print '   Python:       %s' % platform.python_version()
+    print '   Compiler:     %s' % platform.python_compiler()
+    buildno, builddate = platform.python_build()
+    print '   Build:        %s (#%s)' % (builddate, buildno)
+
+class PyBenchCmdline(Application):
+
+    header = ("PYBENCH - a benchmark test suite for Python "
+              "interpreters/compilers.")
+
+    version = __version__
+
+    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',''),
+               SwitchOption('-S','show statistics of benchmarks',0),
+               ArgumentOption('-w','set warp factor to arg',Setup.Warp_factor),
+               SwitchOption('-d','hide noise in compares', 0),
+               SwitchOption('--no-gc','disable garbage collection', 0),
+               ]
+
+    about = """\
+The normal operation is to run the suite and display the
+results. Use -f to save them for later reuse or comparisms.
+
+Examples:
+
+python1.5 pybench.py -w 100 -f p15
+python1.4 pybench.py -w 100 -f p14
+python pybench.py -s p15 -c p14
+"""
+    copyright = __copyright__
+
+    def handle_S(self, value):
+
+        """ Display one line stats for each benchmark file given on the
+            command line.
+
+        """
+        for benchmark in self.files:
+            try:
+                f = open(benchmark, 'rb')
+                bench = pickle.load(f)
+                f.close()
+            except IOError:
+                print '* Error opening/reading file %s' % repr(benchmark)
+            else:
+                print '%s,%-.2f,ms' % (benchmark, bench.roundtime*1000.0)
+        return 0
+
+    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 = self.values['-w']
+        nogc = self.values['--no-gc']
+        
+        # Switch off GC
+        if nogc:
+            try:
+                import gc
+            except ImportError:
+                nogc = 0
+            else:
+                if self.values['--no-gc']:
+                    gc.disable()
+
+        print 'PYBENCH',__version__
+        print
+
+        if not compare_to:
+            print_machine()
+            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:
+                print '* Error opening/reading file',compare_to
+                compare_to = None    
+
+        if show_bench:
+            try:
+                f = open(show_bench,'rb')
+                bench = pickle.load(f)
+                bench.name = show_bench
+                f.close()
+                print 'Benchmark: %s (rounds=%i, warp=%i)' % \
+                      (bench.name,bench.rounds,bench.warp)
+                print
+                bench.print_stat(compare_to, hidenoise)
+            except IOError:
+                print '* Error opening/reading file',show_bench
+                print
+            return
+
+        if reportfile:
+            if nogc:
+                print 'Benchmark: %s (rounds=%i, warp=%i, no GC)' % \
+                      (reportfile,rounds,warp)
+            else:
+                print 'Benchmark: %s (rounds=%i, warp=%i)' % \
+                      (reportfile,rounds,warp)
+            print
+
+        # Create benchmark object
+        bench = Benchmark()
+        bench.rounds = rounds
+        bench.load_tests(Setup,warp)
+        try:
+            bench.run()
+        except KeyboardInterrupt:
+            print
+            print '*** KeyboardInterrupt -- Aborting'
+            print
+            return
+        bench.print_stat(compare_to)
+        # ring bell
+        sys.stderr.write('\007')
+
+        if reportfile:
+            try:
+                f = open(reportfile,'wb')
+                bench.name = reportfile
+                pickle.dump(bench,f)
+                f.close()
+            except IOError:
+                print '* Error opening/writing reportfile'
+
+if __name__ == '__main__':
+    PyBenchCmdline()
diff --git a/Tools/scripts/byext.py b/Tools/scripts/byext.py
index 93759bc..09610b0 100644
--- a/Tools/scripts/byext.py
+++ b/Tools/scripts/byext.py
@@ -17,7 +17,7 @@
             elif os.path.isfile(arg):
                 self.statfile(arg)
             else:
-                sys.stderr.write("Can't find %s\n" % file)
+                sys.stderr.write("Can't find %s\n" % arg)
                 self.addstats("<???>", "unknown", 1)
 
     def statdir(self, dir):
@@ -25,8 +25,8 @@
         try:
             names = os.listdir(dir)
         except os.error, err:
-            sys.stderr.write("Can't list %s: %s\n" % (file, err))
-            self.addstats(ext, "unlistable", 1)
+            sys.stderr.write("Can't list %s: %s\n" % (dir, err))
+            self.addstats("<dir>", "unlistable", 1)
             return
         names.sort()
         for name in names:
@@ -42,9 +42,9 @@
             else:
                 self.statfile(full)
 
-    def statfile(self, file):
-        head, ext = os.path.splitext(file)
-        head, base = os.path.split(file)
+    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)
@@ -52,9 +52,9 @@
             ext = "<none>"
         self.addstats(ext, "files", 1)
         try:
-            f = open(file, "rb")
+            f = open(filename, "rb")
         except IOError, err:
-            sys.stderr.write("Can't open %s: %s\n" % (file, err))
+            sys.stderr.write("Can't open %s: %s\n" % (filename, err))
             self.addstats(ext, "unopenable", 1)
             return
         data = f.read()
diff --git a/Tools/scripts/classfix.py b/Tools/scripts/classfix.py
index cdf006a..d30700f 100755
--- a/Tools/scripts/classfix.py
+++ b/Tools/scripts/classfix.py
@@ -30,7 +30,7 @@
 # into a program for a different change to Python programs...
 
 import sys
-import regex
+import re
 import os
 from stat import *
 
@@ -53,7 +53,7 @@
             if fix(arg): bad = 1
     sys.exit(bad)
 
-ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$')
+ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
 def ispython(name):
     return ispythonprog.match(name) >= 0
 
@@ -148,12 +148,12 @@
 
 # This expression doesn't catch *all* class definition headers,
 # but it's pretty darn close.
-classexpr = '^\([ \t]*class +[a-zA-Z0-9_]+\) *( *) *\(\(=.*\)?\):'
-classprog = regex.compile(classexpr)
+classexpr = '^([ \t]*class +[a-zA-Z0-9_]+) *( *) *((=.*)?):'
+classprog = re.compile(classexpr)
 
 # Expressions for finding base class expressions.
-baseexpr = '^ *\(.*\) *( *) *$'
-baseprog = regex.compile(baseexpr)
+baseexpr = '^ *(.*) *( *) *$'
+baseprog = re.compile(baseexpr)
 
 def fixline(line):
     if classprog.match(line) < 0: # No 'class' keyword -- no change
diff --git a/Tools/scripts/fixcid.py b/Tools/scripts/fixcid.py
index 42aa835..433a425 100755
--- a/Tools/scripts/fixcid.py
+++ b/Tools/scripts/fixcid.py
@@ -35,7 +35,7 @@
 # files.
 
 import sys
-import regex
+import re
 import os
 from stat import *
 import getopt
@@ -90,7 +90,7 @@
 # Change this regular expression to select a different set of files
 Wanted = '^[a-zA-Z0-9_]+\.[ch]$'
 def wanted(name):
-    return regex.match(Wanted, name) >= 0
+    return re.match(Wanted, name) >= 0
 
 def recursedown(dirname):
     dbg('recursedown(%r)\n' % (dirname,))
@@ -212,12 +212,12 @@
 # Anything else is an operator -- don't list this explicitly because of '/*'
 
 OutsideComment = (Identifier, Number, String, Char, CommentStart)
-OutsideCommentPattern = '\(' + '\|'.join(OutsideComment) + '\)'
-OutsideCommentProgram = regex.compile(OutsideCommentPattern)
+OutsideCommentPattern = '(' + '|'.join(OutsideComment) + ')'
+OutsideCommentProgram = re.compile(OutsideCommentPattern)
 
 InsideComment = (Identifier, Number, CommentEnd)
-InsideCommentPattern = '\(' + '\|'.join(InsideComment) + '\)'
-InsideCommentProgram = regex.compile(InsideCommentPattern)
+InsideCommentPattern = '(' + '|'.join(InsideComment) + ')'
+InsideCommentProgram = re.compile(InsideCommentPattern)
 
 def initfixline():
     global Program
diff --git a/Tools/scripts/ifdef.py b/Tools/scripts/ifdef.py
index 7e7b5cc..2ed7a66 100755
--- a/Tools/scripts/ifdef.py
+++ b/Tools/scripts/ifdef.py
@@ -27,7 +27,6 @@
 # preprocessor commands.
 
 import sys
-import regex
 import getopt
 
 defs = []
diff --git a/Tools/scripts/methfix.py b/Tools/scripts/methfix.py
index a872ab7..b81871f 100755
--- a/Tools/scripts/methfix.py
+++ b/Tools/scripts/methfix.py
@@ -27,7 +27,7 @@
 # into a program for a different change to Python programs...
 
 import sys
-import regex
+import re
 import os
 from stat import *
 
@@ -50,7 +50,7 @@
             if fix(arg): bad = 1
     sys.exit(bad)
 
-ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$')
+ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
 def ispython(name):
     return ispythonprog.match(name) >= 0
 
@@ -101,7 +101,7 @@
         if lineno == 1 and g is None and line[:2] == '#!':
             # Check for non-Python scripts
             words = line[2:].split()
-            if words and regex.search('[pP]ython', words[0]) < 0:
+            if words and re.search('[pP]ython', words[0]) < 0:
                 msg = filename + ': ' + words[0]
                 msg = msg + ' script; not fixed\n'
                 err(msg)
@@ -158,8 +158,8 @@
     return 0
 
 
-fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *\(( *\(.*\) *)\) *) *:'
-fixprog = regex.compile(fixpat)
+fixpat = '^[ \t]+def +[a-zA-Z0-9_]+ *( *self *, *(( *(.*) *)) *) *:'
+fixprog = re.compile(fixpat)
 
 def fixline(line):
     if fixprog.match(line) >= 0:
diff --git a/Tools/scripts/objgraph.py b/Tools/scripts/objgraph.py
index 01060f9..f74c2b6 100755
--- a/Tools/scripts/objgraph.py
+++ b/Tools/scripts/objgraph.py
@@ -22,7 +22,7 @@
 import sys
 import os
 import getopt
-import regex
+import re
 
 # Types of symbols.
 #
@@ -32,7 +32,7 @@
 
 # Regular expression to parse "nm -o" output.
 #
-matcher = regex.compile('\(.*\):\t?........ \(.\) \(.*\)$')
+matcher = re.compile('(.*):\t?........ (.) (.*)$')
 
 # Store "item" in "dict" under "key".
 # The dictionary maps keys to lists of items.
diff --git a/Tools/scripts/pathfix.py b/Tools/scripts/pathfix.py
index 5cb5add..7f6f191 100755
--- a/Tools/scripts/pathfix.py
+++ b/Tools/scripts/pathfix.py
@@ -20,7 +20,7 @@
 # into a program for a different change to Python programs...
 
 import sys
-import regex
+import re
 import os
 from stat import *
 import getopt
@@ -59,7 +59,7 @@
             if fix(arg): bad = 1
     sys.exit(bad)
 
-ispythonprog = regex.compile('^[a-zA-Z0-9_]+\.py$')
+ispythonprog = re.compile('^[a-zA-Z0-9_]+\.py$')
 def ispython(name):
     return ispythonprog.match(name) >= 0
 
diff --git a/Tools/scripts/pdeps.py b/Tools/scripts/pdeps.py
index e835f84..da63e35 100755
--- a/Tools/scripts/pdeps.py
+++ b/Tools/scripts/pdeps.py
@@ -21,7 +21,7 @@
 
 
 import sys
-import regex
+import re
 import os
 
 
@@ -57,8 +57,8 @@
 
 # Compiled regular expressions to search for import statements
 #
-m_import = regex.compile('^[ \t]*from[ \t]+\([^ \t]+\)[ \t]+')
-m_from = regex.compile('^[ \t]*import[ \t]+\([^#]+\)')
+m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+')
+m_from = re.compile('^[ \t]*import[ \t]+([^#]+)')
 
 
 # Collect data from one file
diff --git a/Tools/unicode/Makefile b/Tools/unicode/Makefile
index f266d4d..fbd3557 100644
--- a/Tools/unicode/Makefile
+++ b/Tools/unicode/Makefile
@@ -15,7 +15,7 @@
 
 all:	distclean mappings codecs
 
-codecs:	misc windows iso apple ebcdic custom-mappings
+codecs:	misc windows iso apple ebcdic custom-mappings cjk
 
 ### Mappings
 
@@ -72,6 +72,9 @@
 	$(PYTHON) gencodec.py MAPPINGS/VENDORS/MICSFT/EBCDIC/ build/
 	$(RM) -f build/readme.*
 
+cjk:	build/
+	$(PYTHON) gencjkcodecs.py build/
+
 ### Cleanup
 
 clean:
diff --git a/Tools/unicode/gencjkcodecs.py b/Tools/unicode/gencjkcodecs.py
new file mode 100644
index 0000000..975c19c
--- /dev/null
+++ b/Tools/unicode/gencjkcodecs.py
@@ -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@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])
diff --git a/Tools/unicode/gencodec.py b/Tools/unicode/gencodec.py
index bb1c9da..3cfef20 100644
--- a/Tools/unicode/gencodec.py
+++ b/Tools/unicode/gencodec.py
@@ -348,7 +348,7 @@
     l.extend(encoding_map_code)
 
     # Final new-line
-    l.append('\n')
+    l.append('')
 
     return '\n'.join(l).expandtabs()