     [ new RegExp("^.*/shell/.*$"),
      new RegExp("^.*/extensions/ST_.*$"),
      new RegExp("^.*/extensions/JavaGlue.*$"),
+     new RegExp("^.*/eval/.*$"),
      new RegExp("^.*/MMgc/GCTests.*$")];
 
 class LineInfo
 {
-    function LineInfo(_derived, _base, _filename, _lineno) {
+    function LineInfo(_derived, _base, _isExact, _filename, _lineno) {
         derived = _derived;
         base = _base;
+        isExact = _isExact;
         filename = _filename;
         lineno = _lineno;
     }
+
+    public function toString() {
+        return "derived=" + derived + ", base=" + base + ", filename=" + filename + ", lineno=" + lineno + ", defcount=" + defcount;
+    }
+
     var derived;            // name of the class being defined
     var base;               // name of its base class
+    var isExact;            // true iff the class is exactly traced
     var filename;           // file where we found the definition of 'derived'
     var lineno;             // line where we found the definition of 'derived'
     var baseref = null;     // reference to the LineInfo for the base class
     var subrefs = [];       // list of known subclasses
     var destructor = false; // true if we believe this has a destructor
+    var defcount = 0;       // number of definitions
+    var otherlines = [];    // for in-tree lines beyond the first: locations of definition: { filename:x, lineno:n }
+    var exolines = [];      // for out-of-tree lines: locations of definition: { filename:x, lineno:n }
+    var external = false;   // true if there are definitions of the 'derived' name not within the tree
 }
 
 main(System.argv);

}

function printClasses(classes) {
    printCls(classes[rootclass], 0);

    function printCls(cls, indent) {
        if (!ignoreIt(cls)) {
            var d = cls.destructor ? " * " : "   ";
            print(d + padTo50(spaces(indent) + cls.derived) + " " + cls.filename + ":" + cls.lineno);
        }
        cls.subrefs.sort(function (a,b) { return strcmp(a.derived, b.derived); })
        for ( var i=0 ; i < cls.subrefs.length ; i++ ) {

// Input is a bunch of file names and/or names of files from which to read file names.
//
// Output is a tree of classes derived from a root class (default GCFinalizedObject),
// with per-class annotations:
//
//   - a "D" if the class has an explicit Destructor
//   - a "E" if the class is Exactly traced
//
// Each class is printed with the file and line on which the definition starts.
//
// At the end some statistics are printed.
//
// Assumes names are globally unique (namespaces don't matter).  Is tricked by macro
// definitions like in the Error objects, and by the use of the bitwise not operator
