diff --git a/Misc/NEWS b/Misc/NEWS
index 8eecb72..03cd7df 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -724,6 +724,13 @@
 - Removed importlib's custom test discovery code and switched to
     unittest.TestLoader.discover().
 
+Tools/Demos
+-----------
+
+- iobench (a file I/O benchmark) and ccbench (a concurrency benchmark) were
+  added to the `Tools/` directory.  They were previously living in the
+  sandbox.
+
 
 What's New in Python 3.1?
 =========================
diff --git a/Tools/ccbench/ccbench.py b/Tools/ccbench/ccbench.py
new file mode 100644
index 0000000..0b93012
--- /dev/null
+++ b/Tools/ccbench/ccbench.py
@@ -0,0 +1,462 @@
+# -*- coding: utf-8 -*-
+# This file should be kept compatible with both Python 2.6 and Python >= 3.0.
+
+from __future__ import division
+from __future__ import print_function
+
+"""
+ccbench, a Python concurrency benchmark.
+"""
+
+import time
+import os
+import sys
+import functools
+import itertools
+import threading
+import subprocess
+import socket
+from optparse import OptionParser, SUPPRESS_HELP
+import platform
+
+# Compatibility
+try:
+    xrange
+except NameError:
+    xrange = range
+
+try:
+    map = itertools.imap
+except AttributeError:
+    pass
+
+
+THROUGHPUT_DURATION = 2.0
+
+LATENCY_PING_INTERVAL = 0.1
+LATENCY_DURATION = 2.0
+
+
+def task_pidigits():
+    """Pi calculation (Python)"""
+    _map = map
+    _count = itertools.count
+    _islice = itertools.islice
+
+    def calc_ndigits(n):
+        # From http://shootout.alioth.debian.org/
+        def gen_x():
+            return _map(lambda k: (k, 4*k + 2, 0, 2*k + 1), _count(1))
+
+        def compose(a, b):
+            aq, ar, as_, at = a
+            bq, br, bs, bt = b
+            return (aq * bq,
+                    aq * br + ar * bt,
+                    as_ * bq + at * bs,
+                    as_ * br + at * bt)
+
+        def extract(z, j):
+            q, r, s, t = z
+            return (q*j + r) // (s*j + t)
+
+        def pi_digits():
+            z = (1, 0, 0, 1)
+            x = gen_x()
+            while 1:
+                y = extract(z, 3)
+                while y != extract(z, 4):
+                    z = compose(z, next(x))
+                    y = extract(z, 3)
+                z = compose((10, -10*y, 0, 1), z)
+                yield y
+
+        return list(_islice(pi_digits(), n))
+
+    return calc_ndigits, (50, )
+
+def task_regex():
+    """regular expression (C)"""
+    # XXX this task gives horrendous latency results.
+    import re
+    # Taken from the `inspect` module
+    pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)', re.MULTILINE)
+    with open(__file__, "r") as f:
+        arg = f.read(2000)
+
+    def findall(s):
+        t = time.time()
+        try:
+            return pat.findall(s)
+        finally:
+            print(time.time() - t)
+    return pat.findall, (arg, )
+
+def task_sort():
+    """list sorting (C)"""
+    def list_sort(l):
+        l = l[::-1]
+        l.sort()
+
+    return list_sort, (list(range(1000)), )
+
+def task_compress_zlib():
+    """zlib compression (C)"""
+    import zlib
+    with open(__file__, "rb") as f:
+        arg = f.read(5000) * 3
+
+    def compress(s):
+        zlib.decompress(zlib.compress(s, 5))
+    return compress, (arg, )
+
+def task_compress_bz2():
+    """bz2 compression (C)"""
+    import bz2
+    with open(__file__, "rb") as f:
+        arg = f.read(3000) * 2
+
+    def compress(s):
+        bz2.compress(s)
+    return compress, (arg, )
+
+def task_hashing():
+    """SHA1 hashing (C)"""
+    import hashlib
+    with open(__file__, "rb") as f:
+        arg = f.read(5000) * 30
+
+    def compute(s):
+        hashlib.sha1(s).digest()
+    return compute, (arg, )
+
+
+throughput_tasks = [task_pidigits, task_regex]
+for mod in 'bz2', 'hashlib':
+    try:
+        globals()[mod] = __import__(mod)
+    except ImportError:
+        globals()[mod] = None
+
+# For whatever reasons, zlib gives irregular results, so we prefer bz2 or
+# hashlib if available.
+# (NOTE: hashlib releases the GIL from 2.7 and 3.1 onwards)
+if bz2 is not None:
+    throughput_tasks.append(task_compress_bz2)
+elif hashlib is not None:
+    throughput_tasks.append(task_hashing)
+else:
+    throughput_tasks.append(task_compress_zlib)
+
+latency_tasks = throughput_tasks
+
+
+class TimedLoop:
+    def __init__(self, func, args):
+        self.func = func
+        self.args = args
+
+    def __call__(self, start_time, min_duration, end_event, do_yield=False):
+        step = 20
+        niters = 0
+        duration = 0.0
+        _time = time.time
+        _sleep = time.sleep
+        _func = self.func
+        _args = self.args
+        t1 = start_time
+        while True:
+            for i in range(step):
+                _func(*_args)
+            t2 = _time()
+            # If another thread terminated, the current measurement is invalid
+            # => return the previous one.
+            if end_event:
+                return niters, duration
+            niters += step
+            duration = t2 - start_time
+            if duration >= min_duration:
+                end_event.append(None)
+                return niters, duration
+            if t2 - t1 < 0.01:
+                # Minimize interference of measurement on overall runtime
+                step = step * 3 // 2
+            elif do_yield:
+                # OS scheduling of Python threads is sometimes so bad that we
+                # have to force thread switching ourselves, otherwise we get
+                # completely useless results.
+                _sleep(0.0001)
+            t1 = t2
+
+
+def run_throughput_test(func, args, nthreads):
+    assert nthreads >= 1
+
+    # Warm up
+    func(*args)
+
+    results = []
+    loop = TimedLoop(func, args)
+    end_event = []
+
+    if nthreads == 1:
+        # Pure single-threaded performance, without any switching or
+        # synchronization overhead.
+        start_time = time.time()
+        results.append(loop(start_time, THROUGHPUT_DURATION,
+                            end_event, do_yield=False))
+        return results
+
+    started = False
+    ready_cond = threading.Condition()
+    start_cond = threading.Condition()
+    ready = []
+
+    def run():
+        with ready_cond:
+            ready.append(None)
+            ready_cond.notify()
+        with start_cond:
+            while not started:
+                start_cond.wait()
+        results.append(loop(start_time, THROUGHPUT_DURATION,
+                            end_event, do_yield=True))
+
+    threads = []
+    for i in range(nthreads):
+        threads.append(threading.Thread(target=run))
+    for t in threads:
+        t.setDaemon(True)
+        t.start()
+    # We don't want measurements to include thread startup overhead,
+    # so we arrange for timing to start after all threads are ready.
+    with ready_cond:
+        while len(ready) < nthreads:
+            ready_cond.wait()
+    with start_cond:
+        start_time = time.time()
+        started = True
+        start_cond.notify(nthreads)
+    for t in threads:
+        t.join()
+
+    return results
+
+def run_throughput_tests(max_threads):
+    for task in throughput_tasks:
+        print(task.__doc__)
+        print()
+        func, args = task()
+        nthreads = 1
+        baseline_speed = None
+        while nthreads <= max_threads:
+            results = run_throughput_test(func, args, nthreads)
+            # Taking the max duration rather than average gives pessimistic
+            # results rather than optimistic.
+            speed = sum(r[0] for r in results) / max(r[1] for r in results)
+            print("threads=%d: %d" % (nthreads, speed), end="")
+            if baseline_speed is None:
+                print(" iterations/s.")
+                baseline_speed = speed
+            else:
+                print(" ( %d %%)" % (speed / baseline_speed * 100))
+            nthreads += 1
+        print()
+
+
+LAT_END = "END"
+
+def _sendto(sock, s, addr):
+    sock.sendto(s.encode('ascii'), addr)
+
+def _recv(sock, n):
+    return sock.recv(n).decode('ascii')
+
+def latency_client(addr, nb_pings, interval):
+    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    _time = time.time
+    _sleep = time.sleep
+    def _ping():
+        _sendto(sock, "%r\n" % _time(), addr)
+    # The first ping signals the parent process that we are ready.
+    _ping()
+    # We give the parent a bit of time to notice.
+    _sleep(1.0)
+    for i in range(nb_pings):
+        _sleep(interval)
+        _ping()
+    _sendto(sock, LAT_END + "\n", addr)
+
+def run_latency_client(**kwargs):
+    cmd_line = [sys.executable, '-E', os.path.abspath(__file__)]
+    cmd_line.extend(['--latclient', repr(kwargs)])
+    return subprocess.Popen(cmd_line) #, stdin=subprocess.PIPE,
+                            #stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+def run_latency_test(func, args, nthreads):
+    # Create a listening socket to receive the pings. We use UDP which should
+    # be painlessly cross-platform.
+    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    sock.bind(("127.0.0.1", 0))
+    addr = sock.getsockname()
+
+    interval = LATENCY_PING_INTERVAL
+    duration = LATENCY_DURATION
+    nb_pings = int(duration / interval)
+
+    results = []
+    threads = []
+    end_event = []
+    start_cond = threading.Condition()
+    started = False
+    if nthreads > 0:
+        # Warm up
+        func(*args)
+
+        results = []
+        loop = TimedLoop(func, args)
+        ready = []
+        ready_cond = threading.Condition()
+
+        def run():
+            with ready_cond:
+                ready.append(None)
+                ready_cond.notify()
+            with start_cond:
+                while not started:
+                    start_cond.wait()
+            loop(start_time, duration * 1.5, end_event, do_yield=False)
+
+        for i in range(nthreads):
+            threads.append(threading.Thread(target=run))
+        for t in threads:
+            t.setDaemon(True)
+            t.start()
+        # Wait for threads to be ready
+        with ready_cond:
+            while len(ready) < nthreads:
+                ready_cond.wait()
+
+    # Run the client and wait for the first ping(s) to arrive before
+    # unblocking the background threads.
+    chunks = []
+    process = run_latency_client(addr=sock.getsockname(),
+                                 nb_pings=nb_pings, interval=interval)
+    s = _recv(sock, 4096)
+    _time = time.time
+
+    with start_cond:
+        start_time = _time()
+        started = True
+        start_cond.notify(nthreads)
+
+    while LAT_END not in s:
+        s = _recv(sock, 4096)
+        t = _time()
+        chunks.append((t, s))
+
+    # Tell the background threads to stop.
+    end_event.append(None)
+    for t in threads:
+        t.join()
+    process.wait()
+
+    for recv_time, chunk in chunks:
+        # NOTE: it is assumed that a line sent by a client wasn't received
+        # in two chunks because the lines are very small.
+        for line in chunk.splitlines():
+            line = line.strip()
+            if line and line != LAT_END:
+                send_time = eval(line)
+                assert isinstance(send_time, float)
+                results.append((send_time, recv_time))
+
+    return results
+
+def run_latency_tests(max_threads):
+    for task in latency_tasks:
+        print("Background CPU task:", task.__doc__)
+        print()
+        func, args = task()
+        nthreads = 0
+        while nthreads <= max_threads:
+            results = run_latency_test(func, args, nthreads)
+            n = len(results)
+            # We print out milliseconds
+            lats = [1000 * (t2 - t1) for (t1, t2) in results]
+            #print(list(map(int, lats)))
+            avg = sum(lats) / n
+            dev = (sum((x - avg) ** 2 for x in lats) / n) ** 0.5
+            print("CPU threads=%d: %d ms. (std dev: %d ms.)" % (nthreads, avg, dev), end="")
+            print()
+            #print("    [... from %d samples]" % n)
+            nthreads += 1
+        print()
+
+
+def main():
+    usage = "usage: %prog [-h|--help] [options]"
+    parser = OptionParser(usage=usage)
+    parser.add_option("-t", "--throughput",
+                      action="store_true", dest="throughput", default=False,
+                      help="run throughput tests")
+    parser.add_option("-l", "--latency",
+                      action="store_true", dest="latency", default=False,
+                      help="run latency tests")
+    parser.add_option("-i", "--interval",
+                      action="store", type="int", dest="check_interval", default=None,
+                      help="sys.setcheckinterval() value")
+    parser.add_option("-I", "--switch-interval",
+                      action="store", type="float", dest="switch_interval", default=None,
+                      help="sys.setswitchinterval() value")
+    parser.add_option("-n", "--num-threads",
+                      action="store", type="int", dest="nthreads", default=4,
+                      help="max number of threads in tests")
+
+    # Hidden option to run the pinging client
+    parser.add_option("", "--latclient",
+                      action="store", dest="latclient", default=None,
+                      help=SUPPRESS_HELP)
+
+    options, args = parser.parse_args()
+    if args:
+        parser.error("unexpected arguments")
+
+    if options.latclient:
+        kwargs = eval(options.latclient)
+        latency_client(**kwargs)
+        return
+
+    if not options.throughput and not options.latency:
+        options.throughput = options.latency = True
+    if options.check_interval:
+        sys.setcheckinterval(options.check_interval)
+    if options.switch_interval:
+        sys.setswitchinterval(options.switch_interval)
+
+    print("== %s %s (%s) ==" % (
+        platform.python_implementation(),
+        platform.python_version(),
+        platform.python_build()[0],
+    ))
+    # Processor identification often has repeated spaces
+    cpu = ' '.join(platform.processor().split())
+    print("== %s %s on '%s' ==" % (
+        platform.machine(),
+        platform.system(),
+        cpu,
+    ))
+    print()
+
+    if options.throughput:
+        print("--- Throughput ---")
+        print()
+        run_throughput_tests(options.nthreads)
+
+    if options.latency:
+        print("--- Latency ---")
+        print()
+        run_latency_tests(options.nthreads)
+
+if __name__ == "__main__":
+    main()
diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py
new file mode 100644
index 0000000..92b4ffa
--- /dev/null
+++ b/Tools/iobench/iobench.py
@@ -0,0 +1,539 @@
+# -*- coding: utf-8 -*-
+# This file should be kept compatible with both Python 2.6 and Python >= 3.0.
+
+import time
+import os
+import re
+import sys
+import hashlib
+import functools
+import itertools
+from optparse import OptionParser
+
+out = sys.stdout
+
+TEXT_ENCODING = 'utf8'
+NEWLINES = 'lf'
+
+# Compatibility
+try:
+    xrange
+except NameError:
+    xrange = range
+
+def text_open(fn, mode, encoding=None):
+    try:
+        return open(fn, mode, encoding=encoding or TEXT_ENCODING)
+    except TypeError:
+        return open(fn, mode)
+
+def get_file_sizes():
+    for s in ['20 KB', '400 KB', '10 MB']:
+        size, unit = s.split()
+        size = int(size) * {'KB': 1024, 'MB': 1024 ** 2}[unit]
+        yield s.replace(' ', ''), size
+
+def get_binary_files():
+    return ((name + ".bin", size) for name, size in get_file_sizes())
+
+def get_text_files():
+    return (("%s-%s-%s.txt" % (name, TEXT_ENCODING, NEWLINES), size)
+        for name, size in get_file_sizes())
+
+def with_open_mode(mode):
+    def decorate(f):
+        f.file_open_mode = mode
+        return f
+    return decorate
+
+def with_sizes(*sizes):
+    def decorate(f):
+        f.file_sizes = sizes
+        return f
+    return decorate
+
+
+# Here begin the tests
+
+@with_open_mode("r")
+@with_sizes("medium")
+def read_bytewise(f):
+    """ read one unit at a time """
+    f.seek(0)
+    while f.read(1):
+        pass
+
+@with_open_mode("r")
+@with_sizes("medium")
+def read_small_chunks(f):
+    """ read 20 units at a time """
+    f.seek(0)
+    while f.read(20):
+        pass
+
+@with_open_mode("r")
+@with_sizes("medium")
+def read_big_chunks(f):
+    """ read 4096 units at a time """
+    f.seek(0)
+    while f.read(4096):
+        pass
+
+@with_open_mode("r")
+@with_sizes("small", "medium", "large")
+def read_whole_file(f):
+    """ read whole contents at once """
+    f.seek(0)
+    while f.read():
+        pass
+
+@with_open_mode("rt")
+@with_sizes("medium")
+def read_lines(f):
+    """ read one line at a time """
+    f.seek(0)
+    for line in f:
+        pass
+
+@with_open_mode("r")
+@with_sizes("medium")
+def seek_forward_bytewise(f):
+    """ seek forward one unit at a time """
+    f.seek(0, 2)
+    size = f.tell()
+    f.seek(0, 0)
+    for i in xrange(0, size - 1):
+        f.seek(i, 0)
+
+@with_open_mode("r")
+@with_sizes("medium")
+def seek_forward_blockwise(f):
+    """ seek forward 1000 units at a time """
+    f.seek(0, 2)
+    size = f.tell()
+    f.seek(0, 0)
+    for i in xrange(0, size - 1, 1000):
+        f.seek(i, 0)
+
+@with_open_mode("rb")
+@with_sizes("medium")
+def read_seek_bytewise(f):
+    """ alternate read & seek one unit """
+    f.seek(0)
+    while f.read(1):
+        f.seek(1, 1)
+
+@with_open_mode("rb")
+@with_sizes("medium")
+def read_seek_blockwise(f):
+    """ alternate read & seek 1000 units """
+    f.seek(0)
+    while f.read(1000):
+        f.seek(1000, 1)
+
+
+@with_open_mode("w")
+@with_sizes("small")
+def write_bytewise(f, source):
+    """ write one unit at a time """
+    for i in xrange(0, len(source)):
+        f.write(source[i:i+1])
+
+@with_open_mode("w")
+@with_sizes("medium")
+def write_small_chunks(f, source):
+    """ write 20 units at a time """
+    for i in xrange(0, len(source), 20):
+        f.write(source[i:i+20])
+
+@with_open_mode("w")
+@with_sizes("medium")
+def write_medium_chunks(f, source):
+    """ write 4096 units at a time """
+    for i in xrange(0, len(source), 4096):
+        f.write(source[i:i+4096])
+
+@with_open_mode("w")
+@with_sizes("large")
+def write_large_chunks(f, source):
+    """ write 1e6 units at a time """
+    for i in xrange(0, len(source), 1000000):
+        f.write(source[i:i+1000000])
+
+
+@with_open_mode("w+")
+@with_sizes("small")
+def modify_bytewise(f, source):
+    """ modify one unit at a time """
+    f.seek(0)
+    for i in xrange(0, len(source)):
+        f.write(source[i:i+1])
+
+@with_open_mode("w+")
+@with_sizes("medium")
+def modify_small_chunks(f, source):
+    """ modify 20 units at a time """
+    f.seek(0)
+    for i in xrange(0, len(source), 20):
+        f.write(source[i:i+20])
+
+@with_open_mode("w+")
+@with_sizes("medium")
+def modify_medium_chunks(f, source):
+    """ modify 4096 units at a time """
+    f.seek(0)
+    for i in xrange(0, len(source), 4096):
+        f.write(source[i:i+4096])
+
+@with_open_mode("wb+")
+@with_sizes("medium")
+def modify_seek_forward_bytewise(f, source):
+    """ alternate write & seek one unit """
+    f.seek(0)
+    for i in xrange(0, len(source), 2):
+        f.write(source[i:i+1])
+        f.seek(i+2)
+
+@with_open_mode("wb+")
+@with_sizes("medium")
+def modify_seek_forward_blockwise(f, source):
+    """ alternate write & seek 1000 units """
+    f.seek(0)
+    for i in xrange(0, len(source), 2000):
+        f.write(source[i:i+1000])
+        f.seek(i+2000)
+
+# XXX the 2 following tests don't work with py3k's text IO
+@with_open_mode("wb+")
+@with_sizes("medium")
+def read_modify_bytewise(f, source):
+    """ alternate read & write one unit """
+    f.seek(0)
+    for i in xrange(0, len(source), 2):
+        f.read(1)
+        f.write(source[i+1:i+2])
+
+@with_open_mode("wb+")
+@with_sizes("medium")
+def read_modify_blockwise(f, source):
+    """ alternate read & write 1000 units """
+    f.seek(0)
+    for i in xrange(0, len(source), 2000):
+        f.read(1000)
+        f.write(source[i+1000:i+2000])
+
+
+read_tests = [
+    read_bytewise, read_small_chunks, read_lines, read_big_chunks,
+    None, read_whole_file, None,
+    seek_forward_bytewise, seek_forward_blockwise,
+    read_seek_bytewise, read_seek_blockwise,
+]
+
+write_tests = [
+    write_bytewise, write_small_chunks, write_medium_chunks, write_large_chunks,
+]
+
+modify_tests = [
+    modify_bytewise, modify_small_chunks, modify_medium_chunks,
+    None,
+    modify_seek_forward_bytewise, modify_seek_forward_blockwise,
+    read_modify_bytewise, read_modify_blockwise,
+]
+
+def run_during(duration, func):
+    _t = time.time
+    n = 0
+    start = os.times()
+    start_timestamp = _t()
+    real_start = start[4] or start_timestamp
+    while True:
+        func()
+        n += 1
+        if _t() - start_timestamp > duration:
+            break
+    end = os.times()
+    real = (end[4] if start[4] else time.time()) - real_start
+    return n, real, sum(end[0:2]) - sum(start[0:2])
+
+def warm_cache(filename):
+    with open(filename, "rb") as f:
+        f.read()
+
+
+def run_all_tests(options):
+    def print_label(filename, func):
+        name = re.split(r'[-.]', filename)[0]
+        out.write(
+            ("[%s] %s... "
+                % (name.center(7), func.__doc__.strip())
+            ).ljust(52))
+        out.flush()
+
+    def print_results(size, n, real, cpu):
+        bw = n * float(size) / 1024 ** 2 / real
+        bw = ("%4d MB/s" if bw > 100 else "%.3g MB/s") % bw
+        out.write(bw.rjust(12) + "\n")
+        if cpu < 0.90 * real:
+            out.write("   warning: test above used only %d%% CPU, "
+                "result may be flawed!\n" % (100.0 * cpu / real))
+
+    def run_one_test(name, size, open_func, test_func, *args):
+        mode = test_func.file_open_mode
+        print_label(name, test_func)
+        if "w" not in mode or "+" in mode:
+            warm_cache(name)
+        with open_func(name) as f:
+            n, real, cpu = run_during(1.5, lambda: test_func(f, *args))
+        print_results(size, n, real, cpu)
+
+    def run_test_family(tests, mode_filter, files, open_func, *make_args):
+        for test_func in tests:
+            if test_func is None:
+                out.write("\n")
+                continue
+            if mode_filter in test_func.file_open_mode:
+                continue
+            for s in test_func.file_sizes:
+                name, size = files[size_names[s]]
+                #name += file_ext
+                args = tuple(f(name, size) for f in make_args)
+                run_one_test(name, size,
+                    open_func, test_func, *args)
+
+    size_names = {
+        "small": 0,
+        "medium": 1,
+        "large": 2,
+    }
+
+    binary_files = list(get_binary_files())
+    text_files = list(get_text_files())
+    if "b" in options:
+        print("Binary unit = one byte")
+    if "t" in options:
+        print("Text unit = one character (%s-decoded)" % TEXT_ENCODING)
+
+    # Binary reads
+    if "b" in options and "r" in options:
+        print("\n** Binary input **\n")
+        run_test_family(read_tests, "t", binary_files, lambda fn: open(fn, "rb"))
+
+    # Text reads
+    if "t" in options and "r" in options:
+        print("\n** Text input **\n")
+        run_test_family(read_tests, "b", text_files, lambda fn: text_open(fn, "r"))
+
+    # Binary writes
+    if "b" in options and "w" in options:
+        print("\n** Binary append **\n")
+        def make_test_source(name, size):
+            with open(name, "rb") as f:
+                return f.read()
+        run_test_family(write_tests, "t", binary_files,
+            lambda fn: open(os.devnull, "wb"), make_test_source)
+
+    # Text writes
+    if "t" in options and "w" in options:
+        print("\n** Text append **\n")
+        def make_test_source(name, size):
+            with text_open(name, "r") as f:
+                return f.read()
+        run_test_family(write_tests, "b", text_files,
+            lambda fn: text_open(os.devnull, "w"), make_test_source)
+
+    # Binary overwrites
+    if "b" in options and "w" in options:
+        print("\n** Binary overwrite **\n")
+        def make_test_source(name, size):
+            with open(name, "rb") as f:
+                return f.read()
+        run_test_family(modify_tests, "t", binary_files,
+            lambda fn: open(fn, "r+b"), make_test_source)
+
+    # Text overwrites
+    if "t" in options and "w" in options:
+        print("\n** Text overwrite **\n")
+        def make_test_source(name, size):
+            with text_open(name, "r") as f:
+                return f.read()
+        run_test_family(modify_tests, "b", text_files,
+            lambda fn: open(fn, "r+"), make_test_source)
+
+
+def prepare_files():
+    print("Preparing files...")
+    # Binary files
+    for name, size in get_binary_files():
+        if os.path.isfile(name) and os.path.getsize(name) == size:
+            continue
+        with open(name, "wb") as f:
+            f.write(os.urandom(size))
+    # Text files
+    chunk = []
+    with text_open(__file__, "rU", encoding='utf8') as f:
+        for line in f:
+            if line.startswith("# <iobench text chunk marker>"):
+                break
+        else:
+            raise RuntimeError(
+                "Couldn't find chunk marker in %s !" % __file__)
+        if NEWLINES == "all":
+            it = itertools.cycle(["\n", "\r", "\r\n"])
+        else:
+            it = itertools.repeat(
+                {"cr": "\r", "lf": "\n", "crlf": "\r\n"}[NEWLINES])
+        chunk = "".join(line.replace("\n", next(it)) for line in f)
+        if isinstance(chunk, bytes):
+            chunk = chunk.decode('utf8')
+        chunk = chunk.encode(TEXT_ENCODING)
+    for name, size in get_text_files():
+        if os.path.isfile(name) and os.path.getsize(name) == size:
+            continue
+        head = chunk * (size // len(chunk))
+        tail = chunk[:size % len(chunk)]
+        # Adjust tail to end on a character boundary
+        while True:
+            try:
+                tail.decode(TEXT_ENCODING)
+                break
+            except UnicodeDecodeError:
+                tail = tail[:-1]
+        with open(name, "wb") as f:
+            f.write(head)
+            f.write(tail)
+
+def main():
+    global TEXT_ENCODING, NEWLINES
+
+    usage = "usage: %prog [-h|--help] [options]"
+    parser = OptionParser(usage=usage)
+    parser.add_option("-b", "--binary",
+                      action="store_true", dest="binary", default=False,
+                      help="run binary I/O tests")
+    parser.add_option("-t", "--text",
+                      action="store_true", dest="text", default=False,
+                      help="run text I/O tests")
+    parser.add_option("-r", "--read",
+                      action="store_true", dest="read", default=False,
+                      help="run read tests")
+    parser.add_option("-w", "--write",
+                      action="store_true", dest="write", default=False,
+                      help="run write & modify tests")
+    parser.add_option("-E", "--encoding",
+                      action="store", dest="encoding", default=None,
+                      help="encoding for text tests (default: %s)" % TEXT_ENCODING)
+    parser.add_option("-N", "--newlines",
+                      action="store", dest="newlines", default='lf',
+                      help="line endings for text tests "
+                           "(one of: {lf (default), cr, crlf, all})")
+    options, args = parser.parse_args()
+    if args:
+        parser.error("unexpected arguments")
+    NEWLINES = options.newlines.lower()
+    if NEWLINES not in ('lf', 'cr', 'crlf', 'all'):
+        parser.error("invalid 'newlines' option: %r" % NEWLINES)
+
+    test_options = ""
+    if options.read:
+        test_options += "r"
+    if options.write:
+        test_options += "w"
+    elif not options.read:
+        test_options += "rw"
+    if options.text:
+        test_options += "t"
+    if options.binary:
+        test_options += "b"
+    elif not options.text:
+        test_options += "tb"
+
+    if options.encoding:
+        TEXT_ENCODING = options.encoding
+
+    prepare_files()
+    run_all_tests(test_options)
+
+if __name__ == "__main__":
+    main()
+
+
+# -- This part to exercise text reading. Don't change anything! --
+# <iobench text chunk marker>
+
+"""
+1.
+Gáttir allar,
+áðr gangi fram,
+um skoðask skyli,
+um skyggnast skyli,
+því at óvíst er at vita,
+hvar óvinir
+sitja á fleti fyrir.
+
+2.
+Gefendr heilir!
+Gestr er inn kominn,
+hvar skal sitja sjá?
+Mjök er bráðr,
+sá er á bröndum skal
+síns of freista frama.
+
+3.
+Elds er þörf,
+þeims inn er kominn
+ok á kné kalinn;
+matar ok váða
+er manni þörf,
+þeim er hefr um fjall farit.
+
+4.
+Vatns er þörf,
+þeim er til verðar kemr,
+þerru ok þjóðlaðar,
+góðs of æðis,
+ef sér geta mætti,
+orðs ok endrþögu.
+
+5.
+Vits er þörf,
+þeim er víða ratar;
+dælt er heima hvat;
+at augabragði verðr,
+sá er ekki kann
+ok með snotrum sitr.
+
+6.
+At hyggjandi sinni
+skyli-t maðr hræsinn vera,
+heldr gætinn at geði;
+þá er horskr ok þögull
+kemr heimisgarða til,
+sjaldan verðr víti vörum,
+því at óbrigðra vin
+fær maðr aldregi
+en mannvit mikit.
+
+7.
+Inn vari gestr,
+er til verðar kemr,
+þunnu hljóði þegir,
+eyrum hlýðir,
+en augum skoðar;
+svá nýsisk fróðra hverr fyrir.
+
+8.
+Hinn er sæll,
+er sér of getr
+lof ok líknstafi;
+ódælla er við þat,
+er maðr eiga skal
+annars brjóstum í.
+"""
+
+"""
+C'est revenir tard, je le sens, sur un sujet trop rebattu et déjà presque oublié. Mon état, qui ne me permet plus aucun travail suivi, mon aversion pour le genre polémique, ont causé ma lenteur à écrire et ma répugnance à publier. J'aurais même tout à fait supprimé ces Lettres, ou plutôt je lie les aurais point écrites, s'il n'eût été question que de moi : Mais ma patrie ne m'est pas tellement devenue étrangère que je puisse voir tranquillement opprimer ses citoyens, surtout lorsqu'ils n'ont compromis leurs droits qu'en défendant ma cause. Je serais le dernier des hommes si dans une telle occasion j'écoutais un sentiment qui n'est plus ni douceur ni patience, mais faiblesse et lâcheté, dans celui qu'il empêche de remplir son devoir.
+Rien de moins important pour le public, j'en conviens, que la matière de ces lettres. La constitution d'une petite République, le sort d'un petit particulier, l'exposé de quelques injustices, la réfutation de quelques sophismes ; tout cela n'a rien en soi d'assez considérable pour mériter beaucoup de lecteurs : mais si mes sujets sont petits mes objets sont grands, et dignes de l'attention de tout honnête homme. Laissons Genève à sa place, et Rousseau dans sa dépression ; mais la religion, mais la liberté, la justice ! voilà, qui que vous soyez, ce qui n'est pas au-dessous de vous.
+Qu'on ne cherche pas même ici dans le style le dédommagement de l'aridité de la matière. Ceux que quelques traits heureux de ma plume ont si fort irrités trouveront de quoi s'apaiser dans ces lettres, L'honneur de défendre un opprimé eût enflammé mon coeur si j'avais parlé pour un autre. Réduit au triste emploi de me défendre moi-même, j'ai dû me borner à raisonner ; m'échauffer eût été m'avilir. J'aurai donc trouvé grâce en ce point devant ceux qui s'imaginent qu'il est essentiel à la vérité d'être dite froidement ; opinion que pourtant j'ai peine à comprendre. Lorsqu'une vive persuasion nous anime, le moyen d'employer un langage glacé ? Quand Archimède tout transporté courait nu dans les rues de Syracuse, en avait-il moins trouvé la vérité parce qu'il se passionnait pour elle ? Tout au contraire, celui qui la sent ne peut s'abstenir de l'adorer ; celui qui demeure froid ne l'a pas vue.
+Quoi qu'il en soit, je prie les lecteurs de vouloir bien mettre à part mon beau style, et d'examiner seulement si je raisonne bien ou mal ; car enfin, de cela seul qu'un auteur s'exprime en bons termes, je ne vois pas comment il peut s'ensuivre que cet auteur ne sait ce qu'il dit.
+"""
