diff --git a/Tools/scripts/trace.py b/Tools/scripts/trace.py
new file mode 100644
index 0000000..ec0d45f
--- /dev/null
+++ b/Tools/scripts/trace.py
@@ -0,0 +1,661 @@
+#!/usr/bin/env python
+
+# Copyright 2000, Mojam Media, Inc., all rights reserved.
+# Author: Skip Montanaro
+#
+# Copyright 1999, Bioreason, Inc., all rights reserved.
+# Author: Andrew Dalke
+#
+# Copyright 1995-1997, Automatrix, Inc., all rights reserved.
+# Author: Skip Montanaro
+#
+# Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved.
+#
+#
+# Permission to use, copy, modify, and distribute this Python software and
+# its associated documentation for any purpose without fee is hereby
+# granted, provided that the above copyright notice appears in all copies,
+# and that both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of neither Automatrix,
+# Bioreason or Mojam Media be used in advertising or publicity pertaining to
+# distribution of the software without specific, written prior permission.
+#
+#
+# Summary of recent changes:
+#   Support for files with the same basename (submodules in packages)
+#   Expanded the idea of how to ignore files or modules
+#   Split tracing and counting into different classes
+#   Extracted count information and reporting from the count class
+#   Added some ability to detect which missing lines could be executed
+#   Added pseudo-pragma to prohibit complaining about unexecuted lines
+#   Rewrote the main program
+
+# Summary of older changes:
+#   Added run-time display of statements being executed
+#   Incorporated portability and performance fixes from Greg Stein
+#   Incorporated main program from Michael Scharf
+
+"""
+program/module to trace Python program or function execution
+
+Sample use, command line:
+  trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs
+  trace.py -t --ignore-dir '$prefix' spam.py eggs
+
+Sample use, programmatically (still more complicated than it should be)
+   # create an Ignore option, telling it what you want to ignore
+   ignore = trace.Ignore(dirs = [sys.prefix, sys.exec_prefix])
+   # create a Coverage object, telling it what to ignore
+   coverage = trace.Coverage(ignore)
+   # run the new command using the given trace
+   trace.run(coverage.trace, 'main()')
+
+   # make a report, telling it where you want output
+   t = trace.create_results_log(coverage.results(),
+                                '/usr/local/Automatrix/concerts/coverage')
+                                show_missing = 1)
+
+   The Trace class can be instantited instead of the Coverage class if
+   runtime display of executable lines is desired instead of statement
+   converage measurement.
+"""
+
+import sys, os, string, marshal, tempfile, copy, operator
+
+def usage(outfile):
+    outfile.write("""Usage: %s [OPTIONS] <file> [ARGS]
+
+Execution:
+      --help           Display this help then exit.
+      --version        Output version information then exit.
+   -t,--trace          Print the line to be executed to sys.stdout.
+   -c,--count          Count the number of times a line is executed.
+                         Results are written in the results file, if given.
+   -r,--report         Generate a report from a results file; do not
+                         execute any code.
+        (One of `-t', `-c' or `-r' must be specified)
+
+I/O:
+   -f,--file=          File name for accumulating results over several runs.
+                         (No file name means do not archive results)
+   -d,--logdir=        Directory to use when writing annotated log files.
+                         Log files are the module __name__ with `.` replaced
+                         by os.sep and with '.pyl' added.
+   -m,--missing        Annotate all executable lines which were not executed
+                         with a '>>>>>> '.
+   -R,--no-report      Do not generate the annotated reports.  Useful if
+                         you want to accumulate several over tests.
+
+Selection:                 Do not trace or log lines from ...
+  --ignore-module=[string]   modules with the given __name__, and submodules
+                              of that module
+  --ignore-dir=[string]      files in the stated directory (multiple
+                              directories can be joined by os.pathsep)
+
+  The selection options can be listed multiple times to ignore different
+modules.
+""" % sys.argv[0])
+
+
+class Ignore:
+    def __init__(self, modules = None, dirs = None):
+	self._mods = modules or []
+	self._dirs = dirs or []
+
+	self._ignore = { '<string>': 1 }
+
+
+    def names(self, filename, modulename):
+	if self._ignore.has_key(modulename):
+	    return self._ignore[modulename]
+
+	# haven't seen this one before, so see if the module name is
+	# on the ignore list.  Need to take some care since ignoring
+	# "cmp" musn't mean ignoring "cmpcache" but ignoring
+	# "Spam" must also mean ignoring "Spam.Eggs".
+	for mod in self._mods:
+	    if mod == modulename:  # Identical names, so ignore
+		self._ignore[modulename] = 1
+		return 1
+	    # check if the module is a proper submodule of something on
+	    # the ignore list
+	    n = len(mod)
+	    # (will not overflow since if the first n characters are the
+	    # same and the name has not already occured, then the size
+	    # of "name" is greater than that of "mod")
+	    if mod == modulename[:n] and modulename[n] == '.':
+		self._ignore[modulename] = 1
+		return 1
+
+	# Now check that __file__ isn't in one of the directories
+	if filename is None:
+	    # must be a built-in, so we must ignore
+	    self._ignore[modulename] = 1
+	    return 1
+
+	# Ignore a file when it contains one of the ignorable paths
+	for d in self._dirs:
+	    # The '+ os.sep' is to ensure that d is a parent directory,
+	    # as compared to cases like:
+	    #  d = "/usr/local"
+	    #  filename = "/usr/local.py"
+	    # or
+	    #  d = "/usr/local.py"
+	    #  filename = "/usr/local.py"
+	    if string.find(filename, d + os.sep) == 0:
+		self._ignore[modulename] = 1
+		return 1
+
+	# Tried the different ways, so we don't ignore this module
+	self._ignore[modulename] = 0
+	return 0
+	
+
+def run(trace, cmd):
+    import __main__
+    dict = __main__.__dict__
+    sys.settrace(trace)
+    try:
+	exec cmd in dict, dict
+    finally:
+	sys.settrace(None)
+
+def runctx(trace, cmd, globals=None, locals=None):
+    if globals is None: globals = {}
+    if locals is None: locals = {}
+    sys.settrace(trace)
+    try:
+	exec cmd in dict, dict
+    finally:
+	sys.settrace(None)
+
+def runfunc(trace, func, *args, **kw):
+    result = None
+    sys.settrace(trace)
+    try:
+	result = apply(func, args, kw)
+    finally:
+	sys.settrace(None)
+    return result
+
+
+class CoverageResults:
+    def __init__(self, counts = {}, modules = {}):
+	self.counts = counts.copy()    # map (filename, lineno) to count
+	self.modules = modules.copy()  # map filenames to modules
+
+    def update(self, other):
+	"""Merge in the data from another CoverageResults"""
+	counts = self.counts
+	other_counts = other.counts
+	modules = self.modules
+	other_modules = other.modules
+
+	for key in other_counts.keys():
+	    counts[key] = counts.get(key, 0) + other_counts[key]
+
+	for key in other_modules.keys():
+	    if modules.has_key(key):
+		# make sure they point to the same file
+		assert modules[key] == other_modules[key], \
+		       "Strange! filename %s has two different module names" % \
+		       (key, modules[key], other_module[key])
+	    else:
+		modules[key] = other_modules[key]
+
+# Given a code string, return the SET_LINENO information
+def _find_LINENO_from_string(co_code):
+    """return all of the SET_LINENO information from a code string"""
+    import dis
+    linenos = {}
+
+    # This code was filched from the `dis' module then modified
+    n = len(co_code)
+    i = 0
+    prev_op = None
+    prev_lineno = 0
+    while i < n:
+	c = co_code[i]
+	op = ord(c)
+	if op == dis.SET_LINENO:
+	    if prev_op == op:
+		# two SET_LINENO in a row, so the previous didn't
+		# indicate anything.  This occurs with triple
+		# quoted strings (?).  Remove the old one.
+		del linenos[prev_lineno]
+	    prev_lineno = ord(co_code[i+1]) + ord(co_code[i+2])*256
+	    linenos[prev_lineno] = 1
+	if op >= dis.HAVE_ARGUMENT:
+	    i = i + 3
+	else:
+	    i = i + 1
+	prev_op = op
+    return linenos
+
+def _find_LINENO(code):
+    """return all of the SET_LINENO information from a code object"""
+    import types
+
+    # get all of the lineno information from the code of this scope level
+    linenos = _find_LINENO_from_string(code.co_code)
+
+    # and check the constants for references to other code objects
+    for c in code.co_consts:
+	if type(c) == types.CodeType:
+	    # find another code object, so recurse into it
+	    linenos.update(_find_LINENO(c))
+    return linenos
+
+def find_executable_linenos(filename):
+    """return a dict of the line numbers from executable statements in a file
+
+    Works by finding all of the code-like objects in the module then searching
+    the byte code for 'SET_LINENO' terms (so this won't work one -O files).
+
+    """
+    import parser
+
+    prog = open(filename).read()
+    ast = parser.suite(prog)
+    code = parser.compileast(ast, filename)
+
+    # The only way I know to find line numbers is to look for the
+    # SET_LINENO instructions.  Isn't there some way to get it from
+    # the AST?
+    
+    return _find_LINENO(code)
+
+### XXX because os.path.commonprefix seems broken by my way of thinking...
+def commonprefix(dirs):
+    "Given a list of pathnames, returns the longest common leading component"
+    if not dirs: return ''
+    n = copy.copy(dirs)
+    for i in range(len(n)):
+        n[i] = n[i].split(os.sep)
+    prefix = n[0]
+    for item in n:
+        for i in range(len(prefix)):
+            if prefix[:i+1] <> item[:i+1]:
+                prefix = prefix[:i]
+                if i == 0: return ''
+                break
+    return os.sep.join(prefix)
+    
+def create_results_log(results, dirname = ".", show_missing = 1,
+                       save_counts = 0):
+    import re
+    # turn the counts data ("(filename, lineno) = count") into something
+    # accessible on a per-file basis
+    per_file = {}
+    for filename, lineno in results.counts.keys():
+        lines_hit = per_file[filename] = per_file.get(filename, {})
+	lines_hit[lineno] = results.counts[(filename, lineno)]
+
+    # try and merge existing counts and modules file from dirname
+    try:
+        counts = marshal.load(open(os.path.join(dirname, "counts")))
+        modules = marshal.load(open(os.path.join(dirname, "modules")))
+        results.update(results.__class__(counts, modules))
+    except IOError:
+        pass
+    
+    # there are many places where this is insufficient, like a blank
+    # line embedded in a multiline string.
+    blank = re.compile(r'^\s*(#.*)?$')
+
+    # generate file paths for the coverage files we are going to write...
+    fnlist = []
+    tfdir = tempfile.gettempdir()
+    for key in per_file.keys():
+        filename = key
+        
+        # skip some "files" we don't care about...
+        if filename == "<string>":
+            continue
+        # are these caused by code compiled using exec or something?
+        if filename.startswith(tfdir):
+            continue
+
+        # XXX this is almost certainly not portable!!!
+        fndir = os.path.dirname(filename)
+        if filename[:1] == os.sep:
+            coverpath = os.path.join(dirname, "."+fndir)
+        else:
+            coverpath = os.path.join(dirname, fndir)
+
+	if filename.endswith(".pyc") or filename.endswith(".pyo"):
+            filename = filename[:-1]
+
+	# Get the original lines from the .py file
+	try:
+	    lines = open(filename, 'r').readlines()
+	except IOError, err:
+	    sys.stderr.write(
+		"%s: Could not open %s for reading because: %s - skipping\n" % \
+		("trace", `filename`, err.strerror))
+	    continue
+
+	modulename = os.path.split(results.modules[key])[1]
+
+	# build list file name by appending a ".cover" to the module name
+	# and sticking it into the specified directory
+	listfilename = os.path.join(coverpath, modulename + ".cover")
+        #sys.stderr.write("modulename: %(modulename)s\n"
+        #                 "filename: %(filename)s\n"
+        #                 "coverpath: %(coverpath)s\n"
+        #                 "listfilename: %(listfilename)s\n"
+        #                 "dirname: %(dirname)s\n"
+        #                 % locals())
+	try:
+	    outfile = open(listfilename, 'w')
+	except IOError, err:
+	    sys.stderr.write(
+		'%s: Could not open %s for writing because: %s - skipping\n' %
+		("trace", `listfilename`, err.strerror))
+	    continue
+
+	# If desired, get a list of the line numbers which represent
+	# executable content (returned as a dict for better lookup speed)
+	if show_missing:
+	    executable_linenos = find_executable_linenos(filename)
+	else:
+	    executable_linenos = {}
+
+	lines_hit = per_file[key]
+	for i in range(len(lines)):
+	    line = lines[i]
+
+	    # do the blank/comment match to try to mark more lines
+	    # (help the reader find stuff that hasn't been covered)
+	    if lines_hit.has_key(i+1):
+		# count precedes the lines that we captured
+		outfile.write('%5d: ' % lines_hit[i+1])
+	    elif blank.match(line):
+		# blank lines and comments are preceded by dots
+		outfile.write('    . ')
+	    else:
+		# lines preceded by no marks weren't hit
+		# Highlight them if so indicated, unless the line contains
+		# '#pragma: NO COVER' (it is possible to embed this into
+		# the text as a non-comment; no easy fix)
+		if executable_linenos.has_key(i+1) and \
+		   string.find(lines[i],
+                               string.join(['#pragma', 'NO COVER'])) == -1:
+		    outfile.write('>>>>>> ')
+		else:
+		    outfile.write(' '*7)
+	    outfile.write(string.expandtabs(lines[i], 8))
+
+	outfile.close()
+
+        if save_counts:
+            # try and store counts and module info into dirname
+            try:
+                marshal.dump(results.counts,
+                             open(os.path.join(dirname, "counts"), "w"))
+                marshal.dump(results.modules,
+                             open(os.path.join(dirname, "modules"), "w"))
+            except IOError, err:
+                sys.stderr.write("cannot save counts/modules files because %s" %
+                                 err.strerror)
+
+# There is a lot of code shared between these two classes even though
+# it is straightforward to make a super class to share code.  However,
+# for performance reasons (remember, this is called at every step) I
+# wanted to keep everything to a single function call.  Also, by
+# staying within a single scope, I don't have to temporarily nullify
+# sys.settrace, which would slow things down even more.
+
+class Coverage:
+    def __init__(self, ignore = Ignore()):
+	self.ignore = ignore
+	self.ignore_names = ignore._ignore # access ignore's cache (speed hack)
+
+	self.counts = {}   # keys are (filename, linenumber)
+	self.modules = {}  # maps filename -> module name
+
+    def trace(self, frame, why, arg):
+	if why == 'line':
+	    # something is fishy about getting the file name
+	    filename = frame.f_globals.get("__file__", None)
+	    if filename is None:
+		filename = frame.f_code.co_filename
+	    modulename = frame.f_globals["__name__"]
+
+	    # We do this next block to keep from having to make methods
+	    # calls, which also requires resetting the trace
+	    ignore_it = self.ignore_names.get(modulename, -1)
+	    if ignore_it == -1:  # unknown filename
+		sys.settrace(None)
+		ignore_it = self.ignore.names(filename, modulename)
+		sys.settrace(self.trace)
+
+		# record the module name for every file
+		self.modules[filename] = modulename
+
+	    if not ignore_it:
+		lineno = frame.f_lineno
+
+		# record the file name and line number of every trace
+		key = (filename, lineno)
+		self.counts[key] = self.counts.get(key, 0) + 1
+
+	return self.trace
+
+    def results(self):
+	return CoverageResults(self.counts, self.modules)
+
+class Trace:
+    def __init__(self, ignore = Ignore()):
+	self.ignore = ignore
+	self.ignore_names = ignore._ignore # access ignore's cache (speed hack)
+
+	self.files = {'<string>': None}  # stores lines from the .py file, or None
+
+    def trace(self, frame, why, arg):
+	if why == 'line':
+	    filename = frame.f_code.co_filename
+	    modulename = frame.f_globals["__name__"]
+
+	    # We do this next block to keep from having to make methods
+	    # calls, which also requires resetting the trace
+	    ignore_it = self.ignore_names.get(modulename, -1)
+	    if ignore_it == -1:  # unknown filename
+		sys.settrace(None)
+		ignore_it = self.ignore.names(filename, modulename)
+		sys.settrace(self.trace)
+
+	    if not ignore_it:
+		lineno = frame.f_lineno
+		files = self.files
+
+		if filename != '<string>' and not files.has_key(filename):
+                    files[filename] = map(string.rstrip,
+                                          open(filename).readlines())
+
+		# If you want to see filenames (the original behaviour), try:
+		#   modulename = filename
+		# or, prettier but confusing when several files have the same name
+		#   modulename = os.path.basename(filename)
+
+		if files[filename] != None:
+		    print '%s(%d): %s' % (os.path.basename(filename), lineno,
+					  files[filename][lineno-1])
+		else:
+		    print '%s(%d): ??' % (modulename, lineno)
+
+	return self.trace
+    
+
+def _err_exit(msg):
+	sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
+	sys.exit(1)
+
+def main(argv = None):
+    import getopt
+
+    if argv is None:
+	argv = sys.argv
+    try:
+	opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:m",
+					["help", "version", "trace", "count",
+					 "report", "no-report",
+					 "file=", "logdir=", "missing",
+					 "ignore-module=", "ignore-dir="])
+
+    except getopt.error, msg:
+	sys.stderr.write("%s: %s\n" % (sys.argv[0], msg))
+	sys.stderr.write("Try `%s --help' for more information\n" % sys.argv[0])
+	sys.exit(1)
+
+    trace = 0
+    count = 0
+    report = 0
+    no_report = 0
+    counts_file = None
+    logdir = "."
+    missing = 0
+    ignore_modules = []
+    ignore_dirs = []
+
+    for opt, val in opts:
+	if opt == "--help":
+	    usage(sys.stdout)
+	    sys.exit(0)
+
+	if opt == "--version":
+	    sys.stdout.write("trace 2.0\n")
+	    sys.exit(0)
+	
+	if opt == "-t" or opt == "--trace":
+	    trace = 1
+	    continue
+	
+	if opt == "-c" or opt == "--count":
+	    count = 1
+	    continue
+
+	if opt == "-r" or opt == "--report":
+	    report = 1
+	    continue
+
+	if opt == "-R" or opt == "--no-report":
+	    no_report = 1
+	    continue
+	
+	if opt == "-f" or opt == "--file":
+	    counts_file = val
+	    continue
+
+	if opt == "-d" or opt == "--logdir":
+	    logdir = val
+	    continue
+
+	if opt == "-m" or opt == "--missing":
+	    missing = 1
+	    continue
+
+	if opt == "--ignore-module":
+	    ignore_modules.append(val)
+	    continue
+
+	if opt == "--ignore-dir":
+	    for s in string.split(val, os.pathsep):
+		s = os.path.expandvars(s)
+		# should I also call expanduser? (after all, could use $HOME)
+
+		s = string.replace(s, "$prefix",
+				   os.path.join(sys.prefix, "lib",
+						"python" + sys.version[:3]))
+		s = string.replace(s, "$exec_prefix",
+				   os.path.join(sys.exec_prefix, "lib",
+						"python" + sys.version[:3]))
+		s = os.path.normpath(s)
+		ignore_dirs.append(s)
+	    continue
+
+	assert 0, "Should never get here"
+
+    if len(prog_argv) == 0:
+	_err_exit("missing name of file to run")
+
+    if count + trace + report > 1:
+	_err_exit("can only specify one of --trace, --count or --report")
+
+    if count + trace + report == 0:
+	_err_exit("must specify one of --trace, --count or --report")
+
+    if report and counts_file is None:
+	_err_exit("--report requires a --file")
+
+    if report and no_report:
+	_err_exit("cannot specify both --report and --no-report")
+
+    if logdir is not None:
+	# warn if the directory doesn't exist, but keep on going
+	# (is this the correct behaviour?)
+	if not os.path.isdir(logdir):
+	    sys.stderr.write(
+		"trace: WARNING, --logdir directory %s is not available\n" %
+		       `logdir`)
+
+    sys.argv = prog_argv
+    progname = prog_argv[0]
+    if eval(sys.version[:3])>1.3:
+	sys.path[0] = os.path.split(progname)[0] # ???
+
+    # everything is ready
+    ignore = Ignore(ignore_modules, ignore_dirs)
+    if trace:
+	t = Trace(ignore)
+	try:
+	    run(t.trace, 'execfile(' + `progname` + ')')
+	except IOError, err:
+	    _err_exit("Cannot run file %s because: %s" % \
+		      (`sys.argv[0]`, err.strerror))
+
+    elif count:
+	t = Coverage(ignore)
+	try:
+	    run(t.trace, 'execfile(' + `progname` + ')')
+	except IOError, err:
+	    _err_exit("Cannot run file %s because: %s" % \
+		      (`sys.argv[0]`, err.strerror))
+	except SystemExit:
+	    pass
+
+	results = t.results()
+	# Add another lookup from the program's file name to its import name
+	# This give the right results, but I'm not sure why ...
+	results.modules[progname] = os.path.splitext(progname)[0]
+
+	if counts_file:
+	    # add in archived data, if available
+	    try:
+		old_counts, old_modules = marshal.load(open(counts_file, 'rb'))
+	    except IOError:
+		pass
+	    else:
+		results.update(CoverageResults(old_counts, old_modules))
+
+	if not no_report:
+	    create_results_log(results, logdir, missing)
+
+	if counts_file:
+	    try:
+		marshal.dump( (results.counts, results.modules),
+			      open(counts_file, 'wb'))
+	    except IOError, err:
+		_err_exit("Cannot save counts file %s because: %s" % \
+			  (`counts_file`, err.strerror))
+
+    elif report:
+	old_counts, old_modules = marshal.load(open(counts_file, 'rb'))
+	results = CoverageResults(old_counts, old_modules)
+	create_results_log(results, logdir, missing)
+
+    else:
+	assert 0, "Should never get here"
+
+if __name__=='__main__':
+    main()
