/
upgradedb-3.0.1999-08-28/
upgradedb-3.0.1999-08-28/files/
new obj
Inserting httpd_ui.cdc...

new object $httpd_ui: $user_interfaces;

var $root manager = $httpd_ui;
var $command_cache modules = [];
var $root flags = ['variables, 'methods, 'code, 'core, 'general_cache];
var $root created_on = 887523264;
var $dmi_data descriptions = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@list-entries", [["@list-entries", "on *", "@list-entries on <descendant of $directories>", 'list_entries_cmd, #[[2, ['descendant, [$directories]]]]]]], ["@add-entry", [["@add-entry", "* to *", "@add-entry <any:+t?arget> to <descendant of $directories>", 'add_entry_cmd, #[[1, ['any_opt, ["t?arget"]]], [3, ['descendant, [$directories]]]]]]], ["@del-entry", [["@del-entry", "* from *", "@del-entry <any> from <descendant of $directories>", 'del_entry_cmd, #[[1, ['any, []]], [3, ['descendant, [$directories]]]]]]]];
var $root inited = 1;
var $root managed = [$httpd_ui];
var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"];

public method .list_entries_cmd() {
    arg cmd, cmdstr, prep, directory;
    var output, x;
    
    output = map x in (directory.entries()) to ($cml_lib.format_tr_tag($cml_lib.format_td_tag(x[1]), $cml_lib.format_td_tag(x[2])));
    return $ctext_frob.new_with([("Directory entries for " + directory) + ":", $cml_lib.format_table_tag("25%,75%", @output), $cml_lib.format_sep_tag()]);
};

public method .add_entry_cmd() {
    arg cmd, cmdstr, @args;
    var name, opt, prep, directory, target;
    
    [[[name], [opt]], prep, directory] = args;
    if ((opt.length()) != 4)
        return "You must specify the target object via +target.";
    target = opt[4];
    if (!(target = (| $object_lib.to_dbref(target) |)))
        return "The target must be a valid object.";
    if (!(target.is($page)))
        return "The target must be a descendant of $page.";
    directory.add_entry(name, target);
    return;
};

public method .del_entry_cmd() {
    arg cmd, cmdstr, @args;
    var name, prep, directory;
    
    [name, prep, directory] = args;
    catch ~keynf {
        directory.del_entry(name);
        sender().tell(((("Entry, '" + name) + "', removed from ") + directory) + ".");
    } with {
        sender().tell(((("Entry, '" + name) + "', was not an entry on ") + directory) + ".");
    }
    return;
};


new obj
Inserting help_obj_float.cdc...

new object $help_obj_float: $help_obj;

var $root manager = $help_obj_float;
var $help_node index = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 910069163;
var $dmi_data descriptions = #[];
var $has_name name = ['prop, "Float", "Float"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["ind", "8"]], [<$format, ["dt", [], [".", <$format, ["method", [["float.ceiling", 1]], ["ceiling"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method calculates the ceiling of the floating point value. The ceiling is the next largest integer, so the ceiling of 5.4 is 6.0."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.floor", 1]], ["floor"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method calculates the floor of the floating point value ", <$format, ["var", [], ["float"], 'do_var]>, ". The floor is the next smallest integer, so the floor of 5.4 is 5.0."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.round", 1]], ["round"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the rounded off value of ", <$format, ["var", [], ["float"], 'do_var]>, " to the nearest integral value."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.round_to", 1]], ["round_to"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ", ", <$format, ["var", [], ["places"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method rounds the value ", <$format, ["var", [], ["float"], 'do_var]>, " off to the given number of places as specified by the argument ", <$format, ["var", [], ["places"], 'do_var]>, "."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.fractional_part", 1]], ["fractional_part"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the fractional part of a floating point value. The result for 1.234 would be 0.234. The value will always be positive."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.to_integer", 1]], ["to_integer"], 'do_method]>, "(", <$format, ["var", [], ["float"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["This method returns the integral value of a floating point number."], 'do_dd]>, <$format, ["dt", [], [".", <$format, ["method", [["float.log", 1]], ["log"], 'do_method]>, "(", <$format, ["var", [], ["base"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, ")"], 'do_dt]>, <$format, ["dd", [], ["Given a base, ", <$format, ["var", [], ["base"], 'do_var]>, ", and a value, ", <$format, ["var", [], ["value"], 'do_var]>, ", this method returns the log of the value in the given base."], 'do_dd]>], 'do_dl]>], #[]]>;
var $root inited = 1;
var $root managed = [$help_obj_float];


new obj
Inserting float.cdc...

new object $float: $libraries;

var $root manager = $float;
var $float powers_of_ten = [10.0, 100.0, 1000.0, 10000.0, 100000.0, 1e+06];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 909982362;
var $dmi_data descriptions = #[];
var $root inited = 1;
var $root help_node = $help_obj_float;
var $root managed = [$float];

public method .floor() {
    arg float;
    
    return tofloat(toint(float));
};

public method .ceiling() {
    arg float;
    
    return tofloat(toint(float) + 1);
};

public method .round() {
    arg float;
    
    return round(float);
};

public method .round_to() {
    arg float, places;
    var place_value;
    
    if ((places < 1) || (places > 6))
        throw(~range, "Second argument must between 1 and 6.");
    place_value = powers_of_ten[places];
    return round(float * place_value) / place_value;
};

public method .to_integer() {
    arg float;
    
    return toint(float);
};

public method .log() {
    arg base, value;
    
    return log(value) / log(base);
};

public method .fractional_part() {
    arg float;
    
    return abs(float - toint(float));
};


new obj
Inserting systrust_group.cdc...

new object $systrust_group: $core_group;

var $root manager = $systrust_group;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 913800511;
var $group group = #[[$scheduler, 1], [$directories, 1]];
var $root inited = 1;
var $root managed = [$systrust_group];


maintenance

public method $root.__upgrade_handle_var() {
  arg handle, vref, old, current, new;

  if (current != old) {
      // if (handle == 1) {
          if (type(old) != type(current)) {
              dblog("ERROR: datatype inconsistency for " + vref +
                    " " + type(old) + " != " + type(current));
          }
          switch (type(current)) {
              case 'dictionary:
                  return dict_union(new, current);
              case 'list:
                  return union(new, current);
              default:
                  return new;
          }
      // }
  }
  return new;
};
update objvar
Updating objvar $root<$root>,managed

object $root;
var $root managed = [];
old method
Deleting normal method $root.new_descendants()

object $root;
eval {
  del_method('new_descendants);
};
method flags
Changing method $root.list_method() flags from  to nooverride 

object $root;
eval {
  var l;

  dblog("set_method_flags('list_method, 'public");
  catch any {
      set_method_flags('list_method, ['nooverride ]);
  } with {
      for l in ($parse_lib.traceback(traceback()))
          dblog(l);
  }
};
new method
Replacing public method $root.trusts(): nooverride 

public method $root.trusts(): nooverride  {
    arg obj;
    var o;
    
    for o in (.trusted()) {
        if (o.has_ancestor($group)) {
            if (o.includes(obj))
                return 1;
        } else if (o == obj) {
            return 1;
        }
    }
    return ($systrust_group.includes(obj)) || ($sys.is_system(obj));
};
new method
Replacing public method $root.del_var(): nooverride 

public method $root.del_var(): nooverride  {
    arg name;
    var n, obj, errs;
    
    (caller() == definer()) || (> .perms(sender()) <);
    (> $sys.touch() <);
    
    // try and clear the variable on all of the descendants, before 
    // deleting the variable...since we are root, dont use the standard  
    // hooks as perms may not be right
    n = tosym("_dclear_var_" + tostr(time()));
    catch any {
        add_method([("clear_var('" + name) + ");"], n);
        for obj in (.descendants()) {
            (| obj.(n)() |);
            pause();
        }
    }
    (| del_method(n) |);
    
    // now delete the variable
    (> del_var(name) <);
    if ('core in (.flags()))
        $changelog.log((((("DEL-VAR: " + this()) + ",") + name) + " by ") + sender());
};
new method
Replacing public method $root.ancestry(): nooverride 

public method $root.ancestry(): nooverride  {
    arg gen;
    var i, out;
    
    out = [];
    if (type(gen) == 'objnum) {
        for i in (.ancestors()) {
            if (i.has_ancestor(gen))
                out += [i];
        }
        return out;
    }
    if (gen != 0) {
        for i in (.parents())
            out = union(out, i.ancestry(gen - 1));
    }
    return out;
};
new method
Replacing public method $root.initialize(): nooverride 

public method $root.initialize(): nooverride  {
    var ancestors, pos, len, method, a, def, str, tb;
    
    // called by $sys.create() to create a new object.
    if ((caller() != $sys) && (sender() != this()))
        throw(~perm, "Caller is not $sys and sender is not this.");
    if (inited)
        throw(~perm, "Already initialized.");
    ancestors = ancestors().reverse();
    for a in (ancestors) {
        refresh();
        if (!(method = (| tosym("init_" + tostr(a.objname())) |)))
            continue;
        if ((def = (| find_method(method) |))) {
            if (def != a) {
                (| (def.manager()).tell(((("Initialization method for " + a) + " in wrong place (") + find_method(method)) + ")") |);
            } else {
                catch any {
                    .(method)();
                } with {
                    // try and let somebody know they made a boo-boo somewhere
                    str = ((("UNINIT ERROR " + this()) + "<") + def) + ">:";
                    tb = traceback().fmt_tb();
                    if (def) {
                        (| (def.manager()).tell(str) |);
                        (| (def.manager()).tell(tb) |);
                    }
                    if ((.manager()) != sender()) {
                        (| sender().tell(str) |);
                        (| sender().tell(tb) |);
                    }
                    (| sender().tell("Continuing init..") |);
                    (| $sys.log_traceback(tb, "** " + str) |);
                }
            }
        }
    }
    inited = 1;
};
new method
Adding root method $root.pass_test()

root method $root.pass_test() {
    return "YYYYYYY";
};
new method
Replacing public method $root.debug()

public method $root.debug() {
    arg @stuff;
    var x, line, mngr, meth, stack, out, ref;
    
    stack = stack();
    meth = (| (((stack[2])[3]) + "() line ") + ((stack[2])[4]) |);
    
    // dont even bother
    mngr = .manager();
    if (!(| mngr.find_method('tell) |))
        return;
    if (sender() != caller())
        ref = ((sender() + "<") + caller()) + ">";
    else
        ref = sender();
    if (meth)
        line = ((("DEBUG " + ref) + ".") + meth) + ":";
    else
        line = ("DEBUG " + ref) + ":";
    mngr.tell(line);
    for x in (stuff) {
        refresh();
        mngr.tell(($data_lib.unparse_indent(x)).prefix("DEBUG    "));
    }
};
new method
Replacing public method $root.is_writable_by(): nooverride 

public method $root.is_writable_by(): nooverride  {
    arg obj;
    var o;
    
    for o in (.writers()) {
        if (o.has_ancestor($group)) {
            if (o.includes(obj))
                return 1;
        } else if (o == obj) {
            return 1;
        }
    }
    return $sys.is_system(obj);
    
    // return (| obj in .writers() |) || $sys.is_system(obj);
};
new method
Replacing public method $root.generations(): nooverride 

public method $root.generations(): nooverride  {
    arg gen;
    var p, out;
    
    out = [this()];
    if (gen != 0) {
        for p in (.parents())
            out = union(out, p.generations(gen - 1));
    }
    return out;
};
new method
Replacing root method $root.change_parents(): nooverride 

root method $root.change_parents(): nooverride  {
    arg parents;
    var old_a, old_p, a, obj, new_a, definer, branch, method, str;
    
    if (!parents)
        throw(~noparents, "Objects must have at least 1 parent");
    
    // remember a few things
    old_a = setremove(ancestors(), this());
    old_p = .parents();
    branch = (.descendants()) + [this()];
    
    // build the new ancestors list by hand, so we can figure out what is
    // changing, and uninitialize those ancestors that are going away
    new_a = [];
    for obj in (parents)
        new_a = union(new_a, obj.ancestors());
    
    // uninit any ancestors going away
    for a in (old_a.set_difference(new_a)) {
        // call this ancestor's uninit on the obj and all its children
        method = tosym("uninit_" + (a.objname()));
        if ((definer = (| find_method(method) |))) {
            if (definer != a) {
                // scream madly and run around--everybody should know this
                str = "UNINIT ERROR: uninit method for " + a;
                str += (" in wrong place (" + definer) + ")";
                (| (definer.manager()).tell(str) |);
                (| (a.manager()).tell(str) |);
                (| sender().tell(str) |);
                continue;
            }
    
            // call the uninit method on this object only
            catch any {
                .(method)();
            } with {
                // try and let somebody know they made a boo-boo somewhere
                str = ((("UNINIT ERROR " + obj) + "<") + this()) + ">:";
                (| (.manager()).tell(str) |);
                (| (.manager()).tell_traceback(traceback()) |);
                (| sender().tell(str) |);
                (| sender().tell_traceback(traceback()) |);
                (| sender().tell("Continuing chparent..") |);
            }
        }
    
        // cleanup any old obj vars left lying around
        // if (branch)
        //     $sys.clear_definer_vars(a, branch);
        $sys.clear_definer_vars(a, [this()]);
        refresh();
    }
    
    // make the change
    (> chparents(parents) <);
    if ('core in (.flags()))
        $changelog.log(((((("CHANGE-PARENTS: " + this()) + " from ") + old_p) + " to ") + parents()) + " by ");
    new_a = setremove(ancestors(), this());
    
    // init anybody new to the family
    for a in (new_a.set_difference(old_a)) {
        method = tosym("init_" + (a.objname()));
        if ((definer = (| find_method(method) |))) {
            if (definer != a) {
                // scream madly and run around--everybody should know this
                // (damn inlaws, can't ever get things right)
                str = "INIT ERROR: uninit method for " + a;
                str += (" in wrong place (" + definer) + ")";
                (| (definer.manager()).tell(str) |);
                (| (a.manager()).tell(str) |);
                (| sender().tell(str) |);
                continue;
            }
    
            // introduce the new ancestor
            catch any {
                .(method)();
            } with {
                // try and let somebody know they made a boo-boo somewhere
                str = ((("INIT ERROR " + obj) + "<") + this()) + ">:";
                (| (.manager()).tell(str) |);
                (| (.manager()).tell_traceback(traceback()) |);
                (| sender().tell(str) |);
                (| sender().tell_traceback(traceback()) |);
                (| sender().tell("Continuing chparent..") |);
            }
        }
        refresh();
    }
};
update objvar
Updating objvar $sys<$sys>,core_version

object $sys;
var $sys core_version = "3.0.1999-08-28";
old method
Deleting normal method $sys.backup()

object $sys;
eval {
  del_method('backup);
};
new method
Replacing public method $sys.touch()

public method $sys.touch() {
    arg @nocorelock;
    
    if ((!nocorelock) && ((sender().has_flag('core)) && (!writable_core)))
        throw(~perm, sender() + " is a core object, and the core isn't writable. '@set $sys:writable-core = yes' to allow this.");
    touched = time();
};
new method
Replacing public method $sys.configure_core()

public method $sys.configure_core() {
    var list, l, x, t, err, s;
    
    if (caller() != $admin)
        (> .perms(sender()) <);
    s = sender();
    
    // if there is nothing left to config, leave..
    if (configured) {
        if (!(list = config_set.set_difference(configured.keys())))
            return;
    } else {
        configured = #[];
    }
    .add_to_system(s);
    
    // wait for other things to finish printing messages to them
    pause();
    pause();
    
    // expand on this as we go
    s.tell(["*" * 78, strfmt("%78{*}c", " Welcome to ColdCore "), "*" * 78]);
    s.tell(("This is an interactive configuration system which any admin who connects (until it is completed) is sent through.  You must complete this configuration before you can do anything else.  You can skip a specific question at any time by typing '@skip'.  Suggested default values will be enclosed in square brackets.  Pressing enter without any value will use the default value.".wrap_lines(78)).mmap('center, 78));
    s.tell("*" * 78);
    
    // first question please
    if (!(configured.contains('new_user_class))) {
        s.tell("What class should new users be created as?  Available classes:");
        list = filter x in ($user.descendants()) where (('general_cache in (x.flags())) && (x != $guest));
        t = .get_new_user_class();
        list = map x in (list) to ((list == t) ? (x + " (current class)") : x);
        s.tell(list.prefix("    "));
        while (!l) {
            refresh();
            l = (> s.prompt(("New User Class [" + t) + "] ") <);
            if (l == "@skip") {
                s.tell("Skipping..");
                break;
            }
            if (l) {
                catch any {
                    l = $object_lib.to_dbref(l);
                    if (!(l in list))
                        s.tell("Invalid selection, try again.");
                } with {
                    s.tell(("Invalid selection '" + l) + "'");
                    continue;
                }
            } else {
                l = t;
            }
            .set_setting("new-user-class", $sys, l);
            configured = configured.add('new_user_class, 1);
            s.tell("New User Class set to: " + l);
        }
        s.tell(["", "You can set this at any time, with the command:"]);
        s.tell("  @set $sys:new-user-class=" + l);
    }
    refresh();
    
    // server name/title
    if (!(configured.contains('server_name))) {
        s.tell(["", "---"]);
        t = $motd.server_name();
        l = (> s.prompt(("What is your server name? [" + t) + "] ") <) || t;
        if (l == "@skip") {
            s.tell("Skipping..");
        } else {
            $motd.set_setting("server-name", $motd, l);
            configured = configured.add('server_name, 1);
            s.tell("Server name set to: " + l);
        }
        s.tell(["", "You can set this at any time, with the command:"]);
        s.tell("  @set $motd:server-name=" + l);
    }
    refresh();
    if (!(configured.contains('server_title))) {
        s.tell(["", "---"]);
        t = $motd.server_title();
        l = (> s.prompt(("What is your server title? [" + t) + "] ") <) || t;
        if (l == "@skip") {
            s.tell("Skipping..");
        } else {
            $motd.set_setting("server-title", $motd, l);
            configured = configured.add('server_title, 1);
            s.tell("Server title set to: " + l);
        }
        s.tell(["", "You can set this at any time, with the command:"]);
        s.tell("  @set $motd:server-title=" + l);
    }
    refresh();
    if (!(configured.contains('daemons))) {
        s.tell(["", "---"]);
        while (1) {
            refresh();
            list = ($daemon.children()).setremove($login_daemon);
            s.tell("Which network daemons do you want to have automatically startup,");
            s.tell("Other than $login_daemon.  Available daemons:");
            t = filter l in (startup['objects]) where (l.is($daemon));
            for l in (list) {
                if (l in t)
                    s.tell(strfmt("  %20s (auto starting)", l));
                else
                    s.tell("  " + l);
            }
            l = (> s.prompt(("Auto-Start: [" + (t.join(", "))) + "] ") <);
            if (l == "@skip") {
                s.tell("Skipping..");
                break;
            } else if (!l) {
                s.tell("Using existing daemons: " + (t.join(", ")));
                configured = configured.add('daemons, 1);
                break;
            } else {
                err = 0;
                for x in (l.explode_english_list()) {
                    catch any {
                        .set_setting("startup-objects", $sys, "+" + x);
                        s.tell(("Added " + x) + " as a startup daemon.");
                    } with {
                        s.tell(("Unable to add '" + x) + "' as a daemon:");
                        s.tell("=> " + ((traceback()[1])[2]));
                        err++;
                    }
                }
                if (!err) {
                    configured = configured.add('daemons, 1);
                    break;
                }
                s.tell("Errors occurred...");
            }
        }
        s.tell(["", "You can set this at any time, with the command:"]);
        s.tell("  @set $motd:startup-objects=OBJECTS...");
    }
    
    // Other things to add: HTTP Virtual Hosting info,
    // Let them know, if they actually saw anything..
    s.tell(["", strfmt("%79{*}c", " Configuration Complete ")]);
};
new method
Replacing public method $sys.del_from_system()

public method $sys.del_from_system() {
    arg obj;
    
    if (!(.is_admin(sender())))
        throw(~perm, "Sender is not an admin.");
    if (!((obj in admins) || (obj in agents)))
        throw(~perm, "Object is not an agent or admin.");
    system = setremove(system, obj);
};
new method
Replacing public method $sys.add_to_system()

public method $sys.add_to_system() {
    arg obj;
    
    if (!(.is_admin(sender())))
        throw(~perm, "Sender is not an admin.");
    if (!((obj in admins) || (obj in agents)))
        throw(~perm, "Object is not an agent or admin.");
    system = setadd(system, obj);
};
new method
Replacing driver method $sys.startup()

driver method $sys.startup() {
    arg args;
    var opt, str, obj, f, ver, firsttime, doinit;
    
    set_heartbeat(0);
    
    // clean db?
    if ("-clean" in args) {
        catch any {
            dblog("** Cleaning Database..");
            (> .clean_database() <);
            dblog("** Done.");
            if (dict_contains(startup, 'time))
                startup = dict_del(startup, 'time);
        } with {
            .log($parse_lib.traceback(traceback()));
        }
        doinit = "-init" in args;
    } else {
        doinit = ("-init" in args) || (!dict_contains(startup, 'time));
    }
    
    // init?
    if (doinit) {
        catch any {
            dblog("** Initializing Database..");
            (> .init_database() <);
            dblog("** Done.");
        } with {
            .log($parse_lib.traceback(traceback()));
        }
    }
    
    // done?
    if ("-quit" in args) {
        dblog("** Shutting down.");
        .shutdown();
        return;
    }
    
    // make core?
    if ((opt = find opt in (args) where (opt.match_begin("-makecore=")))) {
        ver = regexp(args[opt], "-MAKECORE=(.*)$")[1];
        dblog(("** Calling .make_core(\"" + ver) + "\")..");
        .make_core(ver);
        return;
    }
    
    // Standard startup..
    startup = startup.add('time, time());
    backup = backup.add('next, time() + (backup['interval]));
    
    // In case we're recovering from a backup
    if (dict_contains(backup, 'started))
        backup = dict_del(backup, 'started);
    catch any {
        // get back the heartbeat
        set_heartbeat(startup['heartbeat_interval]);
    
        // Bind functions for security
        for f in (bindings) {
            catch any
                bind_function(@f);
            with
                dblog((("** Unable to bind function " + (f[1])) + "() to ") + (f[2]));
        }
    
        // tell objects who should know, that we are online
        if (type(args) != 'list)
            args = [];
        for obj in (startup['objects]) {
            .log(("Calling " + obj) + ".startup()");
            catch any
                (> obj.startup(@args) <);
            with
                .log($parse_lib.traceback(traceback()));
        }
    } with {
        .log(("** Startup ERROR at " + ctime()) + ":");
        .log(toliteral(traceback()));
        .log($parse_lib.traceback(traceback(), -1, ""));
    }
};
new method
Replacing private method $sys.create()

private method $sys.create() {
    arg parents, name, manager;
    var new;
    
    new = create(parents);
    catch any {
        new.initialize();
    
        // niggle the names around... $has_name may have initted the wrong name
        new.set_objname(name);
        if ((new.has_ancestor($has_name)) && ((new.name()) == ("#" + (new.objnum())))) {
            catch ~invname
                new.set_name(substr(tostr(new), 2));
        }
    
        // let it manage itself
        new.change_manager(manager);
    } with {
        // Failed to initialize the child; destroy it.
        $sys.log_traceback(traceback(), ((((("CREATE (" + parents) + ", '") + name) + ", ") + manager) + ")");
        (| new.destroy() |);
        rethrow(error());
    }
    return new;
};
new method
Replacing private method $sys.clean_database()

private method $sys.clean_database() {
    var obj, p, c, cmd;
    
    // cleanup some of $root's messiness
    for obj in ($root.descendants()) {
        (| obj.clean_root() |);
        refresh();
    }
    
    // purge all command caches
    for obj in ($command_cache.descendants()) {
        (| obj.purge_cache() |);
        refresh();
    }
    
    // check user info (move'em home etc)
    for obj in ($user.descendants()) {
        if ((| (obj.home()) != (obj.location()) |))
            (| obj.move_to(obj.home()) |);
        refresh();
    }
    
    // validate all locations and location content's
    for obj in ($physical.descendants()) {
        (| obj.validate_contents() |);
        if (obj.has_ancestor($located)) {
            if ((!valid(obj.location())) || (!(obj in ((obj.location()).contents()))))
                (| obj.move_to((| obj.home() |) || $lost_and_found) |);
        }
        refresh();
    }
};
new method
Replacing public method $sys.server_info()

public method $sys.server_info() {
    arg what, @long;
    var tmp;
    
    switch (what) {
        case 'up_time:
            return time() - (startup['time]);
        case 'startup_time:
            return startup['time];
        case 'server_hostname:
            return $dns.hostname("");
        case 'server_ip:
            return $dns.ip("");
        case 'last_backup:
            return backup['last];
        case 'driver_version:
            tmp = .version();
            return (((((((long ? "Genesis " : "") + (tmp[1])) + ".") + (tmp[2])) + ".") + (tmp[3])) + "-") + ((listlen(tmp) == 3) ? "NEED TO UPGRADE" : (tmp[4]));
        case 'core_version:
            return (long ? "ColdCore " : "") + core_version;
        case 'version:
            tmp = .version();
            return ((((((((("Genesis/" + (tmp[1])) + ".") + (tmp[2])) + ".") + (tmp[3])) + "-") + (tmp[4])) + " ") + "ColdCore/") + core_version;
        default:
            throw(~unknown, "Unknown flag.");
    }
};
update objvar
Updating objvar $mutex<$root>,flags

object $mutex;
var $root flags = ['variables, 'methods, 'code, 'core, 'fertile];
add objvar
Adding objvar $dmi_data<$root>,credit

object $dmi_data;
var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"];
old method
Deleting normal method $dictionary.nunion()

object $dictionary;
eval {
  del_method('nunion);
};
new method
Adding public method $buffer.bufsub2()

public method $buffer.bufsub2() {
    arg buf, a, b;
    var i, la, lb, lt;
    
    if ((a == b) || ((buflen(a) > buflen(buf)) || ((!a) || (!buf))))
        return buf;
    la = buflen(a);
    lb = buflen(b);
    lt = buflen(buf) - la;
    i = 1;
    anticipate_assignment();
    while ((i < lt) && (i = bufidx(buf, a, i))) {
        buf = (subbuf(buf, 1, i - 1) + b) + subbuf(buf, i + la);
        i += lb;
    }
    return buf;
};
new method
Replacing public method $string.decode64()

public method $string.decode64() {
    arg enc_chars;
    var i, j, k, ints, out_buf, len, num, ob;
    
    i = 1;
    out_buf = `[];
    len = enc_chars.length();
    while (i < len) {
        refresh();
        ints = [0, 0, 0, 0];
        j = 1;
        while (j <= 4) {
            if (((enc_chars[i]) in base64str) || ((enc_chars[i]) == "=")) {
                for k in [1 .. 64] {
                    refresh();
                    if (strcmp(enc_chars[i], base64str[k]) == 0) {
                        ints = replace(ints, j, (k - 1) % 64);
                        break;
                    }
                }
                j++;
            }
            i++;
        }
        out_buf = out_buf + `[(((ints[1]).shleft(2)) % 256) + ((ints[2]).shright(4)), (((ints[2]).shleft(4)) % 256) + ((ints[3]).shright(2)), (((ints[3]).shleft(6)) % 256) + (ints[4])];
    }
    return buf_to_str(out_buf);
};
new method
Adding public method $string.index()

public method $string.index() {
    arg @args;
    
    return stridx(@args);
};
new method
Adding public method $string.equals()

public method $string.equals() {
    arg str1, str2;
    
    return str1 == str2;
};
new method
Replacing public method $object_lib.to_dbref()

public method $object_lib.to_dbref() {
    arg obj;
    var dbref;
    
    switch (type(obj)) {
        case 'string:
            if (!obj)
                throw(~invdbref, "Invalid object reference \"\".");
            if ((obj[1]) == "$") {
                obj = obj.subrange(2);
                dbref = (| lookup(tosym(obj)) |);
            } else if ((obj[1]) == "#") {
                obj = substr(obj, 2);
                if (obj.is_numeric())
                    dbref = (| toobjnum(toint(obj)) |);
                else
                    throw(~objnf, ("Cannot find object \"#" + obj) + "\".");
            } else {
                dbref = toint(obj[1]);
                if (dbref || (obj == "0"))
                    dbref = toobjnum(dbref);
                else
                    dbref = (| lookup(obj) |);
            }
            if (!dbref) {
                dbref = (obj.replace(" ", "_")).lowercase();
                catch ~symbol
                    dbref = tosym(dbref);
                with
                    throw(~symbol, ("Object reference '" + dbref) + "' is invalid.");
                dbref = (> lookup(dbref) <);
            }
            return dbref;
        case 'objnum:
            return obj;
        default:
            return (> lookup(obj) <);
    }
};
new method
Replacing public method $parse_lib.filter_ctext()

public method $parse_lib.filter_ctext() {
    arg what, @defaults;
    var dic, output, prop, eff, ctext;
    
    dic = #[['receiver, sender()], ['time, 'post], ['formatter, $plain_format]];
    if (defaults && (type(defaults[1]) == 'dictionary))
        dic = dict_union(dic, defaults[1]);
    switch (class(what)) {
        case $ctext_frob:
            output = (what.set_vars(dic)).format();
        case $message_frob:
            output = what.format(dic);
        case $filtered_frob:
            if ((prop = (| sender().default_propagator() |)))
                what = what.propagate(prop);
            if (!what) {
                output = `[];
            } else {
                ctext = (what.message()).to_ctext(dic);
                for eff in (what.effects()) {
                    if (type(eff) == 'string)
                        ctext = ($ctext_frob.new_with([eff + " "], ctext.vars())).append(ctext);
                    else
                        ctext = $propagator_effects.(eff[1])(ctext, dic, eff.subrange(2));
                }
                ctext = ctext.set_vars(what.sensory());
                output = ctext.format();
            }
        default:
            output = what;
    }
    return output;
};
update objvar
Updating objvar $code_lib<$root>,flags

object $code_lib;
var $root flags = ['methods, 'variables, 'core, 'code];
new method
Adding public method $mail_lib.generate_unique_id()

public method $mail_lib.generate_unique_id() {
    arg message;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> message.perms(sender()) <);
    return crypt(toliteral([message.time(), message.from(), message.recipients(), message.subject(), message.body()]), "POP3").subrange(9);
};
new method
Replacing public method $foundation.all_edit_types(): nooverride 

public method $foundation.all_edit_types(): nooverride  {
    var i, l, t;
    
    l = [];
    for i in (.ancestors()) {
        if (type((| (t = i.get_edit_types()) |)) == 'list)
            l = union(l, i.get_edit_types());
    }
    return l;
};
new method
Replacing public method $has_commands.get_command_info()

public method $has_commands.get_command_info() {
    arg type, cmd;
    var info, a, ainfo;
    
    info = [];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((ainfo = (| a.command_info(type, cmd) |)))
            info = union(info, ainfo);
    }
    return info;
};
new method
Replacing public method $has_commands.add_command()

public method $has_commands.add_command() {
    arg template, method, @type;
    var cmd, types, count, x;
    
    (> .perms(sender()) <);
    [(type ?= 'local)] = type;
    if ("*" in template)
        throw(~invcmd, "Invalid command, command templates cannot contain \"*\"!.");
    cmd = (> $command_lib.validate_command_template(template) <);
    if (!(type in ['local, 'remote]))
        throw(~type, "Command types can be either 'local or 'remote");
    if ('this in (((cmd[2]).values()).slice(1)))
        type = 'remote;
    if (type == 'remote) {
        for x in (((cmd[2]).values()).slice(1)) {
            if (x == 'this)
                count++;
        }
        if (!count)
            throw(~add_command, "Command type defined as remote with no <this> argument.");
        else if (count > 1)
            throw(~add_command, "More than one <this> argument specified in template.");
    }
    if (!get_var(type))
        set_var(type, #[]);
    set_var(type, get_var(type).setadd_elem((cmd[1])[1], [@cmd[1], template, method, cmd[2]]));
    if (type == 'remote)
        $remote_cache.add_remote_command((cmd[1])[1], this());
    else if ((.command_modules()) || filter x in (parents()) where ('general_cache in (x.flags())))
        (| .cache_client_init() |);
};
new method
Replacing public method $has_name.match_name()

public method $has_name.match_name() {
    arg str;
    var m, t;
    
    if (!str)
        return 0;
    if ((m = match_begin(name[2], str)))
        return m;
    for t in (templates || []) {
        if ((m = match_template(str, t)))
            return m;
    }
    return 0;
};
new method
Replacing public method $has_name.init_has_name()

public method $has_name.init_has_name() {
    var objname;
    
    objname = tostr(this());
    if ((objname[1]) == "$")
        objname = substr(objname, 2);
    name = ['prop, objname, objname];
};
new method
Replacing public method $described._edit_prose_callback()

public method $described._edit_prose_callback() {
    arg text, client_data;
    
    (> .perms(caller(), $editor_reference) <);
    catch ~parse
        .set_prose(text);
    with
        return ['failure, ["Error: " + ((traceback()[1])[2])]];
    return ['success, ["Description set."]];
};
new method
Replacing public method $described.get_description(): nooverride 

public method $described.get_description(): nooverride  {
    arg @dflags;
    var flags, f;
    
    flags = #[['prose, 1], ['actor, sender()]];
    if (dflags && (type(dflags[1]) == 'dictionary))
        flags = dict_union(flags, dflags[1]);
    return .description(flags);
};
new method
Replacing public method $described.set_prose()

public method $described.set_prose() {
    arg new;
    
    (> .perms(sender()) <);
    if (new != 0) {
        switch (type(new)) {
            case 'string, 'list:
                new = (> $compiler.compile_cml(new) <);
            case 'frob:
                // we'll let this pass by unharmed -- potentially dangerous
            default:
                throw(~invalid, "Prose can be submitted as CML or Ctext");
        }
    }
    prose = new;
};
add objvar
Adding objvar $event_handler<$root>,help_node

object $event_handler;
var $root help_node = $help_sys_events;
new method
Replacing public method $event_handler.deregister_event()

public method $event_handler.deregister_event() {
    arg event, update_on;
    var value, event, src, status;
    
    (> .perms(sender()) <);
    if ((events.contains(update_on)) && ((events[update_on]).contains(event))) {
        // clean it up first.. (ignore status)
        [status, src] = (events[update_on])[event];
        switch (src) {
            case 'location:
                (| loc.unhook_from_event(event) |);
            case 'this:
                (| .unhook_from_event(event) |);
            default:
                (| src.hook_into_event(event) |);
        }
    
        // now cleanup 'events'
        value = (events[update_on]).del(event);
        if (value)
            events = events.add(update_on, value);
        else
            events = events.del(update_on);
        if (!events)
            clear_var('events);
    }
};
add objvar
Adding objvar $scheduler<$root>,credit

object $scheduler;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
new method
Replacing public method $compiler._make_tag()

public method $compiler._make_tag() {
    arg token, mode, vars, name, flags, args;
    var method, class;
    
    if (mode == 'fmtname) {
        if (token != "}")
            throw(~parse, "Extra ']' encountered.");
        method = tosym("do_" + (name.strip()));
        class = $format;
    }
    if (mode == 'genname) {
        if (token != "]")
            throw(~parse, "Extra '}' encountered.");
        method = tosym("gen_" + (name.strip()));
        class = $generator;
    }
    catch ~methodnf
        return (> .(method)(vars, flags, args) <);
    with
        return (> [class.new_tag(name, flags, args), vars] <);
};
new method
Adding public method $compiler.do_web()

public method $compiler.do_web() {
    arg vars, flags, args;
    
    if (!(flags.contains("src")))
        throw(~parse, "no 'src' flag for {web}");
    if (!(flags.contains("name")))
        throw(~parse, "no 'name' flag for {web}");
    return [$format.new_tag("web", flags, args), vars];
};
new method
Adding public method $compiler.gen_random()

public method $compiler.gen_random() {
    arg vars, flags, args;
    
    if (!(flags.contains("high")))
        throw(~parse, "no high flag for [random]");
    return [$generator.new_tag("random", flags, args), vars];
};
new method
Replacing public method $compiler.do_table()

public method $compiler.do_table() {
    arg vars, flags, args;
    
    if (!(flags.contains("cols")))
        throw(~parse, "no 'cols' flag for {table}.");
    return [$format.new_tag("table", flags, ._kill_spaces(args)), vars];
};
new method
Replacing public method $compiler.parse_string_new()

public method $compiler.parse_string_new() {
    arg vars, tokens;
    var mode, out, word, token, i, tmp, ret;
    
    if (!tokens)
        return [[], vars];
    mode = ['spaces, 'plain];
    i = 1;
    out = [];
    word = "";
    while (i <= (tokens.length())) {
        refresh();
        token = tokens[i++];
        switch (mode[1]) {
            case 'spaces:
                if (token != " ") {
                    i--;
                    mode = mode.subrange(2);
                }
            case 'plain:
                if (!(token in ["{", "["])) {
                    if (token == " ") {
                        // No scatter because .check can throw
                        if ((| (ret = ._check_glue(tokens, i)) |)) {
                            i = ret[1];
                            mode = [ret[2], @mode];
                            if (word)
                                out += [word];
                            word = "";
                            continue;
                        }
                    }
                    word += token.sed("\\\(.)", "%1", "g");
                } else {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, @mode];
                }
            case 'fmtname, 'genname:
                if (((mode[1]) == 'fmtname) && (token == "quote")) {
                    mode = mode.subrange(2);
                    out += [$format.new_tag("quote", [], [tokens[i++]])];
                    i++;
                } else {
                    if (token in glue_table)
                        mode = [mode[1], 'spaces, @mode.subrange(2)];
                    mode = ['spaces, 'flags, #[], token, @mode];
                }
            case 'flags:
                if (token in ["}", "]"]) {
                    ret = (> ._make_tag(token, mode[4], vars, mode[3], mode[2], []) <);
                    vars = ret[2];
                    out += [ret[1]];
                    mode = mode.subrange(5);
                } else if (token == "=") {
                    throw(~parse, "Value flag with no key.");
                } else if (token == ":") {
                    mode = ['spaces, 'args, out, mode[2], @mode.subrange(3)];
                    out = [];
                } else if ((| (tokens[i]) == "=" |)) {
                    mode = ['flagvalue, token, @mode];
                    i++;
                } else {
                    mode = mode.replace(2, (mode[2]).add(token, 1));
                }
            case 'flagvalue:
                if (token in ["}", "]", ":"]) {
                    mode = mode.subrange(3);
                    i--;
                } else if (token == " ") {
                    mode = mode.subrange(3);
                } else if (!(token in ["[", "{"])) {
                    mode = ['spaces, @(mode.subrange(3)).replace(2, (mode[4]).add(mode[2], token.sed("\\\(.)", "%1", "g")))];
                } else {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, 'flagset, @mode.subrange(2)];
                }
            case 'flagset:
                i--;
                mode = ['spaces, @(mode.subrange(3)).replace(2, (mode[4]).add(mode[2], out[out.length()]))];
                out = out.subrange(1, (out.length()) - 1);
            case 'args:
                if (token in ["}", "]"]) {
                    if (word) {
                        out += [word];
                        word = "";
                    }
                    ret = ._make_tag(token, mode[5], vars, mode[4], mode[3], out);
                    vars = ret[2];
                    out = (mode[2]) + [ret[1]];
                    mode = mode.subrange(6);
                } else if (token in ["{", "["]) {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, @mode];
                } else {
                    if (token == " ") {
                        if ((| (ret = ._check_glue(tokens, i)) |)) {
                            i = ret[1];
                            mode = [ret[2], @mode];
                            if (word)
                                out += [word];
                            word = "";
                            continue;
                        }
                    }
                    word += token.sed("\\\(.)", "%1", "g");
                }
        }
    }
    if (word)
        out += [word];
    while ((mode[1]) == 'spaces)
        mode = mode.subrange(2);
    if (mode != ['plain])
        throw(~parse, "Unclosed tag.");
    return [out, vars];
};
new method
Adding public method $bs_eval.gen_random()

public method $bs_eval.gen_random() {
    arg vars, flags, args;
    var range, low, high;
    
    // No need to ._eval_ctext() since there are no args.
    low = toint((| flags.getkey("low") |) || 1);
    high = toint(flags.getkey("high"));
    return [[random(high - low) + low], vars];
};
new method
Replacing public method $plain_format.do_table()

public method $plain_format.do_table() {
    arg vars, flags, args;
    var tblinfo, i, ntbinfo, info, width, l, lr, lc, inds, ind, cwidth;
    
    tblinfo = (| vars['table_info] |) || 0;
    width = vars['width];
    if (!(| (ntbinfo = flags.getkey("cols")) |))
        throw(~flags, "Need column information.");
    ind = (| abs(toint(flags.getkey("ind"))) |) || 0;
    info = [];
    cwidth = width - ind;
    if ("%" in ntbinfo) {
        for i in (ntbinfo.explode(","))
            info += [toint(cwidth * (toint(i) / 100.0))];
    } else {
        for i in (ntbinfo.explode(","))
            info += [toint(i)];
    }
    vars = dict_union(vars, #[['table_info, [info, 0]], ['rinfo, $list.make(info.length(), 0)], ['rcont, $list.make(info.length(), [])]]);
    [args, vars] = ._eval_ctext(args, vars);
    vars = tblinfo ? (vars.add('table_info, tblinfo)) : (vars.del('table_info));
    vars = vars.add('width, width);
    return ["\n" + args, vars];
};
new method
Replacing public method $ansi_format.weed_ansi()

public method $ansi_format.weed_ansi() {
    arg str;
    var out;
    
    out = str.global_regexp("[\]A[0-9A-LN-Za-ln-z;]+m");
    return out;
    return str.global_regexp("\\\A[0-9A-Ln-z;a-ln-z;]+[a-z]");
};
new method
Adding public method $html_format.do_input()

public method $html_format.do_input() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(("\n<input " + ((flags.mmap('join, "=")).join(" "))) + ">") + args, vars];
};
new method
Replacing public method $html_format.do_web()

public method $html_format.do_web() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [((((args + "<a href=\"") + (flags.getkey("src"))) + "\">") + (flags.getkey("name"))) + "</a>", vars];
};
new method
Adding public method $html_format.do_option()

public method $html_format.do_option() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(("\n<option " + ((flags.mmap('join, "=")).join(" "))) + ">") + args, vars];
};
new method
Replacing public method $html_format.do_td()

public method $html_format.do_td() {
    arg vars, flags, args;
    var f, n, c, width, align;
    
    c = vars['table_col];
    vars = vars.add('table_col, c + 1);
    width = (| (vars['table_cols])[c] |);
    f = " " + join(flags.mmap('join, "="), " ");
    if (!(| flags.getkey("valign") |))
        f += " valign=top";
    if (width)
        f += (" width=\"" + width) + "\"";
    [args, vars] = ._eval_ctext(args, vars);
    return [((("\n<td " + f) + ">") + args) + "</td>", vars];
};
new method
Replacing root method $world.core_world()

root method $world.core_world() {
    .set_setting("realms", $world, "$realm_of_creation");
    .set_setting("starting-place", $world, $the_pit);
};
update objvar
Updating objvar $motd<$motd>,connect_help

object $motd;
var $motd connect_help = ["Connection Help", "===============", "", "  Connecting as a guest:  'guest <name> <email>'", "                Example:  'guest John Doe johndoe@domain.com'", "", "   Connecting as a user:  'connect <name> <password>'", "                Example:  'connect John Doe mypassword'", "", " Quitting (this screen):  '@quit'   or   'quit'", "", "Connected Users Listing:  '@who'", "", "        Creating a user:  'create <name> <password> <email@host>'", "                Example:  'connect John Doe mypassword johndoe@domain.com'"];
update objvar
Updating objvar $motd<$motd>,notes

object $motd;
var $motd notes = ["", "Due to a disk failure we have reverted to an older copy of the db", "If you had a user but do not now, this is why.", "Sorry!", ""];
new method
Adding public method $located.eject(): nooverride 

public method $located.eject(): nooverride  {
    arg @args;
    var old, mover, place;
    
    [(place ?= $nowhere)] = args;
    if (!($sys.is_system(sender()))) {
        if (sender() == location)
            place = (.has_ancestor($body)) ? ($world.starting_place()) : $nowhere;
        else
            throw(~perm, ("Only system objects and " + (.name())) + "'s current location may call .eject()");
    }
    
    // Don't do anything if we're already here.
    if (place == location)
        return;
    if (!(place.has_ancestor($location)))
        throw(~type, (place.namef('ref)) + " is not a location.");
    if (place == this())
        throw(~move, "You cannot move something into itself.");
    if (!valid(location))
        location = $nowhere;
    mover = sender();
    
    // Set location.
    old = location;
    location = place;
    old.del_sender_from_contents();
    place.add_sender_to_contents();
    
    // Notify involved parties of completed move, in reverse order.
    place.did_arrive(mover, old);
    old.did_leave(mover, place);
    .did_move(mover, old);
};
new method
Replacing protected method $command_cache.cache_client_uninit()

protected method $command_cache.cache_client_uninit() {
    var p;
    
    if (sender() != this())
        (> .perms(sender()) <);
    if (.is($place)) {
        for p in (.contents()) {
            if (p.is($command_cache))
                return;
        }
    }
    for p in (([this()] + parents()) + modules)
        (| p.cache_server_uninit() |);
};
new method
Replacing public method $command_cache.cache_server_uninit()

public method $command_cache.cache_server_uninit() {
    var user;
    
    if (caller() != $command_cache)
        throw(~perm, "Caller is not of the command subsystem.");
    
    // see if anybody still needs us, otherwise purge
    if (.is_general_cache()) {
        for user in ($user_db.connected()) {
            if ((user.has_ancestor(this())) || (this() in (user.command_modules())))
                return;
        }
    }
    .purge_cache();
};
new method
Replacing public method $command_cache.match_command()

public method $command_cache.match_command() {
    arg str, cmd, args;
    var command, m, matched, templates, info, cdef, def, cmds, c, p;
    
    templates = (matched = []);
    cmds = #[];
    if (dict_contains(commands, cmd))
        cmds = #[[this(), commands[cmd]]];
    for def in (parents() + modules) {
        if ((c = def.command_cache()) && dict_contains(c, cmd))
            cmds = dict_add(cmds, def, c[cmd]);
    }
    if (!cmds)
        return 0;
    for def in (cmds) {
        if ((def[1]) in parents())
            p = this();
        else
            p = def[1];
        for command in (def[2]) {
            if (!(info = (command[2]).command_info('local, command[1])))
                continue;
            for cdef in (info) {
                if ((m = match_template(args, cdef[2])) != 0)
                    matched += [[listlen(m), [str, cmd, @m], p, @sublist(cdef, 3)]];
            }
            templates = union(templates, info.slice(3));
            refresh();
        }
    }
    if (matched) {
        info = [matched[1]];
        matched = delete(matched, 1);
        for m in (matched) {
            if ((m[1]) > ((info[1])[1]))
                info = [m];
            else if ((m[1]) == ((info[1])[1]))
                info += [m];
        }
        return ['command, info];
    }
    if (!templates)
        return 0;
    return ['partial, templates];
};
new method
Replacing public method $command_cache.cache_client_init()

public method $command_cache.cache_client_init() {
    var p;
    
    if (sender() != this())
        (> .perms(sender()) <);
    modules ?= [];
    for p in (([this()] + parents()) + modules)
        (| p.cache_server_init() |);
};
new method
Replacing public method $command_cache.match_remote_command()

public method $command_cache.match_remote_command() {
    arg str, cmd, args;
    var command, m, matched, templates, info, cdef, def, cmds, c;
    
    if (this() != $remote_cache)
        throw(~perm, "This should only be used on $remote_cache");
    templates = (matched = []);
    if (commands && dict_contains(commands, cmd))
        cmds = commands[cmd];
    else
        return 0;
    for command in (cmds) {
        if (!(info = (command[2]).command_info('remote, command[1])))
            continue;
        for cdef in (info) {
            if ((m = match_template(args, cdef[2])) != 0)
                matched += [[listlen(m), command[2], [str, cmd, @m], @sublist(cdef, 3)]];
        }
        templates = union(templates, info.slice(3));
        refresh();
    }
    if (matched)
        return ['remote, matched];
    if (!templates)
        return 0;
    return ['partial, templates];
};
add objvar
Adding objvar $remote_cache<$command_cache>,shortcuts

object $remote_cache;
var $command_cache shortcuts = 0;
clear objvar
Clearing objvar $user_interfaces<$command_cache>,shortcuts

object $user_interfaces;
old var $command_cache shortcuts;
clear objvar
Clearing objvar $user_interfaces<$command_cache>,commands

object $user_interfaces;
old var $command_cache commands;
new method
Replacing public method $mail_list.set_name()

public method $mail_list.set_name() {
    arg new_name, @args;
    var old_name;
    
    old_name = .name('noarticle);
    if (new_name && ((new_name[1]) == "*"))
        new_name = new_name.subrange(2);
    (> pass(new_name, @args) <);
    (| $mail_db.key_changed(old_name, new_name) |);
};
clear objvar
Clearing objvar $mail_ui<$command_cache>,shortcuts

object $mail_ui;
old var $command_cache shortcuts;
clear objvar
Clearing objvar $mail_ui<$command_cache>,commands

object $mail_ui;
old var $command_cache commands;
new method
Replacing protected method $mail_ui.unsubscribe_cmd()

protected method $mail_ui.unsubscribe_cmd() {
    arg cmdstr, cmd, str;
    var list, line, mname;
    
    (> .perms(caller(), 'command) <);
    if (!str)
        return .mail_lists_cmd();
    catch ~listnf, ~ambig {
        list = (> $mail_lib.match_mail_recipient(str) <);
    } with {
        if (error() == ~listnf)
            return (traceback()[1])[2];
        else
            return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
    }
    if (list == this())
        return "You cannot unsubscribe yourself.";
    mname = list.mail_name();
    if (!(list in (subscribed.keys())))
        return "You are not subscribed to " + mname;
    .unsubscribe(list);
    return ("Successfully unsubscribed from " + mname) + ".";
};
new method
Replacing protected method $mail_ui.parse_mail_recipient_list()

protected method $mail_ui.parse_mail_recipient_list() {
    arg str;
    var recip, lists;
    
    lists = [];
    for recip in (str.explode_english_list()) {
        catch ~listnf, ~ambig {
            recip = (> $mail_lib.match_mail_recipient(recip) <);
            if (recip.list_is_sendable_by(this()))
                lists += [recip];
            else
                .tell("You cannot send to " + (recip.mail_name()));
        } with {
            if (error() == ~listnf)
                .tell(("The recipient \"" + recip) + "\" is invalid.");
            else
                .tell(((("The list '" + recip) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".");
        }
    }
    return lists;
};
new method
Replacing protected method $mail_ui.next_new_cmd()

protected method $mail_ui.next_new_cmd() {
    arg cmdstr, cmd, str;
    var mail, list, keys, start;
    
    (> .perms(caller(), 'command) <);
    str = strsed(str, "^ *on +", "");
    if (str) {
        catch any {
            list = (> $mail_lib.match_mail_recipient(str) <);
        } with {
            if (error() == ~ambig)
                return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
            else
                return (traceback()[1])[2];
        }
        .new_list(list);
        mail = (| list.mail_list_next((subscribed[list])[2]) |);
        while (mail && (mail.has_read(this()))) {
            refresh();
            mail = (| list.mail_list_next(mail) |);
        }
        if (!mail)
            return ("No new mail on " + ($mail_lib.mail_name(list))) + ".";
        .read_mail(mail, list);
    } else {
        keys = dict_keys(subscribed);
        if (!keys)
            return "You are not subscribed to any lists.";
        if (!((current['list]) in keys))
            current = current.add('list, keys[1]);
        start = (list = current['list]);
        while (1) {
            // anything left on this list?
            mail = (| list.mail_list_next((subscribed[list])[2]) |);
            while (mail && (mail.has_read(this()))) {
                refresh();
                mail = (| list.mail_list_next(mail) |);
            }
            if (mail)
                break;
    
            // pick a new list
            catch any
                list = (> keys[(list in keys) + 1] <);
            with
                list = (| keys[1] |);
    
            // die?
            if ((!list) || (list == start))
                return "No new mail.";
        }
        .new_list(list);
        .read_mail(mail, list);
    }
};
new method
Replacing protected method $mail_ui.reply_cmd()

protected method $mail_ui.reply_cmd() {
    arg cmdstr, cmd, str;
    var list, msg, args, i, subj, text, recip;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "to *")))
        str = args[2];
    if ((args = match_template(str, "* on *")))
        [msg, str, list] = args;
    else
        msg = str;
    if (!list) {
        list = current['list];
    } else {
        catch ~listnf, ~perm, ~ambig {
            list = (> $mail_lib.match_mail_recipient(list) <);
            (> .new_list(list) <);
        } with {
            if (error() == ~ambig)
                return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
            else
                return (traceback()[1])[2];
        }
    }
    if (!msg) {
        if (!valid((msg = (| (subscribed[list])[2] |))))
            return "No current message to reply to.";
    } else {
        catch ~range
            msg = $mail_lib.range_to_actual($parse_lib.range(msg), current);
        with
            return (traceback()[1])[2];
        msg = msg[1];
    }
    i = msg in (list.mail());
    if (list.is($user))
        recip = msg.from();
    else
        recip = list;
    if (!(recip.is($mail_list)))
        return (list.namef('ref)) + " is not a valid mail recipient.";
    .tell(((("Replying to message " + i) + " on ") + (list.mail_name())) + ".");
    text = msg.body();
    if (text == ["", "(no message)", ""])
        text = [];
    text = $mail_lib.indent_reply(text);
    text = [((("On " + ($time.format("%d-%b-%Y", msg.time()))) + " ") + ((msg.from()).namef('ref))) + " said: "] + text;
    if (.active_editor()) {
        .tell("Storing active editor..");
        .store_editor();
    }
    subj = msg.subject();
    if (!(subj.match_begin("Re:")))
        subj = "Re: " + subj;
    (> .invoke_editor(this(), '_edit_mail_callback, text, ['mail, [recip], subj, i, msg]) <);
    if (.active_editor()) {
        .tell(("Editor invoked with " + ((.active_editor()).session_name())) + ".");
        .tell("Type 'help' for available commands.");
    }
};
new method
Replacing protected method $mail_ui.mail_remove_cmd()

protected method $mail_ui.mail_remove_cmd() {
    arg cmdstr, cmd, str;
    var mail, args, lmail, list, rng, m, x, name, lname, offset, ans;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* on|from *"))) {
        rng = args[1];
        list = args[3];
    } else if (!str) {
        return "You must specify a message and list.";
    } else {
        // grr, be hacky
        args = explode(str);
        if ((args.length()) > 1) {
            list = args.last();
            if (!(| $mail_lib.match_mail_recipient(list) |)) {
                rng = str;
                list = "";
            } else {
                rng = (args.delete(args.length())).join();
            }
        } else {
            rng = str;
            list = "";
        }
    }
    if (!rng)
        return ("You must specify a message to remove from " + lname) + ".";
    if (!list) {
        list = current['list];
        ans = (> .prompt(((("Remove mail " + rng) + " from ") + (list.mail_name())) + "?  ") <);
        if (match_regexp(ans, "no|n"))
            return "Ok, aborting..";
    } else {
        catch ~listnf, ~ambig {
            list = (> $mail_lib.match_mail_recipient(list) <);
        } with {
            if (error() == ~listnf)
                return (traceback()[1])[2];
            else
                return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
        }
    }
    lname = list.mail_name();
    catch any
        (> .new_list(list) <);
    with
        return (traceback()[1])[2];
    if (rng == "$") {
        mail = (> $mail_lib.range_to_actual(['end, 'single], current) <);
    } else if (rng && ((rng[1]) == "$")) {
        catch ~namenf
            mail = [(> $object_lib.to_dbref(rng) <)];
        with
            return (traceback()[1])[2];
    } else {
        catch ~range
            mail = (> $mail_lib.range_to_actual($parse_lib.range(rng), current) <);
        with
            return (traceback()[1])[2];
    }
    lmail = list.mail();
    if ((mail[1]) != (| lmail[1] |)) {
        offset = (mail[1]) in lmail;
        lmail = sublist(lmail, offset);
        offset--;
    }
    for m in (mail) {
        catch ~perm {
            x = (m in lmail) + offset;
            name = ((((("#" + x) + " \"") + (m.subject())) + "\" (") + m) + ")";
            list.del_mail(m);
            .tell(((("Removed message " + name) + " from ") + (list.mail_name())) + ".");
        } with {
            .tell((traceback()[1])[2]);
        }
    }
};
new method
Replacing protected method $mail_ui.mail_on_cmd()

protected method $mail_ui.mail_on_cmd() {
    arg cmdstr, cmd, str;
    var args, lmail, mail, rng, start, end, line, list, len, out, m, rows, o, from, subj;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* on *"))) {
        rng = args[1];
        list = args[3];
    } else if (match_template(str, "* to *")) {
        return "Please use the @send command instead.";
    } else {
        rng = "";
        list = str;
    }
    if (!list) {
        list = current['list];
    } else {
        catch ~listnf, ~perm, ~ambig {
            list = (> $mail_lib.match_mail_recipient(list) <);
            (> .new_list(list) <);
        } with {
            if (error() == ~ambig)
                return ((("The list '" + list) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
            else
                return (traceback()[1])[2];
        }
    }
    if (!rng) {
        mail = list.mail();
        end = mail.length();
    
        // minus two for the head and tail
        rows = (.get_rows()) - 2;
        if (end > rows) {
            start = end - rows;
            mail = sublist(mail, start);
        } else {
            start = 1;
        }
        rng = (start + "-") + end;
    } else {
        catch ~range
            mail = $mail_lib.range_to_actual($parse_lib.range(rng), current);
        with
            return (traceback()[1])[2];
    }
    if (!mail)
        return "No mail on " + (list.mail_name());
    len = (.linelen()) - 36;
    out = [((("Mail from " + rng) + " on ") + (list.mail_name())) + ":"];
    lmail = list.mail();
    o = [];
    for m in (mail) {
        if (!valid(m)) {
            list.notify_bad_mail(m);
        } else {
            from = $object_lib.get_name(m.from(), 'name);
            if ((args = regexp(from, "<([^>]+)>")))
                from = explode(args[1], "@")[1];
            subj = m.subject();
            subj = strsed(subj, "^\[[^]]+\] *", "");
            o += [$cml_lib.format_tr_tag($cml_lib.format_td_tag((m == (| (subscribed[list])[2] |)) ? "=>" : " "), $cml_lib.format_td_tag(m in lmail), $cml_lib.format_td_tag((m.has_read(this())) ? " " : "!"), $cml_lib.format_td_tag(subj), $cml_lib.format_td_tag(from), $cml_lib.format_td_tag(m.lines()), $cml_lib.format_td_tag($time.format("%d-%h-%Y", m.time())))];
        }
    }
    return $ctext_frob.new_with((out + [$cml_lib.format_table_tag("5%,5%,2%,50%,17%,5%,15%", o)]) + [$cml_lib.format_sep_tag()]);
};
new method
Replacing protected method $mail_ui.subscribe_cmd()

protected method $mail_ui.subscribe_cmd() {
    arg cmdstr, cmd, str;
    var list, mname, l, args, line, len, out;
    
    (> .perms(caller(), 'command) <);
    
    // this is ugly bad bad
    args = (> $parse_lib.opt(str, "n?ew") <);
    if (!(args[1])) {
        if ("n?ew" in ((args[2]).slice(1))) {
            out = [];
            for l in ((subscribed.keys()).setremove(this())) {
                if ((l.last_received_on()) > ((subscribed[l])[1]))
                    out += ["  " + (l.mail_name())];
            }
            if (out)
                .tell(["New mail on:"] + out);
            else
                .tell(["No new mail on the lists you are subscribed to."]);
            return;
        }
        .tell("Currently Subscribed Lists:");
        len = (.linelen()) / 3;
        for l in ((subscribed.keys()).setremove(this())) {
            if (!valid(l)) {
                subscribed = dict_del(subscribed, l);
            } else {
                line = "  " + (l.mail_name());
                if ((l.last_received_on()) > ((subscribed[l])[1]))
                    line += " (new mail)";
                .tell(line);
            }
        }
        .tell("---");
        return;
    }
    catch ~listnf, ~ambig {
        list = $mail_lib.match_mail_recipient(str);
    } with {
        if (error() == ~listnf)
            return (traceback()[1])[2];
        else
            return ((("The list '" + str) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
    }
    mname = $mail_lib.mail_name(list);
    if (list in (subscribed.keys()))
        return .tell(("You are already subscribed to " + mname) + ".");
    if (!(list.list_is_readable_by(this())))
        return .tell(mname + " is not subscribeable by you.");
    .subscribe(list);
    .tell(("Successfully subscribed to " + mname) + ".");
};
new method
Replacing protected method $mail_ui.mail_lists_cmd()

protected method $mail_ui.mail_lists_cmd() {
    arg @args;
    var l, output;
    
    if (caller() != $mail_ui)
        (> .perms(caller(), 'command) <);
    output = map l in (($mail_db.database()).values()) to ($cml_lib.format_tr_tag($cml_lib.format_td_tag(l.mail_name()), $cml_lib.format_td_tag(dict_contains(subscribed, l) ? "[subscribed]" : " "), $cml_lib.format_td_tag((l.list_is_sendable_by(this())) ? "[sendable]" : " "), $cml_lib.format_td_tag((l.list_is_readable_by(this())) ? "[readable]" : " ")));
    return $ctext_frob.new_with(["All Available Mail Lists:", $cml_lib.format_table_tag("53%,17%,15%,15%", @output), $cml_lib.format_sep_tag()]);
};
new method
Replacing protected method $mail_ui.mail_read_cmd()

protected method $mail_ui.mail_read_cmd() {
    arg cmdstr, cmd, str;
    var mail, m, args, opts, lname, list, rng, args, meta;
    
    (> .perms(caller(), 'command) <);
    [args, opts] = (> $parse_lib.opt(str, "m?eta") <);
    str = args.join(" ");
    meta = [];
    if ((m = "m?eta" in (opts.slice(1)))) {
        if ((opts[m])[3])
            meta = [1];
    }
    if ((args = match_template(str, "* on *"))) {
        rng = args[1];
        catch ~listnf, ~ambig {
            list = (> $mail_lib.match_mail_recipient(args[3]) <);
        } with {
            if (error() == ~listnf) {
                return (traceback()[1])[2];
            } else {
                // error == ~ambig
                return ((("The list '" + (args[3])) + "' could match ") + ((((traceback()[1])[3]).mmap('mail_name)).to_english("nothing", " or "))) + ".";
            }
        }
    } else {
        rng = str;
        list = current['list];
    }
    catch ~perm
        (> .new_list(list) <);
    with
        return (traceback()[1])[2];
    if (((list.mail()).length()) == 0)
        return ("There is no mail on " + (list.mail_name())) + ".";
    if (!rng)
        return ("You must specify a message to read on " + (list.mail_name())) + ".";
    catch ~range {
        if (rng == "next") {
            .read_mail((> list.mail_list_next((subscribed[list])[2]) <), list, @meta);
        } else if (rng == "prev") {
            .read_mail((> list.mail_list_prev((subscribed[list])[2]) <), list, @meta);
        } else {
            for m in ($mail_lib.range_to_actual($parse_lib.range(rng), current))
                .read_mail(m, list, @meta);
        }
    } with {
        return ((("Mail message " + rng) + " does not exist on ") + (list.mail_name())) + ".";
    }
};
new method
Replacing root method $location.uninit_location()

root method $location.uninit_location() {
    var obj;
    
    for obj in (contents)
        (| obj.eject() |);
};
new method
Replacing public method $location.add_sender_to_contents(): nooverride 

public method $location.add_sender_to_contents(): nooverride  {
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
    if ((sender().location()) != this())
        throw(~location, "Sorry, but you're not here.");
    contents = setadd(contents, sender());
};
add objvar
Adding objvar $body<$command_cache>,shortcuts

object $body;
var $command_cache shortcuts = 0;
add objvar
Adding objvar $body<$command_cache>,commands

object $body;
var $command_cache commands = 0;
new method
Replacing public method $body.pose_cmd()

public method $body.pose_cmd() {
    arg cmdstr, cmd, args;
    var shortwords, preword_punct_chars, postword_punct_chars, preword_punct_expr, postword_punct_expr, pronouns, ant_pronouns, selfmsg, othersmsg, recips, antecedent, prepunct, postpunct, word, oword, things, who, aliases, msg, cap, name, wname, m, w, quoted, msgdict, posessive, name_expr;
    
    (> .perms(caller(), $user, $body) <);
    args = explode("." + (args.trim()));
    if (args == ["."]) {
        (.location()).announce(.name());
        return;
    }
    
    // ------------
    shortwords = ["a", "an", "the", "to", "for", "out", "of", "on", "at", "and"];
    preword_punct_chars = "[\"'`([{]";
    postword_punct_chars = "[]})\"',.!?:;]";
    
    // ------------
    preword_punct_expr = ("^" + preword_punct_chars) + "+";
    postword_punct_expr = postword_punct_chars + "+$";
    pronouns = (.gender()).pronouns();
    ant_pronouns = $gender_neuter.pronouns();
    selfmsg = (othersmsg = (recips = (antecedent = [])));
    quoted = 0;
    for word in (args) {
        if ((m = match_regexp(word, preword_punct_expr))) {
            prepunct = substr(word, @m[1]);
            word = substr(word, ((m[1])[2]) + 1);
        } else {
            prepunct = "";
        }
        if ((m = match_regexp(word, postword_punct_expr))) {
            postpunct = substr(word, @m[1]);
            word = substr(word, 1, ((m[1])[1]) - 1);
        } else {
            postpunct = "";
        }
        oword = word;
        quoted = (quoted + (((prepunct + word).sed("[^\"]+", "", "g")).length())) % 2;
        if ((!quoted) && ((word.length()) > 0)) {
            if ((word[1]) == "\\") {
                oword = (word = word.subrange(2));
            } else if (word in shortwords) {
                // don't match against common short words.
            } else if (word in ["me", "myself"]) {
                word = "yourself";
                oword = pronouns['pr];
            } else if (word == "I") {
                word = "you";
                oword = pronouns['ps];
            } else if (word == "my") {
                word = "your";
                oword = pronouns['pp];
            } else if (word == "mine") {
                word = "yours";
                oword = pronouns['pq];
            } else if (word in [ant_pronouns['ps], "%s"]) {
                word = ant_pronouns['ps];
                oword = antecedent ? [antecedent, word, "you"] : word;
            } else if (word in [ant_pronouns['po], "%o"]) {
                word = ant_pronouns['po];
                oword = antecedent ? [antecedent, word, "you"] : word;
            } else if (word in [ant_pronouns['pp], "%p"]) {
                word = ant_pronouns['pp];
                oword = antecedent ? [antecedent, word, "your"] : word;
            } else if (word in [ant_pronouns['pr], "%r"]) {
                word = ant_pronouns['pr];
                oword = antecedent ? [antecedent, word, ((antecedent.length()) > 1) ? "yourselves" : "yourself"] : word;
            } else if (word in [ant_pronouns['pq], "%q"]) {
                word = ant_pronouns['pq];
                oword = antecedent ? [antecedent, word, "yours"] : word;
            } else if ((word[1]) == ".") {
                // verb to conjugate
                word = substr(word, 2);
                if (match_regexp(word, "(ch|sh|s)$"))
                    oword = word + "es";
                else if (match_regexp(word, "[^a]y$"))
                    oword = substr(word, 1, strlen(word) - 1) + "ies";
                else
                    oword = word + "s";
            } else if ((word[1]) == ":") {
                // a verb for antecedent, to conjugate
                word = substr(word, 2);
                if (match_regexp(word, "es$"))
                    oword = substr(word, 1, strlen(word) - 2);
                else if (match_regexp(word, "ies$"))
                    oword = substr(word, 1, strlen(word) - 3) + "y";
                else if (match_regexp(word, "s$"))
                    oword = substr(word, 1, strlen(word) - 1);
                if ((antecedent.length()) < 2)
                    oword = [antecedent, word, oword];
                else
                    word = oword;
            } else {
                if ((| substr(word, (word.length()) - 1, 2) |) == "'s") {
                    posessive = "'s";
                    word = (oword = substr(word, 1, (word.length()) - 2));
                } else {
                    posessive = "";
                }
                if (((word[word.length()]) == "*") || (word in ["everyone", "everything"])) {
                    // look for matching things..
                    if (word in ["everyone", "everything"]) {
                        things = word == "everything";
                        word = "";
                    } else if (((word.length()) > 1) && ((word[(word.length()) - 1]) == "*")) {
                        // match things too.
                        word = substr(word, 1, (word.length()) - 2);
                        things = 1;
                    } else {
                        // just match people.
                        things = 0;
                        word = substr(word, 1, (word.length()) - 1);
                    }
                    catch ~ambig, ~objnf {
                        who = [.match_environment(word)];
                    } with {
                        if ((error() == ~objnf) && word) {
                            who = [];
                        } else {
                            catch ~ambig, ~objnf {
                                who = [(.environment()).match_object(word)];
                            } with {
                                if (error() == ~ambig)
                                    who = (traceback()[1])[3];
                                else
                                    throw(~stop, ("Object '" + word) + "' not found.");
                            }
                        }
                    }
                    who = setremove(who, this());
                    if (!things)
                        who = filter w in (who) where (w.is($body));
                    else
                        who = filter w in (who) where (w.is($thing));
                    if (who) {
                        word = map w in (who) to ((w.name()) + posessive).to_english();
                        recips = union(recips, who);
                    } else {
                        word = (things ? "nothing" : "nobody") + posessive;
                    }
                    oword = word;
                    posessive = "";
                    antecedent = who;
                    ant_pronouns = ((antecedent.length()) == 1) ? (((antecedent[1]).gender()).pronouns()) : ($gender_plural.pronouns());
                } else if ((| (who = .match_environment((w = word))) |) && (who.is($body))) {
                    // Might be a valid match for a username..
                    if ((wname = who.name()) == w) {
                        // full name match.  Make sure it's capitalized right.
                        word = (oword = wname);
                        recips = setadd(recips, who);
                        antecedent = [who];
                        ant_pronouns = (who.gender()).pronouns();
                    } else {
                        aliases = who.name_templates();
                        aliases = map w in (aliases) to (explode(w, "|")).flatten();
                        aliases = map w in (aliases) to (strsub(w, "?", ""));
                        if (word in aliases) {
                            word = (oword = wname);
                            recips = setadd(recips, who);
                            antecedent = [who];
                            ant_pronouns = (who.gender()).pronouns();
                        }
                    }
                }
                word += posessive;
                oword += posessive;
            }
        }
        quoted = (quoted + ((postpunct.sed("[^\"]+", "", "g")).length())) % 2;
        selfmsg += [(prepunct + word) + postpunct];
        if (type(oword) == 'string)
            othersmsg += [(prepunct + oword) + postpunct];
        else
            othersmsg += [[oword[1], (prepunct + (oword[2])) + postpunct, (prepunct + (oword[3])) + postpunct]];
        refresh();
    }
    msg = "";
    cap = 0;
    for word in (selfmsg) {
        word = cap ? ("  " + (word.capitalize())) : (" " + word);
        msg += word;
        cap = match_regexp(word, "[.!?:][^A-Za-z0-9_]*$");
        refresh();
    }
    msgdict = #[[this(), (<$ctext_frob, [[("You" + msg) + (cap ? "" : ".")], #[]]>)]];
    name = .name();
    for w in (recips + [0]) {
        wname = w ? (w.name()) : 0;
        cap = 0;
        msg = "";
        name_expr = ((((("( |^)" + preword_punct_chars) + "*(") + ((w.name()).regexp_escape())) + ")('s)?") + postword_punct_chars) + "*( |$)";
        for word in (othersmsg) {
            switch (type(word)) {
                case 'string:
                    if (w && (wname != "you")) {
                        while ((m = word.match_regexp(name_expr))) {
                            if ((m[4])[1])
                                word = ((word.subrange(1, ((m[3])[1]) - 1)) + "your") + (word.subrange(((m[4])[1]) + ((m[4])[2])));
                            else
                                word = ((word.subrange(1, ((m[3])[1]) - 1)) + "you") + (word.subrange(((m[3])[1]) + ((m[3])[2])));
                        }
                    }
                    word = cap ? ("  " + (word.capitalize())) : (" " + word);
                case 'list:
                    if (w in (word[1]))
                        word = cap ? ("  " + ((word[3]).capitalize())) : (" " + (word[3]));
                    else
                        word = cap ? ("  " + ((word[2]).capitalize())) : (" " + (word[2]));
            }
            msg += word;
            cap = match_regexp(word, "[.!?:][^A-Za-z0-9_]*$");
            refresh();
        }
        msg = (name + msg) + (cap ? "" : ".");
        msgdict = msgdict.add(w || "general", (<$ctext_frob, [[msg], #[]]>));
    }
    (.location()).announce((<$message_frob, msgdict>));
};
new method
Replacing protected method $body.say_cmd()

protected method $body.say_cmd() {
    arg cmdstr, cmd, what;
    var type, how, idx;
    
    (> .perms(caller(), 'command) <);
    if (what)
        how = $code_lib.punctuation_type(what);
    else
        how = "say";
    (.location()).announce((((((.name()) + " ") + how) + "s, \"") + what) + "\"");
};
new method
Replacing protected method $body.remove_cmd()

protected method $body.remove_cmd() {
    arg cmd, cmdstr, what;
    
    (> .perms(caller(), $user, $body) <);
    what = (> .match_env_nice(what) <);
    if (!(what.is($wearable_frob)))
        return ("You are not wearing " + (what.name())) + ".";
    catch any
        what = (> what.shed() <);
    with
        return (traceback()[1])[2];
    return "You remove " + (what.name());
};
new method
Replacing protected method $body.parse_interaction_reference()

protected method $body.parse_interaction_reference() {
    arg targets, what, @userdb;
    var recip, target, msg, out;
    
    [(userdb ?= 0)] = userdb;
    targets = (targets && (targets.explode_list())) || [];
    if (!targets) {
        if (!(targets = (| interaction['objs] |)))
            throw(~stop, ("You must direct your " + what) + " to a target.");
        out = targets[2];
    } else {
        out = [];
        for recip in (targets) {
            target = 0;
            if (userdb)
                target = (| $user_db.match_begin(recip) |);
            if (!target) {
                catch ~objnf, ~namenf, ~invdbref, ~context, ~ambig
                    target = (> .match_environment(recip) <);
                with
                    throw(~stop, (traceback()[1])[2]);
            }
            if (!(target.is($body)))
                throw(~stop, (target.namef('ref)) + " is not a valid recipient.");
            out = setadd(out, target);
        }
    }
    return filter target in (out) where (valid(target));
};
update objvar
Updating objvar $robot<$located>,location

object $robot;
var $located location = $the_pit;
add objvar
Adding objvar $robot<$command_cache>,shortcuts

object $robot;
var $command_cache shortcuts = 0;
add objvar
Adding objvar $robot<$command_cache>,commands

object $robot;
var $command_cache commands = 0;
clear objvar
Clearing objvar $command_aliases<$command_cache>,shortcuts

object $command_aliases;
old var $command_cache shortcuts;
clear objvar
Clearing objvar $command_aliases<$command_cache>,commands

object $command_aliases;
old var $command_cache commands;
clear objvar
Clearing objvar $bad_commands<$command_cache>,shortcuts

object $bad_commands;
old var $command_cache shortcuts;
clear objvar
Clearing objvar $bad_commands<$command_cache>,commands

object $bad_commands;
old var $command_cache commands;
update objvar
Updating objvar $bad_commands<$bad_commands>,non_supported_cmds

object $bad_commands;
var $bad_commands non_supported_cmds = #[["quit", "@quit"], ["WHO", "@who"], ["@create", "@new"], ["help", "@help"], ["news", "@news"], ["page", "@page"], ["@gender", "@set gender"], ["uptime", "@status"], ["@alias", "@add-command-alias` or `@add-name-alias"], ["@check", "@monitor"], ["@paranoid", "@monitor"], ["@version", "@status"], ["@lock", "@set lock"], ["@unlock", "@set lock"], ["+com", ["See: `@help Channels`"]], ["tell", "@page"]];
update objvar
Updating objvar $bad_commands<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[["@create", [["@create", "*", "@create <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["help", [["help", "*", "help <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["page", [["page", "*", "page <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["who", [["who", "*", "who <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["quit", [["quit", "*", "quit <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["news", [["news", "*", "news <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@gender", [["@gender", "*", "@gender <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["uptime", [["uptime", "*", "uptime <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@alias", [["@alias", "*", "@alias <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@check|@paranoid", [["@check|@paranoid", "*", "@check|@paranoid <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@version", [["@version", "*", "@version <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@lock", [["@lock", "*", "@lock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@unlock", [["@unlock", "*", "@unlock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["+com", [["+com", "*", "+com <any>", 'old_command_cmd, #[[1, ['any, []]]]]]]];
  new = #[["@create", [["@create", "*", "@create <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["help", [["help", "*", "help <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["page", [["page", "*", "page <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["who", [["who", "*", "who <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["quit", [["quit", "*", "quit <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["news", [["news", "*", "news <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@gender", [["@gender", "*", "@gender <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["uptime", [["uptime", "*", "uptime <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@alias", [["@alias", "*", "@alias <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@check|@paranoid", [["@check|@paranoid", "*", "@check|@paranoid <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@version", [["@version", "*", "@version <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@lock", [["@lock", "*", "@lock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@unlock", [["@unlock", "*", "@unlock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["+com", [["+com", "*", "+com <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["tell", [["tell", "*", "tell <any>", 'old_command_cmd, #[[1, ['any, []]]]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$bad_commands<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $bad_commands;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
clear objvar
Clearing objvar $help_ui<$command_cache>,shortcuts

object $help_ui;
old var $command_cache shortcuts;
clear objvar
Clearing objvar $help_ui<$command_cache>,commands

object $help_ui;
old var $command_cache commands;
update objvar
Updating objvar $editor_reference<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[["@mcp-upload-session", [["@mcp-upload-session", "*", "@mcp-upload-session <descendant of $editor_session>", 'mcp_upload_cmd, #[[1, ['descendant, [$editor_session]]]]]]], ["@cleanup-sessions|@c-s?essions", [["@cleanup-sessions|@c-s?essions", "", "@cleanup-sessions|@c-s?essions", 'cleanup_sessions, #[]]]], ["@edit", [["@edit", "*", "@edit <any>", 'edit_cmd, #[[1, ['any, []]]]]]]];
  new = #[["@mcp-upload-session", [["@mcp-upload-session", "*", "@mcp-upload-session <descendant of $editor_session>", 'mcp_upload_cmd, #[[1, ['descendant, [$editor_session]]]]]]], ["@edit", [["@edit", "*", "@edit <any>", 'edit_cmd, #[[1, ['any, []]]]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$editor_reference<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $editor_reference;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
new method
Replacing protected method $editor_reference.reinvoke_editor()

protected method $editor_reference.reinvoke_editor() {
    arg @session;
    var i, t, name;
    
    t = "";
    [(session ?= active_editor), (name ?= "")] = session;
    if (session == 0)
        return "No session to resume.";
    bg_sessions ?= [];
    if (active_editor && ((active_editor != session) || (!(| session.is_resumable() |))))
        t = (.store_editor()) + " ";
    if ((!valid(session)) || (!(session in (bg_sessions + [active_editor])))) {
        active_editor = 0;
        return "Invalid session - editor cleared.";
    }
    if (!(| session.is_resumable() |))
        return "The session is not resumable, you can use '@edit +clean' to remove it";
    active_editor = session;
    bg_sessions = bg_sessions.setremove(active_editor);
    bg_sessions = filter i in (bg_sessions) where (valid(i));
    .add_parser($editor_parser);
    return [t, ("Resumed editing " + ((.active_editor()).session_name())) + ".", "Type 'help' to list available commands."];
};
new method
Replacing public method $editor_reference.cleanup_sessions()

public method $editor_reference.cleanup_sessions() {
    arg @disregard;
    var out, s;
    
    (sender() == $housekeeper) || (> .perms(sender(), this()) <);
    out = [];
    for s in (bg_sessions || []) {
        if (valid(s)) {
            if (s.cleanup_session())
                s.destroy();
            else
                out = setadd(out, s);
        }
    }
    bg_sessions = out;
    if (valid(active_editor) && (active_editor.cleanup_session())) {
        active_editor.destroy();
        clear_var('active_editor);
    }
    return "Clean and invalid sessions cleared.";
};
new method
Replacing public method $editor_reference.edit_cmd()

public method $editor_reference.edit_cmd() {
    arg cmdstr, com, args;
    var syn, num, sess, out, type, i, e, bg;
    
    (> .perms(caller(), 'command) <);
    syn = "@edit <object reference> [+type=...]";
    args = args.trim();
    if (!args) {
        // list sessions
        out = [];
        e = .active_editor();
        if (e) {
            if ($editor_parser in (.parsers()))
                out += ["** %0 " + (e.session_name())];
            else
                out += ["   %0 " + (e.session_name())];
        }
        bg = .background_editor_sessions();
        for sess in [1 .. listlen(bg)]
            out += [(("   %" + sess) + " ") + ((bg[sess]).session_name())];
        if (out)
            return ["Editor Sessions:"] + out;
        return "No editor sessions.";
    } else if ((args[1]) == "%") {
        // resume session
        args = substr(args, 2);
        if ((!args) || ((args[1]) == " ")) {
            num = 0;
        } else {
            catch ~nonum
                num = (> args.to_number() <);
            with
                return (traceback()[1])[2];
        }
        if (!num) {
            if (.active_editor())
                return .reinvoke_editor(.active_editor(), "%0");
            else if (.background_editor_sessions())
                sess = (.background_editor_sessions())[1];
            else
                return "No sessions to resume.";
        } else {
            if ((listlen((.background_editor_sessions()) || []) < num) || (num < 0))
                return ("There is not an editor session %" + num) + ".";
            sess = (.background_editor_sessions())[num];
        }
        return .reinvoke_editor(sess, "%" + num);
    } else {
        args = (> $parse_lib.opt(args, "t?ype", "c?lean") <);
        if ((i = "c?lean" in ((args[2]).slice(1))))
            return .cleanup_sessions();
        if ((i = "t?ype" in ((args[2]).slice(1))))
            type = ((args[2])[i])[4];
        type ?= "any";
        catch ~objnf, ~namenf, ~ambig
            args = replace(args, 1, (> $parse_lib.ref((args[1]).join()) <));
        with
            return (traceback()[1])[2];
        return .edit(@args, type);
    }
};
add objvar
Adding objvar $channel_ui<$command_cache>,shortcuts

object $channel_ui;
var $command_cache shortcuts = 0;
add objvar
Adding objvar $channel_ui<$command_cache>,commands

object $channel_ui;
var $command_cache commands = 0;
clear objvar
Clearing objvar $user_info<$command_cache>,shortcuts

object $user_info;
old var $command_cache shortcuts;
clear objvar
Clearing objvar $user_info<$command_cache>,commands

object $user_info;
old var $command_cache commands;
clear objvar
Clearing objvar $www_preferences<$command_cache>,shortcuts

object $www_preferences;
old var $command_cache shortcuts;
clear objvar
Clearing objvar $www_preferences<$command_cache>,commands

object $www_preferences;
old var $command_cache commands;
update objvar
Updating objvar $user<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[["@quit", [["@quit", "", "@quit", 'quit_cmd, #[]]]], ["i?nventory", [["i?nventory", "", "i?nventory", 'inventory_cmd, #[]]]], ["@audit", [["@audit", "*", "@audit <any>", 'audit_cmd, #[[1, ['any, []]]]]]], ["@who", [["@who", "*", "@who <any>", 'who_cmd, #[[1, ['any, []]]]]]], ["@del-command-a?lias|@dca?lias", [["@del-command-a?lias|@dca?lias", "*", "@del-command-a?lias|@dca?lias <any>", 'del_command_alias_cmd, #[[1, ['any, []]]]]]], ["@command-a?liases|@ca?liases", [["@command-a?liases|@ca?liases", "*", "@command-a?liases|@ca?liases <any>", 'command_aliases_cmd, #[[1, ['any, []]]]]]], ["@add-command-a?lias|@aca?lias", [["@add-command-a?lias|@aca?lias", "*", "@add-command-a?lias|@aca?lias <any>", 'add_command_alias_cmd, #[[1, ['any, []]]]]]], ["@com?mands", [["@com?mands", "*", "@com?mands <any>", 'commands_cmd, #[[1, ['any, []]]]]]], ["@news", [["@news", "", "@news", 'news_cmd, #[]]]], ["@forget", [["@forget", "*", "@forget <any>", 'forget_cmd, #[[1, ['any, []]]]]]], ["@whereis|@where-is", [["@whereis|@where-is", "*", "@whereis|@where-is <any>", 'whereis_cmd, #[[1, ['any, []]]]]]], ["@password|@passwd", [["@password|@passwd", "*", "@password|@passwd <any>", 'password_cmd, #[[1, ['any, []]]]]]], ["@age", [["@age", "*", "@age <object>", 'age_cmd, #[[1, ['object, []]]]]]], ["@context", [["@context", "", "@context", 'context_cmd, #[]]]], ["@rename", [["@rename", "*", "@rename <any>", 'rename_cmd, #[[1, ['any, []]]]]]], ["@add-writer|@aw", [["@add-writer|@aw", "*", "@add-writer|@aw <any>", 'add_writer_cmd, #[[1, ['any, []]]]]]], ["@del-writer|@dw", [["@del-writer|@dw", "*", "@del-writer|@dw <any>", 'del_writer_cmd, #[[1, ['any, []]]]]]], ["@manage?d", [["@manage?d", "*", "@manage?d <any>", 'managed_cmd, #[[1, ['any, []]]]]]], ["@remember", [["@remember", "* as *", "@remember <object> as <any>", 'remember_cmd, #[[1, ['object, []]], [3, ['any, []]]]]]], ["@remembered", [["@remembered", "*", "@remembered <any>", 'remembered_cmd, #[[1, ['any, []]]]]]], ["discard", [["discard", "*", "discard <object>", 'discard_cmd, #[[1, ['object, []]]]]]], ["@writes", [["@writes", "*", "@writes <object>", 'writes_cmd, #[[1, ['object, []]]]]]], ["@trusted?-by", [["@trusted?-by", "*", "@trusted?-by <object>", 'trusted_by_cmd, #[[1, ['object, []]]]]]], ["@del-trust?ee|@dt", [["@del-trust?ee|@dt", "*", "@del-trust?ee|@dt <object:>", 'del_trustee_cmd, #[[1, ['object_opt, []]]]]]], ["@monitor", [["@monitor", "*", "@monitor <any>", 'monitor_cmd, #[[1, ['any, []]]]]]], ["@ex?amine", [["@ex?amine", "*", "@ex?amine <object:+c?hop>", 'examine_cmd, #[[1, ['object_opt, ["c?hop"]]]]]]], ["@map", [["@map", "", "@map", 'map_cmd, #[]]]], ["@finger|@ustat", [["@finger|@ustat", "*", "@finger|@ustat <user>", 'finger_cmd, #[[1, ['user, []]]]]]], ["@trusts|@trustee?s", [["@trusts|@trustee?s", "*", "@trusts|@trustee?s <object>", 'trusts_cmd, #[[1, ['object, []]]]]]], ["@writers", [["@writers", "*", "@writers <object>", 'writers_cmd, #[[1, ['object, []]]]]]], ["@manager", [["@manager", "*", "@manager <object>", 'manager_cmd, #[[1, ['object, []]]]]]], ["@desc?ribe|@prose", [["@desc?ribe|@prose", "*", "@desc?ribe|@prose <any>", 'description_cmd, #[[1, ['any, []]]]]]], ["l?ook|exam?ine", [["l?ook|exam?ine", "*", "l?ook|exam?ine <any>", 'look_cmd, #[[1, ['any, []]]]]]], ["walk|go", [["walk|go", "*", "walk|go <any>", 'go_cmd, #[[1, ['any, []]]]]]], ["@ant|@add-name-template", [["@ant|@add-name-template", "*", "@ant|@add-name-template <any>", 'add_name_template_cmd, #[[1, ['any, []]]]]]], ["@dnt|@del-name-template", [["@dnt|@del-name-template", "*", "@dnt|@del-name-template <any>", 'del_name_template_cmd, #[[1, ['any, []]]]]]], ["@name-template?s|@template?s", [["@name-template?s|@template?s", "*", "@name-template?s|@template?s <object>", 'name_templates_cmd, #[[1, ['object, []]]]]]], ["@register|@register-name", [["@register|@register-name", "*", "@register|@register-name <any>", 'register_name_cmd, #[[1, ['any, []]]]]]], ["@unregister|@unregister-name", [["@unregister|@unregister-name", "*", "@unregister|@unregister-name <any>", 'unregister_name_cmd, #[[1, ['any, []]]]]]], ["@registered", [["@registered", "", "@registered", 'registered_cmd, #[]]]], ["@page", [["@page", "* with *", "@page <any> with <any>", 'remote_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@paste?-to", [["@paste?-to", "*", "@paste?-to <any>", 'paste_cmd, #[[1, ['any, []]]]]]], ["@new", [["@new", "*", "@new <any>", 'new_cmd, #[[1, ['any, []]]]]]], ["@status|@uptime", [["@status|@uptime", "*", "@status|@uptime <any>", 'status_cmd, #[[1, ['any, []]]]]]], ["@msg?s|@message?s", [["@msg?s|@message?s", "*", "@msg?s|@message?s <any>", 'msg_cmd, #[[1, ['any, []]]]]]], ["@date|@time", [["@date|@time", "*", "@date|@time <any>", 'date_cmd, #[[1, ['any, []]]]]]], ["@set", [["@set", "*", "@set <any>", 'set_cmd, #[[1, ['any, []]]]]]], ["PUEBLOCLIENT", [["PUEBLOCLIENT", "*", "PUEBLOCLIENT <any>", 'pueblo_cmd, #[[1, ['any, []]]]]]], ["@ways|@exits", [["@ways|@exits", "*", "@ways|@exits <any>", 'ways_cmd, #[[1, ['any, []]]]]]], ["@tut?orial", [["@tut?orial", "*", "@tut?orial <any>", 'tutorial_cmd, #[[1, ['any, []]]]]]], ["null", [["null", "*", "null <any>", 'null_cmd, #[[1, ['any, []]]]]]], ["@away", [["@away", "*", "@away <any>", 'away_cmd, #[[1, ['any, []]]]]]], ["@back", [["@back", "", "@back", 'back_cmd, #[]]]], ["@add-trust?ee|@at", [["@add-trust?ee|@at", "*", "@add-trust?ee|@at <object:>", 'add_trustee_cmd, #[[1, ['object_opt, []]]]]]]];
  new = #[["@quit", [["@quit", "", "@quit", 'quit_cmd, #[]]]], ["i?nventory", [["i?nventory", "", "i?nventory", 'inventory_cmd, #[]]]], ["@audit", [["@audit", "*", "@audit <any>", 'audit_cmd, #[[1, ['any, []]]]]]], ["@who", [["@who", "*", "@who <any>", 'who_cmd, #[[1, ['any, []]]]]]], ["@del-command-a?lias|@dca?lias", [["@del-command-a?lias|@dca?lias", "*", "@del-command-a?lias|@dca?lias <any>", 'del_command_alias_cmd, #[[1, ['any, []]]]]]], ["@command-a?liases|@ca?liases", [["@command-a?liases|@ca?liases", "*", "@command-a?liases|@ca?liases <any>", 'command_aliases_cmd, #[[1, ['any, []]]]]]], ["@add-command-a?lias|@aca?lias", [["@add-command-a?lias|@aca?lias", "*", "@add-command-a?lias|@aca?lias <any>", 'add_command_alias_cmd, #[[1, ['any, []]]]]]], ["@com?mands", [["@com?mands", "*", "@com?mands <any>", 'commands_cmd, #[[1, ['any, []]]]]]], ["@news", [["@news", "", "@news", 'news_cmd, #[]]]], ["@forget", [["@forget", "*", "@forget <any>", 'forget_cmd, #[[1, ['any, []]]]]]], ["@whereis|@where-is", [["@whereis|@where-is", "*", "@whereis|@where-is <any>", 'whereis_cmd, #[[1, ['any, []]]]]]], ["@password|@passwd", [["@password|@passwd", "*", "@password|@passwd <any>", 'password_cmd, #[[1, ['any, []]]]]]], ["@age", [["@age", "*", "@age <object>", 'age_cmd, #[[1, ['object, []]]]]]], ["@context", [["@context", "", "@context", 'context_cmd, #[]]]], ["@rename", [["@rename", "*", "@rename <any>", 'rename_cmd, #[[1, ['any, []]]]]]], ["@add-writer|@aw", [["@add-writer|@aw", "*", "@add-writer|@aw <any>", 'add_writer_cmd, #[[1, ['any, []]]]]]], ["@del-writer|@dw", [["@del-writer|@dw", "*", "@del-writer|@dw <any>", 'del_writer_cmd, #[[1, ['any, []]]]]]], ["@manage?d", [["@manage?d", "*", "@manage?d <any>", 'managed_cmd, #[[1, ['any, []]]]]]], ["@remember", [["@remember", "* as *", "@remember <object> as <any>", 'remember_cmd, #[[1, ['object, []]], [3, ['any, []]]]]]], ["@remembered", [["@remembered", "*", "@remembered <any>", 'remembered_cmd, #[[1, ['any, []]]]]]], ["discard", [["discard", "*", "discard <object>", 'discard_cmd, #[[1, ['object, []]]]]]], ["@writes", [["@writes", "*", "@writes <object>", 'writes_cmd, #[[1, ['object, []]]]]]], ["@trusted?-by", [["@trusted?-by", "*", "@trusted?-by <object>", 'trusted_by_cmd, #[[1, ['object, []]]]]]], ["@del-trust?ee|@dt", [["@del-trust?ee|@dt", "*", "@del-trust?ee|@dt <object:>", 'del_trustee_cmd, #[[1, ['object_opt, []]]]]]], ["@monitor", [["@monitor", "*", "@monitor <any>", 'monitor_cmd, #[[1, ['any, []]]]]]], ["@ex?amine", [["@ex?amine", "*", "@ex?amine <object:+c?hop>", 'examine_cmd, #[[1, ['object_opt, ["c?hop"]]]]]]], ["@map", [["@map", "", "@map", 'map_cmd, #[]]]], ["@finger|@ustat", [["@finger|@ustat", "*", "@finger|@ustat <user>", 'finger_cmd, #[[1, ['user, []]]]]]], ["@trusts|@trustee?s", [["@trusts|@trustee?s", "*", "@trusts|@trustee?s <object>", 'trusts_cmd, #[[1, ['object, []]]]]]], ["@writers", [["@writers", "*", "@writers <object>", 'writers_cmd, #[[1, ['object, []]]]]]], ["@manager", [["@manager", "*", "@manager <object>", 'manager_cmd, #[[1, ['object, []]]]]]], ["@desc?ribe|@prose", [["@desc?ribe|@prose", "*", "@desc?ribe|@prose <any>", 'description_cmd, #[[1, ['any, []]]]]]], ["l?ook|exam?ine", [["l?ook|exam?ine", "*", "l?ook|exam?ine <any>", 'look_cmd, #[[1, ['any, []]]]]]], ["walk|go", [["walk|go", "*", "walk|go <any>", 'go_cmd, #[[1, ['any, []]]]]]], ["@ant|@add-name-template", [["@ant|@add-name-template", "*", "@ant|@add-name-template <any>", 'add_name_template_cmd, #[[1, ['any, []]]]]]], ["@dnt|@del-name-template", [["@dnt|@del-name-template", "*", "@dnt|@del-name-template <any>", 'del_name_template_cmd, #[[1, ['any, []]]]]]], ["@name-template?s|@template?s", [["@name-template?s|@template?s", "*", "@name-template?s|@template?s <object>", 'name_templates_cmd, #[[1, ['object, []]]]]]], ["@register|@register-name", [["@register|@register-name", "*", "@register|@register-name <any>", 'register_name_cmd, #[[1, ['any, []]]]]]], ["@unregister|@unregister-name", [["@unregister|@unregister-name", "*", "@unregister|@unregister-name <any>", 'unregister_name_cmd, #[[1, ['any, []]]]]]], ["@registered", [["@registered", "", "@registered", 'registered_cmd, #[]]]], ["@page", [["@page", "* with *", "@page <any> with <any>", 'remote_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@paste?-to", [["@paste?-to", "*", "@paste?-to <any>", 'paste_cmd, #[[1, ['any, []]]]]]], ["@new", [["@new", "*", "@new <any>", 'new_cmd, #[[1, ['any, []]]]]]], ["@status|@uptime", [["@status|@uptime", "*", "@status|@uptime <any>", 'status_cmd, #[[1, ['any, []]]]]]], ["@msg?s|@message?s", [["@msg?s|@message?s", "*", "@msg?s|@message?s <any>", 'msg_cmd, #[[1, ['any, []]]]]]], ["@date|@time", [["@date|@time", "*", "@date|@time <any>", 'date_cmd, #[[1, ['any, []]]]]]], ["@set", [["@set", "*", "@set <any>", 'set_cmd, #[[1, ['any, []]]]]]], ["PUEBLOCLIENT", [["PUEBLOCLIENT", "*", "PUEBLOCLIENT <any>", 'pueblo_cmd, #[[1, ['any, []]]]]]], ["@ways|@exits", [["@ways|@exits", "*", "@ways|@exits <any>", 'ways_cmd, #[[1, ['any, []]]]]]], ["@tut?orial", [["@tut?orial", "*", "@tut?orial <any>", 'tutorial_cmd, #[[1, ['any, []]]]]]], ["null", [["null", "*", "null <any>", 'null_cmd, #[[1, ['any, []]]]]]], ["@away", [["@away", "*", "@away <any>", 'away_cmd, #[[1, ['any, []]]]]]], ["@back", [["@back", "", "@back", 'back_cmd, #[]]]], ["@add-trust?ee|@at", [["@add-trust?ee|@at", "*", "@add-trust?ee|@at <object:>", 'add_trustee_cmd, #[[1, ['object_opt, []]]]]]], ["@player-breakdown|@pb|@user-breakdown|@ub", [["@player-breakdown|@pb|@user-breakdown|@ub", "", "@player-breakdown|@pb|@user-breakdown|@ub", 'player_breakdown_cmd, #[]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$user<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $user;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
old method
Deleting normal method $user._who_is()

object $user;
eval {
  del_method('_who_is);
};
old method
Deleting normal method $user._who_at_place()

object $user;
eval {
  del_method('_who_at_place);
};
old method
Deleting normal method $user._who_admins()

object $user;
eval {
  del_method('_who_admins);
};
old method
Deleting normal method $user._who_short()

object $user;
eval {
  del_method('_who_short);
};
old method
Deleting normal method $user._who_programmers()

object $user;
eval {
  del_method('_who_programmers);
};
old method
Deleting normal method $user.reap_notified()

object $user;
eval {
  del_method('reap_notified);
};
new method
Adding public method $user._reap__notified()

public method $user._reap__notified() {
    return reap_notified;
};
new method
Adding protected method $user._who__short()

protected method $user._who__short() {
    arg people, title, @rest;
    var user, tmp, who, namestr, total;
    
    who = [];
    total = people.length();
    .tell((((title + " (total: ") + tostr(total)) + ((total == 1) ? " person" : " people")) + "):");
    for user in (people) {
        //     namestr = " " + user.name() + " (" + $time.elapsed(time()
        // - user.connected_at())
        //+ " " + $time.dhms(user.idle_seconds()) + ")";
        namestr = (((((" " + (user.name())) + " (") + ($time.dhms(time() - (user.connected_at())))) + "/") + ($time.dhms(user.idle_seconds()))) + ")";
        who += [namestr];
        if (tmp < ((namestr.length()) + 2))
            tmp = (namestr.length()) + 2;
    }
    .tell($list.vcolumnize(who, (.linelen()) / (tmp + 1), .linelen()));
};
new method
Adding public method $user.format_messages()

public method $user.format_messages() {
    arg target, @what;
    var messages, out, b, branches, m;
    
    catch ~methodnf
        messages = target.all_msgs();
    with
        return [("[" + (target.name())) + " does not have settable messages]"];
    out = [];
    for m in ((messages.keys()).sort()) {
        branches = messages[m];
        if (branches.contains("general")) {
            out += [("  " + m) + " = "].affix((branches["general"]).uncompile());
            branches = dict_del(branches, "general");
        }
        for b in ((branches.keys()).sort())
            out += [((("  " + m) + ".") + b) + " = "].affix((branches[b]).uncompile());
    }
    return out;
};
new method
Replacing protected method $user.login_notify(): forked 

protected method $user.login_notify(): forked  {
    arg connection, last;
    var l, sub, out, ans, rtime;
    
    sub = .subscribed();
    out = [];
    for l in ((sub.keys()).setremove(this())) {
        if (valid(l) && ((l.last_received_on()) > ((sub[l])[1])))
            out += [l.mail_name()];
    }
    if (out)
        .tell("<Mail> New mail on lists: " + (out.to_english()));
    if ((| (.last_received_on()) > (((.subscribed())[this()])[1]) |))
        .tell("<Mail> You have new mail (use `@help mail` to learn about mail)");
    if (last)
        .tell("<Login> Last connected at " + ($time.format("%A %B %d %I:%M %p %Y", abs(last))));
    rtime = $time.realm_time((.location()).realm(), 'with_season);
    .tell((("<Login> It is currently " + (rtime[1])) + " in ") + ((rtime[2]).name()));
    if (failed) {
        (| .tell(("<Login> ** " + failed) + " failed login attempts **") |);
        (| clear_var('failed) |);
    }
    if (!(.prose('literal)))
        .tell(["You have not yet set a description for yourself.", "Perhaps you'd like to take a look at the tutorial.", "Type @tutorial to read about how to set a description and more."]);
};
new method
Replacing protected method $user.description_cmd()

protected method $user.description_cmd() {
    arg cmdstr, cmd, str;
    var args, obj, desc, long;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* as *"))) {
        obj = (> .match_env_nice(args[1]) <);
        desc = ((args[3]).trim()).unquote();
    } else {
        obj = (> .match_env_nice(str) <);
        if ((desc = .read()) == 'aborted)
            return;
        desc = join(desc.flatten()).trim();
    }
    if (!desc)
        desc = 0;
    catch any
        obj.set_prose(desc);
    with
        return (traceback()[1])[2];
    return ("Description for " + (obj.namef('ref))) + " set.";
};
new method
Replacing public method $user.set_cmd()

public method $user.set_cmd() {
    arg cmdstr, cmd, args;
    var who, branch, name, setting, what, def, opts, clear, showdef, syn;
    
    (> .perms(caller(), 'command) <);
    syn = ["Syntax: @set [TARGET:]SETTING=VALUE", "TARGET defaults to yourself, if unspecified."];
    if ((what = regexp(args, "^ *\+(clear|c) +(.*)"))) {
        clear = 1;
        args = what[2];
    }
    if ((what = regexp(args, "^ *\+(definers|definer|def|d) *= *\$?([a-z0-9_]+) *(.*)"))) {
        if (!(showdef = (| lookup(tosym(what[2])) |)))
            return "Invalid definer $" + (what[2]);
        args = what[3];
    }
    if ((what = regexp(args, "^ *\+(def|definer|definers|d) *(.*)"))) {
        showdef = 1;
        args = what[2];
    }
    if ((what = regexp(args, "^([^:=]+): *(.*)$"))) {
        who = (> .match_env_nice((what[1]).trim()) <);
        args = (what[2]).trim();
    } else {
        who = this();
    }
    if ((what = regexp(args, "^([\@a-z0-9-]+) *= *(.*)$"))) {
        name = (what[1]).trim();
        args = (what[2]).trim();
    } else {
        name = args;
        args = "";
    }
    if (!name)
        return ([("-- Settings on " + (who.namef('ref))) + ":"] + (.format_settings(who, showdef))) + ["---"];
    if (!($code_lib.valid_setting_id(name)))
        return syn + [("** Invalid Setting name \"" + name) + "\""];
    setting = args.unquote();
    catch any {
        def = who.setting_definer(name);
        if (clear)
            who = who.clear_setting(name, def);
        else
            who = who.set_setting(name, def, setting);
        setting = who.format_setting(name, def, who.get_setting(name, def));
        return ["-- Setting changed to:", (("  " + name) + " = ") + setting, "--"];
    } with {
        if (error() == ~perm)
            return "You are not allowed to change settings on " + (who.namef('ref));
        return (traceback()[1])[2];
    }
};
new method
Replacing protected method $user.rename_cmd()

protected method $user.rename_cmd() {
    arg cmdstr, cmd, args;
    var obj, name, templates, article, old, oldart, oldts, new, t;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) > 2) && ((args[2]) == "to"))
        args = delete(args, 2);
    if (listlen(args) > 2)
        args = [args[1], sublist(args, 2).join()];
    if ((!args) || (listlen(args) != 2))
        return ("Syntax: `" + cmd) + " \"<object>\" [to] \"<newname>\" [+(proper|unique|normal)]`";
    obj = (> .match_env_nice(args[1]) <);
    catch any {
        name = (> $code_lib.parse_name(sublist(args, 2).join()) <);
        templates = name[2];
        article = (name[1])[2];
        name = (name[1])[1];
        if ((name[1]) == "$") {
            if ((obj.is($user)) || (obj.is($place))) {
                if (!(.is($admin)))
                    return "User and Place objnames can only be changed by administrators.";
                else
                    (> .check_mojo() <);
            }
            name = substr(name, 2);
            if (!(name.valid_ident()))
                return "Object names can only contain a-z, 0-9 and the underscore.";
            name = tosym(name);
            old = obj.namef('xref);
            (> obj.set_objname(name) <);
            return ((("Renamed " + old) + " to ") + obj) + ".";
        } else {
            if (!(obj.has_ancestor($has_name)))
                return ("Object \"" + obj) + "\" cannot have a regular name.";
            oldart = (obj.name('literal))[1];
            oldts = obj.name_templates();
            old = ((((" [" + article) + "] \"") + (obj.name())) + "\"") + (templates ? ((" (" + (oldts.to_english())) + ")") : "");
            old = ("\"" + (obj.name())) + "\"";
            obj = (> obj.set_name(name, article) <);
            new = ("\"" + (obj.name())) + "\"";
            if (templates) {
                for t in (templates)
                    obj = (> obj.add_name_template(t) <);
                new += (" (" + ((obj.name_templates()).to_english())) + ")";
                old += (" (" + (oldts.to_english())) + ")";
            }
            if (oldart != ((obj.name('literal))[1])) {
                old = (("[" + oldart) + "] ") + old;
                new = (("[" + ((obj.name('literal))[1])) + "] ") + new;
            }
            return ((("Renamed " + old) + " to ") + new) + ".";
        }
    } with {
        return (traceback()[1])[2];
    }
};
new method
Replacing protected method $user.rehash_cmd()

protected method $user.rehash_cmd() {
    arg cmdstr, cmd, args;
    var target, client, opts, client, o;
    
    (> .perms(caller(), 'command) <);
    [args, opts] = args;
    if ((o = (| "c?lient" in (opts.slice(1)) |)))
        client = (opts[o])[3];
    else if ((o = (| "r?aw" in (opts.slice(1)) |)))
        client = !((opts[o])[3]);
    if (args)
        target = (> .match_env_nice(join(args)) <);
    else
        target = this();
    catch ~perm {
        if (client) {
            .tell(("Rehashing commands on " + (target.namef('ref))) + "...");
            target.cache_client_uninit();
            target.cache_client_init();
            .tell("Done.");
        } else {
            .tell(("Rehashing (raw) commands on " + (target.namef('ref))) + "...");
            target.rehash_cache();
            .tell("Done.");
        }
    } with {
        return "You do not have permission to rehash " + (target.namef('ref));
    }
};
new method
Replacing root method $user.init_user()

root method $user.init_user() {
    var n;
    
    password = "*";
    connected_at = 0;
    last_command_at = 0;
    connections = [];
    parsers = [$command_parser, $channel_parser];
    action = "";
    context = #[];
    .set_quota($sys.get_starting('quota));
    $user_db.insert(.name(), this());
    .set_flags([]);
    .move_to($body_cave);
    task_connections = #[];
    formatter = $plain_format;
};
new method
Replacing protected method $user.add_writer_cmd()

protected method $user.add_writer_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, writer;
    
    (> .perms(caller(), 'command) <);
    args = (args.replace(" to ", " ")).explode();
    if ((!args) || ((args.length()) != 2))
        (> .tell_error(cmd + " <writer> [to] <object>") <);
    writer = (> .match_env_nice(args[1]) <);
    obj = (> .match_env_nice(args[2]) <);
    catch any {
        obj.add_writer(writer);
        return [(("Sucessfully added writer " + (writer.namef('xref))) + " to ") + (obj.namef('xref)), ("New writers list: " + ((((obj.writers('literal)).compress()).mmap('namef, 'xref)).to_english())) + "."];
    } with {
        .tell((traceback()[1])[2]);
    }
};
new method
Adding protected method $user._who__programmers()

protected method $user._who__programmers() {
    arg args, all;
    var out, progs, p, x, t;
    
    progs = [];
    if (args && (!all)) {
        for p in (args) {
            x = $user_db.search(p);
            if (!x)
                .tell(("I don't know who \"" + p) + "\" is.");
            else
                progs += [x];
        }
        t = (("Programmer" + (progs.length())) == 1) ? "" : "s";
    } else if (all) {
        t = "All Programmers";
        progs = $programmer.descendants();
        progs = progs.setremove($admin);
    } else {
        t = "Connected Programmers";
        for p in ($user_db.connected()) {
            if (p.has_ancestor($programmer))
                progs += [p];
        }
    }
    if (!progs)
        return 0;
    return [progs, t];
};
new method
Adding protected method $user._who__at_place()

protected method $user._who__at_place() {
    arg str;
    var place, thing, who, args;
    
    if (str == "home")
        place = .home();
    else
        place = (| .match_environment(str) |);
    
    // try the place db
    if (!place) {
        catch any {
            place = $place_db.search(str);
        } with {
            switch (error()) {
                case ~ambig:
                    .tell("Several places match that name: " + ((((traceback()[1])[3]).mmap('namef)).to_english()));
                case ~namenf:
                    .tell(("The place \"" + str) + "\" cannot be located.");
                    return 0;
                default:
                    .tell((traceback()[1])[2]);
                    return 0;
            }
        }
    }
    who = [];
    for thing in (place.contents()) {
        if (thing.has_ancestor($user))
            who += [thing];
    }
    if (!who) {
        .tell(("Nobody is in " + (place.name())) + ".");
        return 0;
    }
    args = [who, "Users in " + (place.name())];
    args = [@args, [['namef, 'titled], ['idle_time]]];
    args = [@args, ["Name", "Times (idle)"], [1, 1]];
    return args;
};
new method
Replacing public method $user.match_name()

public method $user.match_name() {
    arg str;
    var m, n;
    
    if (!str)
        return 0;
    if ((m = pass(str)))
        return m;
    for n in (registered || []) {
        if ((m = match_begin(n, str)))
            return m;
    }
    return 0;
};
new method
Replacing root method $user.uninit_user()

root method $user.uninit_user() {
    var conn, name;
    
    if (.connected())
        (| (.location()).did_disconnect() |);
    
    // and incase any are lying about
    for conn in (connections)
        (| conn.interface_going_away() |);
    password = 0;
    connections = 0;
    (| $user_db.remove(.name()) |);
    for name in (registered || [])
        (| $user_db.remove(name) |);
};
new method
Adding public method $user.player_breakdown_cmd()

public method $user.player_breakdown_cmd() {
    arg cmdstr, cmd;
    var admins, programmers, builders, users, total, pstrip, bstrip, strip, names, players;
    
    // stuff to strip
    // users
    strip = [$guest, $user, $reaper, $no_one, $player, $builder, $storyteller, $programmer, $admin];
    
    // programmers
    pstrip = [$admin];
    
    // builders
    bstrip = [$programmer, $admin];
    
    // get number of admins
    admins = listlen($sys.admins());
    names = $sys.admins();
    
    // get number of programmers, minus those that are also admins
    programmers = $programmer.descendants();
    programmers = $list.setremove_all(programmers, pstrip);
    programmers = $list.setremove_all(programmers, $sys.admins());
    names += programmers;
    programmers = listlen(programmers);
    
    // get number of builders
    builders = $builder.descendants();
    builders = $list.setremove_all(builders, $sys.admins());
    builders = $list.setremove_all(builders, $programmer.descendants());
    builders = $list.setremove_all(builders, strip);
    names += builders;
    builders = listlen(builders);
    
    // get number of users
    users = $user.descendants();
    users = $list.setremove_all(users, strip);
    names += users;
    users = listlen(users);
    
    // get total number of players, users counts everybody, even admins
    total = users;
    
    // correct for backwards places like tCD where everybody is a programmer
    if ((users - ((admins + programmers) + builders)) < 0)
        users = 0;
    else
        users = users - ((admins + programmers) + builders);
    
    // break it down
    sender().tell("--- Player Breakdown ---");
    sender().tell(("There are currently " + total) + " total users.");
    sender().tell(("    " + admins) + " admin(s) *");
    sender().tell(("    " + programmers) + " programmer(s)");
    sender().tell(("    " + builders) + " builder(s)");
    sender().tell(("    " + users) + " user(s)");
    sender().tell("---");
    sender().tell("");
    players = (($sys.admins()).mmap('name)).prefix("*");
    players += ($list.setremove_all($list.setremove_all($user_db.user_dbrefs(), strip), $sys.admins())).mmap('name);
    sender().tell($list.columnize(players, 3));
};
new method
Replacing protected method $user.date_cmd()

protected method $user.date_cmd() {
    arg @args;
    var fmt, l, d, out, rtime;
    
    fmt = "%I:%M %p";
    l = "%25r ";
    rtime = $time.realm_time((.location()).realm(), 'with_season);
    out = [strfmt(l, "Server Time:") + ($time.format(fmt + " %A, %B %d %Y %Z"))];
    out += [strfmt(l, ((rtime[2]).name()) + " Time:") + (rtime[1])];
    return out;
};
new method
Replacing public method $user.connection_starting()

public method $user.connection_starting() {
    arg addr, port;
    var line, c;
    
    (> .perms(caller(), $connection) <);
    
    // shutoff our connection's timeout
    sender().set_timeout(0);
    
    // cleanup our connections list
    for c in (connections) {
        if (!valid(c))
            connections = setremove(connections, c);
    }
    connections = setadd(connections, sender());
    if ((connections.length()) == 1)
        (| .login(sender()) |);
    else
        (| .login_again(sender()) |);
    line = ("CONNECT " + tostr(sender() in connections)) + " (";
    line = (line + ((.parents())[1])) + "): ";
    line = (((line + this()) + " <") + (sender().address())) + "> ";
    (| $sys.log(line) |);
};
new method
Replacing public method $user.who_cmd()

public method $user.who_cmd() {
    arg cmdstr, com, args;
    var who, title, rest, opts, opt, a, all, prog, admin, short, sort, sortorder, s, x, place, results, sortopts, sortmeths;
    
    (> .perms(caller(), 'command) <);
    
    // just the basic who listing
    args = ((.get_setting("@who-options", $user)) + " ") + args;
    [args, opts] = (> $parse_lib.opt(args, "a?ll", "p?rogrammers", "a?dmins", "s?hort", "so?rt") <);
    for opt in (opts) {
        switch (opt[1]) {
            case "a?ll":
                all = opt[3];
            case "p?rogrammers":
                prog = opt[3];
            case "a?dmins":
                admin = opt[3];
            case "s?hort":
                short = opt[3];
            case "so?rt":
                sort = opt[4];
                sortorder = opt[3];
        }
    }
    args = (args.join()).explode_english_list();
    results = [];
    if (admin && (admin = ._who__admins([], all)))
        results += [admin];
    if (prog && (prog = ._who__programmers([], all)))
        results += [prog];
    if ((!prog) && ((!admin) && (!args))) {
        results += [[$user_db.connected(), "Connected Users"]];
    } else {
        for a in (args) {
            if ((a[1]) == "@") {
                if ((place = ._who__at_place(a.subrange(2))))
                    results += [place];
                args = args.setremove(a);
            }
        }
        if (args && (args = ._who__is(args)))
            results += [args];
    }
    who = [];
    for x in (results)
        who = union(who, x[1]);
    title = (results.slice(2)).to_english();
    rest = ((results.length()) == 1) ? ((results[1]).subrange(3)) : [];
    if (!who)
        return "Ack, nobody to list?";
    if (sort) {
        sortopts = ["idle", "connected", "name", "location", "place"];
        sortmeths = ['idle_seconds, 'connected_at, 'name, 'location, 'location];
        s = filter x in (sortopts) where (match_begin(x, sort));
        if ((s.length()) != 1) {
            .ptell("Unrecognized sort option: " + sort, #[['type, 'command]]);
            sort = 0;
        } else {
            sort = sortmeths[(s[1]) in sortopts];
        }
    }
    if (sort) {
        sort = who.mmap(sort);
        if (type(sort[1]) == 'objnum)
            sort = sort.mmap('name);
        who = who.sort(sort);
        if (!sortorder)
            who = who.reverse();
    }
    if (short)
        return ._who__short(who, title, @rest);
    else
        .ptell($code_lib.generate_listing(who, title, @rest), #[['type, 'command]]);
};
new method
Replacing public method $user.parse_line()

public method $user.parse_line() {
    arg line;
    var parse, c, r, rval;
    
    (> .perms(caller(), $connection) <);
    set_user();
    if (away)
        .tell("You are still marked as being away.");
    
    // if we dont set it, it'll act like normal
    rval = this();
    last_command_at = time();
    .set_last_command(line.trim());
    catch any {
        task_connections = task_connections.add(task_id(), sender());
        parse = parsers ? ((parsers[1]).parse(this(), line, @parsers.subrange(2), $null_parser)) : ['failed];
        switch (parse[1]) {
            case 'action:
                r = (| (parse[2]).action(@parse[3]) |);
                if (type(r) in ['list, 'frob, 'string])
                    .ptell(r, #[['type, 'parser], ['action, parse[3]]]);
                else
                    .tell(("Invalid registered action '" + (parse[3])) + "'");
            case 'error:
                .tell(parse[2]);
            case 'match, 'command:
                r = (> (parse[2]).(parse[3])(@parse.subrange(4)) <);
                if (type(r) in ['list, 'frob, 'string])
                    .ptell(r, #[['type, 'parser], ['command, parse[3]]]);
                else
                    rval = r;
            case 'failed:
                for c in (($place_lib.coordinate_shortcuts()).keys()) {
                    if (line.match_template(c)) {
                        .tell(("There is no exit " + line) + " here.");
                        r = 1;
                    }
                }
                if (!r)
                    .tell(("I don't understand " + (line.chop((.linelen()) - 22))) + ".");
            case 'ok:
                // do nothing, probably a null command
            default:
                .tell("Unusual response from the parser: " + toliteral(parse));
        }
    } with {
        if (error() == ~stop) {
            if ((traceback()[1])[2])
                .tell((traceback()[1])[2]);
        } else {
            .tell_traceback(traceback(), @parse);
        }
    }
    catch any
        task_connections = task_connections.del(task_id());
    return rval;
};
new method
Adding protected method $user._who__admins()

protected method $user._who__admins() {
    arg args, all;
    var out, admins, a, x, t;
    
    admins = [];
    if (args && (!all)) {
        for a in (args) {
            x = $user_db.search(a);
            if (!x)
                .tell(("I don't know who \"" + a) + "\" is.");
            else
                admins += [x];
        }
        t = (("Admin" + (admins.length())) == 1) ? "" : "s";
    } else if (all) {
        t = "All Admins";
        admins = $sys.admins();
    } else {
        t = "Connected Admins";
        for a in ($user_db.connected()) {
            if (a.has_ancestor($admin))
                admins += [a];
        }
    }
    if (!admins)
        return 0;
    return [admins, t];
};
new method
Adding protected method $user._who__is()

protected method $user._who__is() {
    arg people, @args;
    var person, p, who, x;
    
    who = [];
    if (type(people) == 'string)
        people = ($string.explode_english_list(people, @args)) || [];
    for p in (people) {
        catch any {
            person = $user_db.search(p);
        } with {
            switch (error()) {
                case ~ambig:
                    .tell(((("The name \"" + p) + "\" can match any of: ") + ($list.to_english(filter x in ($user_db.users()) where (x.match_begin(p))))) + ".");
                    continue;
                default:
                    // hack, look for robots..
                    catch any {
                        person = ($robot.children()).match_object(p);
                    } with {
                        .tell(("I don't know who \"" + p) + "\" is.");
                        continue;
                    }
            }
        }
        who += [person];
    }
    if (!who)
        return 0;
    return [who, ((who.length()) == 1) ? "User" : "Users"];
};
new method
Replacing protected method $user.password_cmd(): nooverride 

protected method $user.password_cmd(): nooverride  {
    arg cmdstr, com, args;
    var syn, c, curr, new, verify;
    
    (> .perms(caller(), 'command) <);
    syn = com + " [<old password> [<new password>]]";
    args = explode(args);
    c = .task_connection();
    if (!args) {
        while (!curr)
            curr = (> (.prompt("Current Password (@abort to abort): ")).trim() <);
    } else {
        curr = args[1];
    }
    if (!(.check_password(curr)))
        return "Invalid Password";
    if (listlen(args) < 2) {
        while (1) {
            while (!new)
                new = (> (.prompt("New Password (@abort to abort): ")).trim() <);
            while (!verify)
                verify = (> (.prompt("Retype New Password (@abort to abort): ")).trim() <);
            if (new == verify)
                break;
            .tell("Passwords do not match!");
            new = (verify = 0);
        }
    } else if (listlen(args) == 2) {
        new = args[2];
    } else {
        (> .tell_error(syn) <);
    }
    catch any
        .set_password(new);
    with
        (> .tell_error(syn, (traceback()[1])[2]) <);
    .tell("Password changed.");
};
new method
Replacing protected method $user.audit_cmd()

protected method $user.audit_cmd() {
    arg cmdstr, cmd, args;
    var who, obj, col, str, out, total, line, syntax, loc, size, full, s, o;
    
    (> .perms(caller(), 'command) <);
    o = (> $parse_lib.opt(args, "f?ull") <);
    args = (o[1]).join();
    full = (| "f?ull" in ((o[2]).slice(1)) |);
    if (full)
        full = ((o[2])[full])[3];
    who = (| .match_environment(args) |);
    if (!who) {
        who = (| $user_db.search(args) |);
        if (!who)
            return ("Unable to find \"" + args) + "\".";
    }
    if (full) {
        col = (.linelen()) / 2;
        out = [(((("Objects managed by " + (who.namef('ref))) + ":").pad(col)) + ("bytes".pad(-10))) + " Location"];
        for obj in (who.managed()) {
            if (!valid(obj)) {
                .tell(("  ** invalid object (" + toliteral(obj)) + ") **");
                continue;
            }
            line = ("  " + (obj.namef('xref))).pad(col);
            s = obj.size();
            size = s.to_english();
            line = (line + (size.pad(-(((size.length()) > 10) ? (size.length()) : 10)))) + " ";
            loc = (obj.has_ancestor($located)) ? (("[" + ((obj.location()).name())) + "]") : "";
            out += [(line + loc).pad(.linelen())];
            total += s;
        }
    } else {
        if ((who != this()) && (!(.is($admin))))
            return "Only admins can get quota usage information from other users.";
        out = [("Quota information on " + (who.namef('ref))) + ":"];
        for obj in (who.managed()) {
            if (valid(obj))
                total += obj.size();
        }
    }
    if ((who == this()) || (.is($admin))) {
        out += [("Total usage: " + ($integer.to_english(total))) + " bytes"];
        size = who.get_quota();
        line = ("Total quota: " + ($integer.to_english(size))) + " bytes";
        out += [line, ("Remaining:   " + ($integer.to_english(size - total))) + " bytes"];
    }
    if (!(who.quota_valid())) {
        if (who == this())
            out += ["*** You are over quota! ***"];
        else
            out += [("*** " + (who.name())) + " is over quota! ***"];
    }
    if (who.quota_exempt()) {
        if (who == this())
            out += ["*** You are exempt from quota! ***"];
        else
            out += [("*** " + (who.name())) + " is exempt from quota! ***"];
    }
    return out;
};
new method
Replacing public method $user.set_name()

public method $user.set_name() {
    arg new_name, @ignore;
    var old_name, part, sname;
    
    (> .perms(sender(), 'manager) <);
    
    // if $sys is calling this, we probably want to strip off
    // the user_ prefix...
    if (sender() == $sys)
        new_name = strsed(new_name, ("^" + ((parents()[1]).objname())) + "_", "");
    
    // so it doesnt bomb on .set_objname
    if ((> $user_db.valid_name(new_name) <))
        old_name = .name();
    catch any {
        (> pass(new_name, 'prop) <);
        if (new_name in (registered || []))
            .unregister_name(new_name);
        if (!(| $user_db.key_changed(old_name, new_name) |))
            $user_db.insert(new_name, this());
        if (old_name != new_name) {
            sname = new_name.strip();
            (> .set_objname(tosym("user_" + sname)) <);
        }
    } with {
        (| pass(old_name, 'prop) |);
        rethrow(error());
    }
};
new method
Replacing frob method $no_one.mail_name()

frob method $no_one.mail_name() {
    arg frob;
    
    if (valid(frob[1]))
        return (frob[1]).mail_name();
    return frob[1];
};
new method
Adding frob method $no_one.namef()

frob method $no_one.namef() {
    arg frob, @args;
    
    if (valid(frob[1]))
        return (frob[1]).namef(@args);
    return frob[1];
};
new method
Replacing frob method $no_one.name()

frob method $no_one.name() {
    arg frob, @args;
    
    if (valid(frob[1]))
        return (frob[1]).name();
    return frob[1];
};
add objvar
Adding objvar $player<$command_cache>,commands

object $player;
var $command_cache commands = 0;
add objvar
Adding objvar $player<$command_cache>,shortcuts

object $player;
var $command_cache shortcuts = 0;
add objvar
Adding objvar $builder<$command_cache>,commands

object $builder;
var $command_cache commands = 0;
update objvar
Updating objvar $builder<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[["@realm?s", [["@realm?s", "", "@realm?s", 'realms_cmd, #[]]]], ["@child?ren|@kids", [["@child?ren|@kids", "*", "@child?ren|@kids <object>", 'children_cmd, #[[1, ['object, []]]]]]], ["@par?ents", [["@par?ents", "*", "@par?ents <object>", 'parents_cmd, #[[1, ['object, []]]]]]], ["@build", [["@build", "*", "@build <any:-conf?igure>", 'build_cmd, #[[1, ['any_opt, ["conf?igure"]]]]]]], ["@attach", [["@attach", "* to *", "@attach <any> to <descendant of $place>", 'attach_cmd, #[[1, ['any, []]], [3, ['descendant, [$place]]]]]]], ["@destroy", [["@destroy", "*", "@destroy <list object>", 'destroy_cmd, #[[1, ['list, ['object, []]]]]]]], ["@dig", [["@dig", "*", "@dig <any>", 'dig_cmd, #[[1, ['any, []]]]]]], ["@teleport|@go", [["@teleport|@go", "*", "@teleport|@go <any>", 'teleport_cmd, #[[1, ['any, []]]]]]], ["@def-msg|@def-message", [["@def-msg|@def-message", "*", "@def-msg|@def-message <any>", 'define_msg_cmd, #[[1, ['any, []]]]]]], ["@undef-msg|@undef-message", [["@undef-msg|@undef-message", "*", "@undef-msg|@undef-message <any>", 'undefine_msg_cmd, #[[1, ['any, []]]]]]], ["@prob?lems|@pr|@bug?s", [["@prob?lems|@pr|@bug?s", "*", "@prob?lems|@pr|@bug?s <any>", 'problems_cmd, #[[1, ['any, []]]]]]], ["@mv|@move", [["@mv|@move", "*", "@mv|@move <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]]];
  new = #[["@realm?s", [["@realm?s", "", "@realm?s", 'realms_cmd, #[]]]], ["@child?ren|@kids", [["@child?ren|@kids", "*", "@child?ren|@kids <object>", 'children_cmd, #[[1, ['object, []]]]]]], ["@par?ents", [["@par?ents", "*", "@par?ents <object>", 'parents_cmd, #[[1, ['object, []]]]]]], ["@build", [["@build", "*", "@build <any:-conf?igure>", 'build_cmd, #[[1, ['any_opt, ["conf?igure"]]]]]]], ["@attach", [["@attach", "* to *", "@attach <any> to <descendant of $place>", 'attach_cmd, #[[1, ['any, []]], [3, ['descendant, [$place]]]]]]], ["@destroy", [["@destroy", "*", "@destroy <list object>", 'destroy_cmd, #[[1, ['list, ['object, []]]]]]]], ["@dig", [["@dig", "*", "@dig <any>", 'dig_cmd, #[[1, ['any, []]]]]]], ["@teleport|@go", [["@teleport|@go", "*", "@teleport|@go <any>", 'teleport_cmd, #[[1, ['any, []]]]]]], ["@def-msg|@def-message", [["@def-msg|@def-message", "*", "@def-msg|@def-message <any>", 'define_msg_cmd, #[[1, ['any, []]]]]]], ["@undef-msg|@undef-message", [["@undef-msg|@undef-message", "*", "@undef-msg|@undef-message <any>", 'undefine_msg_cmd, #[[1, ['any, []]]]]]], ["@mv|@move", [["@mv|@move", "*", "@mv|@move <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]], ["@action-request|@ar", [["@action-request|@ar", "*", "@action-request|@ar <any>", 'action_request_cmd, #[[1, ['any, []]]]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$builder<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $builder;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
add objvar
Adding objvar $builder<$command_cache>,shortcuts

object $builder;
var $command_cache shortcuts = 0;
old method
Deleting normal method $builder.format_messages()

object $builder;
eval {
  del_method('format_messages);
};
old method
Deleting normal method $builder._problem__fix()

object $builder;
eval {
  del_method('_problem__fix);
};
old method
Deleting normal method $builder._problem__dismiss()

object $builder;
eval {
  del_method('_problem__dismiss);
};
old method
Deleting normal method $builder._problem__interactive()

object $builder;
eval {
  del_method('_problem__interactive);
};
old method
Deleting normal method $builder._problem__claim()

object $builder;
eval {
  del_method('_problem__claim);
};
old method
Deleting normal method $builder._problem__mailmsg()

object $builder;
eval {
  del_method('_problem__mailmsg);
};
old method
Deleting normal method $builder._problem__get_group()

object $builder;
eval {
  del_method('_problem__get_group);
};
old method
Deleting normal method $builder._problem__comment()

object $builder;
eval {
  del_method('_problem__comment);
};
old method
Deleting normal method $builder._problem__iview()

object $builder;
eval {
  del_method('_problem__iview);
};
old method
Deleting normal method $builder._problem__ilist()

object $builder;
eval {
  del_method('_problem__ilist);
};
old method
Deleting normal method $builder._problem_listgrp()

object $builder;
eval {
  del_method('_problem_listgrp);
};
old method
Deleting normal method $builder.problems_cmd()

object $builder;
eval {
  del_method('problems_cmd);
};
old method
Deleting normal method $builder._problem__view()

object $builder;
eval {
  del_method('_problem__view);
};
old method
Deleting normal method $builder._problem__get_report()

object $builder;
eval {
  del_method('_problem__get_report);
};
old method
Deleting normal method $builder._problem__list()

object $builder;
eval {
  del_method('_problem__list);
};
new method
Adding protected method $builder._ar__get_request()

protected method $builder._ar__get_request() {
    arg args, cmd;
    var request, g, menu;
    
    if (!args)
        throw(~stop, ("No request specified with '" + cmd) + "'");
    [request, @args] = args;
    if ((request[1]) == "$") {
        catch any
            request = $object_lib.to_dbref(request);
        with
            throw(~stop, (traceback()[1])[2]);
        if ((!(request.is($action_request))) || (request == $action_request))
            throw(~stop, (request.namef('ref)) + " is not a Action Request.");
    } else {
        if ((request[1]) == "#")
            request = substr(request, 2);
        request = toint(request);
        if (request <= 0)
            throw(~stop, "Invalid request number #" + request);
        for g in ($argroup.children()) {
            if (dict_contains(g.requests(), request))
                return ((g.requests())[request])[1];
        }
        throw(~stop, "Unable to find action request #" + request);
    }
};
new method
Adding protected method $builder._ar__fix()

protected method $builder._ar__fix() {
    arg args, opts, request;
    var line, cmt, n;
    
    n = (request.group()).name();
    if (request.resolved_on())
        return (((n + " Action Request #") + (request.id())) + " has already been resolved by ") + ((request.resolved_by()).namef('ref));
    .tell(request.format());
    line = (> .prompt(("Mark " + n) + " Action Request as resolved? [yes] ") <);
    if ((line.is_boolean()) == 0)
        return "** Aborting.";
    .tell("** Enter any final remarks, or nothing for no remarks.");
    cmt = .read("** Enter \".\" to finish or \"@abort\" to abort.");
    if (type(cmt) != 'list)
        return [];
    request.resolve();
    .tell(("** " + n) + " Action Request has been marked as resolved.");
    if (cmt)
        request.add_comment(cmt);
    return ._ar__mailmsg(request, cmt);
};
new method
Adding protected method $builder._ar__get_group()

protected method $builder._ar__get_group() {
    arg args, opts;
    var group, groups, s, menu;
    
    groups = $argroup.children();
    if (opts) {
        if ("a?ll" in (opts.slice(1)))
            group = 'All;
        else if (!(group = (| groups.match_object((opts[1])[2]) |)))
            throw(~stop, ("Invalid AR Group '" + ((opts[1])[2])) + "'");
    } else {
        while (1) {
            menu = ["0=>ALL GROUPS"];
            for group in [1 .. listlen(groups)]
                menu += [(group + "=>") + ((groups[group]).name())];
            menu += ["X=>Exit"];
            s = .do_menu("AR Groups", "Select AR Group", @menu);
            if ((!s) || (s == "X"))
                return 0;
            if (s.is_numeric()) {
                if ((!(group = (| groups[toint(s)] |))) && (s == "0"))
                    group = 'All;
            }
            if (!group)
                .tell(["**", ("** Sorry, '" + s) + "' is not a valid group."]);
            else
                break;
        }
    }
    return group;
};
new method
Replacing protected method $builder.move_cmd()

protected method $builder.move_cmd() {
    arg cmdstr, cmd, args;
    var what, dest, loc, opts, src, fromto;
    
    (> .perms(caller(), 'command) <);
    [src, args, opts] = args;
    if (args && (type(args[1]) == 'string)) {
        if ((args[1]) == "to")
            args = delete(args, 1);
        if (!args)
            throw(~stop, "You must move to somewhere.");
        catch ~obj, ~namenf, ~ambig
            dest = $parse_lib.ref(join(args));
        with
            throw(~stop, (traceback()[1])[2]);
    } else {
        dest = args;
    }
    what = src[2];
    dest = dest[2];
    catch any {
        loc = what.location();
        fromto = ((" from " + ((| loc.name() |) || $nowhere)) + " to ") + (dest.name());
        (| what.tell(((("You are suddenly yanked" + fromto) + " by ") + (.name())) + ".") |);
        (> what.move_to(dest) <);
    
        // hook into messages eventually
        (| loc.announce((what.name()) + " suddenly disappears.") |);
        (| dest.announce((what.name()) + " suddenly appears.", what) |);
        return (("You move " + (what.name())) + fromto) + ".";
    } with {
        (| what.tell(("You feel as if " + (.name())) + " was incapable of moving you, you did not go anywhere.") |);
        return (traceback()[1])[2];
    }
};
new method
Adding protected method $builder._ar__view()

protected method $builder._ar__view() {
    arg args, opts, request;
    
    return request.format();
};
new method
Adding protected method $builder._ar__list()

protected method $builder._ar__list() {
    arg args, opts;
    var requests, w, all, r, g, list, group;
    
    group = (> ._ar__get_group(args, opts) <);
    if (!group)
        return "Goodbye.";
    if (group != 'All) {
        requests = filter r in (group.requests()) where (!((r[2])[2]));
        requests = #[[group, requests]];
        .tell(("** Un-Resolved " + (group.name())) + " Action Requests:");
        w = (.linelen()) - 20;
    } else {
        requests = #[];
        for g in (setremove($argroup.children(), $dismissed_problems)) {
            list = filter r in (g.requests()) where (!((r[2])[2]));
            if (list)
                requests = dict_add(requests, g, list);
        }
        all = 1;
        .tell("** ALL Un-Resolved Action Requests:");
        w = (.linelen()) - 34;
    }
    return ._ar__listgrp(requests, w, all);
};
new method
Adding protected method $builder._ar__iview()

protected method $builder._ar__iview() {
    arg pr;
    var str, msg;
    
    msg = "[RET] Return, [N]ext, [P]rev, [C]laim, [F]ix, [D]ismiss, [A]ppend";
    while (1) {
        .tell(pr.format());
        str = (> .prompt(msg) <);
        if ((!str) || match_template(str, "x|ex?it"))
            return 0;
        if (match_template(str, "n?ext"))
            return 'next;
        if (match_template(str, "p?revious"))
            return 'prev;
        if (match_template(str, "c?laim"))
            .tell(._ar__claim([], [], pr));
        else if (match_template(str, "f?ix|r?esolve"))
            .tell(._ar__fix([], [], pr));
        else if (match_template(str, "d?ismiss"))
            .tell(._ar__dismiss([], [], pr));
        else if (match_template(str, "a?ppend|cmt|com?ment"))
            .tell(._ar__comment([], [], pr));
    }
};
new method
Adding protected method $builder._ar__ilist()

protected method $builder._ar__ilist() {
    arg how;
    var requests, list, g, r, pr, list, keys, choice;
    
    while (1) {
        if (how == 'mine) {
            requests = #[];
            for g in (setremove($argroup.children(), $dismissed_problems)) {
                list = filter r in (g.requests()) where ((!((r[2])[2])) && (((r[2])[5]) == this()));
                if (list)
                    requests = dict_add(requests, g, list);
            }
            .tell("** Your Un-Resolved Action Requests:");
            list = ._ar__listgrp(requests, (.linelen()) - 32, 1);
        } else {
            list = ._ar__list([], []);
            if ((!list) || (list == "Goodbye."))
                return;
        }
        pr = (> .prompt("Select Action Request, or [RET] to exit") <);
        if ((!pr) || match_template(pr, "x|ex?it"))
            return;
        if ((!(pr.is_numeric())) || (!dict_contains(list, toint(pr)))) {
            .tell("Invalid Action Request");
        } else {
            pr = toint(pr);
            keys = dict_keys(list);
            while ((choice = ._ar__iview(list[pr]))) {
                if (choice == 'next) {
                    r = pr in keys;
                    if (r < listlen(keys)) {
                        pr = keys[r + 1];
                    } else {
                        .tell("No Next Action Request.");
                        break;
                    }
                } else {
                    r = pr in keys;
                    if (r != 1) {
                        pr = keys[r - 1];
                    } else {
                        .tell("No Previous Action Request.");
                        break;
                    }
                }
            }
        }
    }
};
new method
Adding protected method $builder.action_request_cmd()

protected method $builder.action_request_cmd() {
    arg cmdstr, cmd, args;
    var syn, opts, request, command;
    
    syn = ("Syntax: " + cmd) + " [+<ar group>] <cmt|list|view|claim|dismiss|fix> [addtl]";
    [args, opts] = (> $parse_lib.opt(args, "a?ll", "f?ull") <);
    if (!args)
        return ._ar__interactive();
    if ((listlen(args) > 1) && ((args[1]).is_numeric()))
        args = [args[2], args[1]] + sublist(args, 3);
    [command, @args] = args;
    if (match_template(command, "com?ment|cmt")) {
        request = (> ._ar__get_request(args, cmd + " comment") <);
        return (> ._ar__comment(sublist(args, 2), opts, request) <);
    } else if (match_template(command, "l?ist")) {
        return (> ._ar__list(args, opts) <);
    } else if (match_template(command, "v?iew")) {
        request = (> ._ar__get_request(args, cmd + " view") <);
        return (> ._ar__view(sublist(args, 2), opts, request) <);
    } else if (match_template(command, "cl?aim")) {
        request = (> ._ar__get_request(args, cmd + " claim") <);
        return (> ._ar__claim(sublist(args, 2), opts, request) <);
    } else if (match_template(command, "r?esolv|f?ix")) {
        request = (> ._ar__get_request(args, cmd + " fix") <);
        return (> ._ar__fix(sublist(args, 2), opts, request) <);
    } else if (match_template(command, "d?ismiss")) {
        request = (> ._ar__get_request(args, cmd + " dismiss") <);
        return (> ._ar__dismiss(sublist(args, 2), opts, request) <);
    } else {
        if ((!args) && (command.is_numeric())) {
            request = (> ._ar__get_request([command], cmd + " view") <);
            return (> ._ar__view([], opts, request) <);
        }
        return [syn, ("Unsupported command '" + command) + "'"];
    }
};
new method
Adding protected method $builder._ar__dismiss()

protected method $builder._ar__dismiss() {
    arg args, opts, request;
    var line, cmt, n, id;
    
    n = (request.group()).name();
    id = request.id();
    if ((request.group()) == $dismissed_problems)
        return ((n + " Action Request #") + id) + " has already been dismissed";
    .tell(request.format());
    line = (> .prompt(((("Dismiss " + n) + " Action Request #") + id) + "? [yes] ") <);
    if ((line.is_boolean()) == 0)
        return "** Aborting.";
    .tell("** Enter any remarks, or nothing for no remarks.");
    cmt = .read("** Enter \".\" to finish or \"@abort\" to abort.");
    if (type(cmt) != 'list)
        return;
    if (cmt)
        request.add_comment(cmt);
    request.change_group($dismissed_problems);
    return ("** " + n) + " Action Request has been marked as resolved.";
};
new method
Adding protected method $builder._ar__interactive()

protected method $builder._ar__interactive() {
    var choice, category, bug, list, line, menu;
    
    while (choice != 'exit) {
        choice = .do_menu("Action Requests", "", "1=>Scan unclaimed open requests", "2=>Scan your open requests", "X=>Exit", 'exit);
        switch (choice) {
            case "1":
                (> ._ar__ilist('unclaimed) <);
            case "2":
                (> ._ar__ilist('mine) <);
            case 'exit:
                return "Goodbye.";
        }
    }
};
new method
Adding protected method $builder._ar__listgrp()

protected method $builder._ar__listgrp() {
    arg requests, w, full;
    var group, request, r, id, date, summary, resolved, str, list, out;
    
    list = #[];
    out = [];
    for group in (dict_keys(requests)) {
        for request in (requests[group]) {
            id = request[1];
            [r, resolved, date, summary] = request[2];
            date = $time.format("%d-%h-%Y", date);
            if (full)
                str = strfmt("%4r: %11l %11l  %*e", id, group.name(), date, w, summary).trim('right);
            else
                str = strfmt("%4r: %13l  %*e", id, date, w, summary).trim('right);
            out += [str];
            list = dict_add(list, id, r);
        }
    }
    .tell(out);
    .tell(("--- " + listlen(dict_keys(list))) + " Total");
    return list;
};
new method
Adding private method $builder._ar__mailmsg()

private method $builder._ar__mailmsg() {
    arg request, msg;
    var u, recip, text, mail, id, fmt, c, cmts;
    
    u = request.submitted_by();
    id = request.id();
    if (valid(u) && (u.is($mail_list))) {
        text = (u.mail_name()) + " and *bugs";
        .tell("** Specify recipients for this comment, or 'none'");
        recip = (> .prompt(("** Mail comment to [" + text) + "] ") <);
        if (!recip)
            recip = text;
        if ((recip == "no") || (recip == "none"))
            return "** Not mailing.";
        recip = .parse_mail_recipient_list(recip);
        if (!recip)
            return "** No valid recipients.";
        mail = $mail_message.new_mail();
        mail.set_subject((("Comment on AR #" + id) + ": ") + (request.summary()));
        text = ["Reported By: " + (request.submitted_by())];
        text += ["Reported On: " + ($time.format("%d-%h-%Y", request.submitted_on()))];
        text += [""];
        text += ((request.text()).mmap('wrap_lines, 70, "> ", 1)).flatten();
        cmts = request.comments();
        msg = (cmts.last())[3];
        cmts = sublist(cmts, 1, listlen(cmts) - 1);
        for c in (cmts) {
            fmt = "On " + ($time.format("%d-%h-%Y ", c[1]));
            fmt += ((c[2]).namef('ref)) + " Comments:";
            text += ["", fmt] + (((c[3]).mmap('wrap_lines, 70, "> ", 1)).flatten());
        }
        text += [""] + msg;
        mail.set_text(text);
        catch any
            mail.send(@recip);
        with
            return (traceback()[1])[2];
        return "** Mail sent.";
    }
};
new method
Adding protected method $builder._ar__comment()

protected method $builder._ar__comment() {
    arg args, opts, request;
    var text, fmt, cmt, n, u, msg, id;
    
    n = (request.group()).name();
    id = request.id();
    .tell("** Commenting on Action Request #" + id);
    cmt = .read("** Enter \".\" to finish or \"@abort\" to abort.");
    if ((type(cmt) != 'list) || (!cmt))
        return "** No comments added.";
    request.add_comment(cmt);
    .tell((("** Comments added to " + n) + " AR #") + id);
    return ._ar__mailmsg(request, cmt);
};
new method
Replacing protected method $builder.build_query_realm()

protected method $builder.build_query_realm() {
    arg there;
    var line, realm, r, prompt;
    
    prompt = ((("What realm is " + (there.name())) + " in? [") + (((.location()).realm()).name())) + "] ";
    while (!realm) {
        line = (> .build_prompt(prompt, tostr((.location()).realm())) <);
        if (!line) {
            realm = (.location()).realm();
        } else if (line == "@realms") {
            r = ($place_lib.known_realms()).union($realm.descendants());
            .tell(["Realms:", ""] + ((r.mmap('name)).prefix("    ")));
        } else {
            realm = $place_lib.match_realm(line);
            if (!realm) {
                .tell(("Unknown realm \"" + line) + "\", try @realms.");
            } else if (!(realm.is($realm))) {
                .tell((realm.namef('ref)) + " is not a realm, try @realms.");
                realm = 0;
            }
        }
    }
    return realm;
};
new method
Adding protected method $builder._ar__claim()

protected method $builder._ar__claim() {
    arg args, opts, request;
    var n, id, s, cmt;
    
    n = (request.group()).name();
    id = request.id();
    if (request.claimed_on()) {
        .tell((((n + " Action Request #") + id) + " has already been claimed by ") + ((request.claimed_by()).namef('ref)));
        s = (> .prompt("Reclaim it in your name? [no] ") <);
        if ((!s) || ((s.is_boolean()) == 0))
            return "** Aborting.";
    }
    .tell(request.format());
    s = (> .prompt(("Claim this " + n) + " Action Request? [yes] ") <);
    if ((s.is_boolean()) == 0)
        return "** Aborting.";
    .tell("** Enter any remarks, or nothing for no remarks.");
    cmt = .read("** Enter \".\" to finish or \"@abort\" to abort claiming.");
    if (type(cmt) != 'list)
        return;
    if (cmt)
        request.add_comment(cmt);
    request.claim();
    return (("** You have claimed " + n) + " Action Request #") + id;
};
clear objvar
Clearing objvar $dmi_data_ui<$command_cache>,commands

object $dmi_data_ui;
old var $command_cache commands;
clear objvar
Clearing objvar $dmi_data_ui<$command_cache>,shortcuts

object $dmi_data_ui;
old var $command_cache shortcuts;
add objvar
Adding objvar $dmi_data_ui<$root>,credit

object $dmi_data_ui;
var $root credit = ["Bruce Mitchener, Jr <bruce@puremagic.com>"];
update objvar
Updating objvar $programmer<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[["@id", [["@id", "*", "@id <any>", 'id_cmd, #[[1, ['any, []]]]]]], ["@which", [["@which", "*", "@which <any>", 'which_cmd, #[[1, ['any, []]]]]]], ["@eval", [["@eval", "*", "@eval <any>", 'eval_cmd, #[[1, ['any, []]]]]]], ["@add-c?ommand|@ac", [["@add-c?ommand|@ac", "*", "@add-c?ommand|@ac <any>", 'add_command_cmd, #[[1, ['any, []]]]]]], ["@del-c?ommand|@dc", [["@del-c?ommand|@dc", "*", "@del-c?ommand|@dc <any>", 'del_command_cmd, #[[1, ['any, []]]]]]], ["@join", [["@join", "*", "@join <any>", 'join_cmd, #[[1, ['any, []]]]]]], ["@chpar?ents", [["@chpar?ents", "*", "@chpar?ents <any>", 'chparents_cmd, #[[1, ['any, []]]]]]], ["@add-s?hortcut|@as", [["@add-s?hortcut|@as", "*", "@add-s?hortcut|@as <any>", 'add_shortcut_cmd, #[[1, ['any, []]]]]]], ["@del-m?ethod|@delm?ethod|@dm", [["@del-m?ethod|@delm?ethod|@dm", "*", "@del-m?ethod|@delm?ethod|@dm <objref>", 'del_method_cmd, #[[1, ['objref, []]]]]]], ["@rehash", [["@rehash", "", "@rehash", 'rehash_cmd, #[]]]], ["@trace-method|@trace", [["@trace-method|@trace", "*", "@trace-method|@trace <objref>", 'trace_method_cmd, #[[1, ['objref, []]]]]]], ["@ledit", [["@ledit", "*", "@ledit <objref: +e?dited>", 'local_edit_cmd, #[[1, ['objref_opt, ["e?dited"]]]]]]], ["@program", [["@program", "*", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]]], ["@program", "* with *", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1> with <any>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]], [3, ['any, []]]]]], ["@del-v?ariable|@dv", [["@del-v?ariable|@dv", "*", "@del-v?ariable|@dv <objref>", 'del_var_cmd, #[[1, ['objref, []]]]]]], ["@show", [["@show", "*", "@show <objref: +c?hop>", 'show_cmd, #[[1, ['objref_opt, ["c?hop"]]]]]]], ["@del-s?hortcut|@ds", [["@del-s?hortcut|@ds", "*", "@del-s?hortcut|@ds <any>", 'del_shortcut_cmd, #[[1, ['any, []]]]]]], ["@add-p?arent|@ap", [["@add-p?arent|@ap", "*", "@add-p?arent|@ap <any>", 'add_parent_cmd, #[[1, ['any, []]]]]]], ["@del-p?arent|@dp", [["@del-p?arent|@dp", "*", "@del-p?arent|@dp <any>", 'del_parent_cmd, #[[1, ['any, []]]]]]], ["@grep", [["@grep", "*", "@grep <any:+d?escend +f?ull +l?ist +r?eplace-with=1>", 'grep_cmd, #[[1, ['any_opt, ["d?escend", "f?ull", "l?ist", "r?eplace-with"]]]]]]], ["@chmod|@mmod|@omod|@chflag?s", [["@chmod|@mmod|@omod|@chflag?s", "*", "@chmod|@mmod|@omod|@chflag?s <any>", 'chmod_cmd, #[[1, ['any, []]]]]]], ["@dump", [["@dump", "*", "@dump <any: +t?extdump +m?ethods +v?ariables +h?eader>", 'dump_cmd, #[[1, ['any_opt, ["t?extdump", "m?ethods", "v?ariables", "h?eader"]]]]]]], ["@list", [["@list", "*", "@list <objref: +n?umbers +t?extdump>", 'list_cmd, #[[1, ['objref_opt, ["n?umbers", "t?extdump"]]]]]]], ["@add-v?ariable|@av", [["@add-v?ariable|@av", "*", "@add-v?ariable|@av <any>", 'add_var_cmd, #[[1, ['any, []]]]]]], ["@hl?ist|@help-list", [["@hl?ist|@help-list", "*", "@hl?ist|@help-list <any>", 'help_list_cmd, #[[1, ['any, []]]]]]], ["@hw?rite|@help-write", [["@hw?rite|@help-write", "*", "@hw?rite|@help-write <any>", 'help_write_cmd, #[[1, ['any, []]]]]]], ["@spawn", [["@spawn", "*", "@spawn <any>", 'spawn_cmd, #[[1, ['any, []]]]]]], ["@ancestors", [["@ancestors", "*", "@ancestors <any>", 'ancestors_cmd, #[[1, ['any, []]]]]]], ["@nh?n|@new-help|@new-help-node", [["@nh?n|@new-help|@new-help-node", "*", "@nh?n|@new-help|@new-help-node <any:+n?amed=1 +o?bjname=1 +i?ndex=1>", 'new_help_node_cmd, #[[1, ['any_opt, ["n?amed", "o?bjname", "i?ndex"]]]]]]], ["@config-set?ting|@configure-set?ting", [["@config-set?ting|@configure-set?ting", "*", "@config-set?ting|@configure-set?ting <any>", 'configure_setting_cmd, #[[1, ['any, []]]]]]], ["@def-set?ting|@define-set?ting", [["@def-set?ting|@define-set?ting", "*", "@def-set?ting|@define-set?ting <any>", 'define_setting_cmd, #[[1, ['any, []]]]]]], ["@undef-set?ting|@undefine-set?ting", [["@undef-set?ting|@undefine-set?ting", "*", "@undef-set?ting|@undefine-set?ting <any>", 'undefine_setting_cmd, #[[1, ['any, []]]]]]], ["@descend?ants", [["@descend?ants", "*", "@descend?ants <objref:+a?ll +r?edundant +o?nly +n?ot>", 'descendants_cmd, #[[1, ['objref_opt, ["a?ll", "r?edundant", "o?nly", "n?ot"]]]]]]], ["@d?isplay", [["@d?isplay", "*", "@d?isplay <objref: +c?hop +g?enerations>", 'display_cmd, #[[1, ['objref_opt, ["c?hop", "g?enerations"]]]]]]], ["@cp|@copy", [["@cp|@copy", "*", "@cp|@copy <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]]];
  new = #[["@id", [["@id", "*", "@id <any>", 'id_cmd, #[[1, ['any, []]]]]]], ["@which", [["@which", "*", "@which <any>", 'which_cmd, #[[1, ['any, []]]]]]], ["@eval", [["@eval", "*", "@eval <any>", 'eval_cmd, #[[1, ['any, []]]]]]], ["@add-c?ommand|@ac", [["@add-c?ommand|@ac", "*", "@add-c?ommand|@ac <any>", 'add_command_cmd, #[[1, ['any, []]]]]]], ["@del-c?ommand|@dc", [["@del-c?ommand|@dc", "*", "@del-c?ommand|@dc <any>", 'del_command_cmd, #[[1, ['any, []]]]]]], ["@join", [["@join", "*", "@join <any>", 'join_cmd, #[[1, ['any, []]]]]]], ["@chpar?ents", [["@chpar?ents", "*", "@chpar?ents <any>", 'chparents_cmd, #[[1, ['any, []]]]]]], ["@add-s?hortcut|@as", [["@add-s?hortcut|@as", "*", "@add-s?hortcut|@as <any>", 'add_shortcut_cmd, #[[1, ['any, []]]]]]], ["@del-m?ethod|@delm?ethod|@dm", [["@del-m?ethod|@delm?ethod|@dm", "*", "@del-m?ethod|@delm?ethod|@dm <objref>", 'del_method_cmd, #[[1, ['objref, []]]]]]], ["@trace-method|@trace", [["@trace-method|@trace", "*", "@trace-method|@trace <objref>", 'trace_method_cmd, #[[1, ['objref, []]]]]]], ["@ledit", [["@ledit", "*", "@ledit <objref: +e?dited>", 'local_edit_cmd, #[[1, ['objref_opt, ["e?dited"]]]]]]], ["@program", [["@program", "*", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]]], ["@program", "* with *", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1> with <any>", 'program_cmd, #[[1, ['objref_opt, ["w?arnings", "e?dited", "a?ccess", "f?lags"]]]], [3, ['any, []]]]]], ["@del-v?ariable|@dv", [["@del-v?ariable|@dv", "*", "@del-v?ariable|@dv <objref>", 'del_var_cmd, #[[1, ['objref, []]]]]]], ["@show", [["@show", "*", "@show <objref: +c?hop>", 'show_cmd, #[[1, ['objref_opt, ["c?hop"]]]]]]], ["@del-s?hortcut|@ds", [["@del-s?hortcut|@ds", "*", "@del-s?hortcut|@ds <any>", 'del_shortcut_cmd, #[[1, ['any, []]]]]]], ["@add-p?arent|@ap", [["@add-p?arent|@ap", "*", "@add-p?arent|@ap <any>", 'add_parent_cmd, #[[1, ['any, []]]]]]], ["@del-p?arent|@dp", [["@del-p?arent|@dp", "*", "@del-p?arent|@dp <any>", 'del_parent_cmd, #[[1, ['any, []]]]]]], ["@grep", [["@grep", "*", "@grep <any:+d?escend +f?ull +l?ist +r?eplace-with=1>", 'grep_cmd, #[[1, ['any_opt, ["d?escend", "f?ull", "l?ist", "r?eplace-with"]]]]]]], ["@chmod|@mmod|@omod|@chflag?s", [["@chmod|@mmod|@omod|@chflag?s", "*", "@chmod|@mmod|@omod|@chflag?s <any>", 'chmod_cmd, #[[1, ['any, []]]]]]], ["@dump", [["@dump", "*", "@dump <any: +t?extdump +m?ethods +v?ariables +h?eader>", 'dump_cmd, #[[1, ['any_opt, ["t?extdump", "m?ethods", "v?ariables", "h?eader"]]]]]]], ["@list", [["@list", "*", "@list <objref: +n?umbers +t?extdump>", 'list_cmd, #[[1, ['objref_opt, ["n?umbers", "t?extdump"]]]]]]], ["@add-v?ariable|@av", [["@add-v?ariable|@av", "*", "@add-v?ariable|@av <any>", 'add_var_cmd, #[[1, ['any, []]]]]]], ["@hl?ist|@help-list", [["@hl?ist|@help-list", "*", "@hl?ist|@help-list <any>", 'help_list_cmd, #[[1, ['any, []]]]]]], ["@hw?rite|@help-write", [["@hw?rite|@help-write", "*", "@hw?rite|@help-write <any>", 'help_write_cmd, #[[1, ['any, []]]]]]], ["@spawn", [["@spawn", "*", "@spawn <any>", 'spawn_cmd, #[[1, ['any, []]]]]]], ["@ancestors", [["@ancestors", "*", "@ancestors <any>", 'ancestors_cmd, #[[1, ['any, []]]]]]], ["@nh?n|@new-help|@new-help-node", [["@nh?n|@new-help|@new-help-node", "*", "@nh?n|@new-help|@new-help-node <any:+n?amed=1 +o?bjname=1 +i?ndex=1>", 'new_help_node_cmd, #[[1, ['any_opt, ["n?amed", "o?bjname", "i?ndex"]]]]]]], ["@config-set?ting|@configure-set?ting", [["@config-set?ting|@configure-set?ting", "*", "@config-set?ting|@configure-set?ting <any>", 'configure_setting_cmd, #[[1, ['any, []]]]]]], ["@def-set?ting|@define-set?ting", [["@def-set?ting|@define-set?ting", "*", "@def-set?ting|@define-set?ting <any>", 'define_setting_cmd, #[[1, ['any, []]]]]]], ["@undef-set?ting|@undefine-set?ting", [["@undef-set?ting|@undefine-set?ting", "*", "@undef-set?ting|@undefine-set?ting <any>", 'undefine_setting_cmd, #[[1, ['any, []]]]]]], ["@descend?ants", [["@descend?ants", "*", "@descend?ants <objref:+a?ll +r?edundant +o?nly +n?ot>", 'descendants_cmd, #[[1, ['objref_opt, ["a?ll", "r?edundant", "o?nly", "n?ot"]]]]]]], ["@d?isplay", [["@d?isplay", "*", "@d?isplay <objref: +c?hop +g?enerations>", 'display_cmd, #[[1, ['objref_opt, ["c?hop", "g?enerations"]]]]]]], ["@cp|@copy", [["@cp|@copy", "*", "@cp|@copy <objref:+c?omment>", 'move_cmd, #[[1, ['objref_opt, ["c?omment"]]]]]]], ["@rehash", [["@rehash", "*", "@rehash <any:+r?aw +c?lient>", 'rehash_cmd, #[[1, ['any_opt, ["r?aw", "c?lient"]]]]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$programmer<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $programmer;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
old method
Deleting normal method $programmer.grep_full()

object $programmer;
eval {
  del_method('grep_full);
};
old method
Deleting normal method $programmer.grep_replace_method()

object $programmer;
eval {
  del_method('grep_replace_method);
};
old method
Deleting normal method $programmer.grep_list()

object $programmer;
eval {
  del_method('grep_list);
};
old method
Deleting normal method $programmer.grep_replace()

object $programmer;
eval {
  del_method('grep_replace);
};
old method
Deleting normal method $programmer._show_variables()

object $programmer;
eval {
  del_method('_show_variables);
};
old method
Deleting normal method $programmer.grep_brief()

object $programmer;
eval {
  del_method('grep_brief);
};
old method
Deleting normal method $programmer.create_cmd()

object $programmer;
eval {
  del_method('create_cmd);
};
old method
Deleting normal method $programmer._show_methods()

object $programmer;
eval {
  del_method('_show_methods);
};
new method
Adding protected method $programmer._grep__list()

protected method $programmer._grep__list() {
    arg regexp, objs;
    var obj, code, x, l, lr, what, loop, method, opt;
    
    opt = .get_setting("@program-options", $programmer);
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        for method in (obj.methods()) {
            code = obj.list_method(method);
            for l in (code) {
                if (match_regexp(l, regexp)) {
                    .tell(([$object_lib.format_method_header(obj, method, opt, obj.method_flags(method), obj.method_access(method))] + (code.prefix("  "))) + ["."]);
                    break;
                }
                refresh();
            }
            refresh();
        }
        refresh();
    }
    return "---";
};
new method
Replacing protected method $programmer.del_parent_cmd()

protected method $programmer.del_parent_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, parent;
    
    (> .perms(caller(), 'command) <);
    syn = cmd + " <parent> [from] <object>";
    args = args.explode();
    if ((listlen(args) > 2) && ((args[2]) == "from"))
        args = delete(args, 2);
    if (listlen(args) != 2)
        (> .tell_error(syn) <);
    if (!args)
        (> .tell_error(syn) <);
    parent = (> .match_env_nice(args[1]) <);
    obj = (> .match_env_nice(args[2]) <);
    catch any {
        (> obj.del_parent(parent) <);
        return ((("Deleted parent from " + (obj.namef('ref))) + ", parents: ") + ((obj.parents()).to_english())) + ".";
    } with {
        (> .tell_error("", (traceback()[1])[2]) <);
    }
};
new method
Replacing protected method $programmer.grep_cmd()

protected method $programmer.grep_cmd() {
    arg cmdstr, cmd, args;
    var more, regexp, from, syn, opts, d, f, l, r, rep, slice, objs, obj, out;
    
    (> .perms(caller(), 'command) <);
    [more, opts] = args;
    if ((more.length()) < 2)
        return ("=> Syntax: `" + cmd) + " [options] <regexp> <object> <object>..";
    regexp = more[1];
    more = more.subrange(2);
    
    // handle the options
    slice = opts.slice(1);
    if ((r = (| "r?eplace-with" in slice |))) {
        rep = (opts[r])[4];
        r = (opts[r])[3];
    }
    if ((d = (| "d?escend" in ((args[2]).slice(1)) |)))
        d = (opts[d])[3];
    if ((l = (| "l?ist" in ((args[2]).slice(1)) |)))
        l = (opts[l])[3];
    if ((f = (| "f?ull" in ((args[2]).slice(1)) |)))
        f = (opts[f])[3];
    
    // now we check for conflicting or incorrect options..
    if (d && (!(.is($admin))))
        return "Only administrators may use the +descend option, talk to one.";
    if (d && ((more.length()) > 1))
        return "+descend can only be used with a single object as the target.";
    if (r && (f || l))
        return "+replace-with option cannot be used with +full or +list.";
    if (f && l)
        return "+full cannot be used with +list.";
    
    // the pause() flushes so we can see the 'Searching for ..'
    // Do this now because .descendants() can lag
    .tell(("Searching for \"" + regexp) + "\"...");
    pause();
    
    // figure out our targets
    if (d) {
        obj = (> .match_env_nice(more[1]) <);
        objs = [obj, @obj.descendants()];
    } else {
        objs = [];
        for obj in (more)
            objs += [(> .match_env_nice(obj) <)];
    }
    
    // verify its a valid regexp
    catch ~regexp
        match_regexp("", regexp);
    with
        return "Invalid regular expression: " + ((traceback()[1])[2]);
    
    // call the right grep method
    if (r)
        return (> ._grep__replace(regexp, objs, rep) <);
    else if (l)
        return (> ._grep__list(regexp, objs) <);
    else if (f)
        return (> ._grep__full(regexp, objs) <);
    else
        return (> ._grep__brief(regexp, objs) <);
};
new method
Replacing protected method $programmer.descendants_cmd()

protected method $programmer.descendants_cmd() {
    arg cmdstr, cmd, args;
    var obj, max, line, opts, i, r, not, only, f;
    
    (> .perms(caller(), 'command) <);
    
    // parse args
    [obj, args, opts] = args;
    if ((obj[1]) != 'object)
        return "Object reference must simply be a dbref.";
    if ((obj[2]) != (obj[3]))
        .tell(("Ignoring specified definer " + (obj[2])) + ".");
    obj = obj[3];
    only = (not = []);
    max = 1;
    if ((i = "o?nly" in (opts.slice(1)))) {
        only = map f in ((((opts[i])[4]).split(" *, *")).nonzero()) to (f.to_symbol());
        opts = delete(opts, i);
    }
    if ((i = "n?ot" in (opts.slice(1)))) {
        not = map f in ((((opts[i])[4]).split(" *, *")).nonzero()) to (f.to_symbol());
        opts = delete(opts, i);
    }
    if ((i = "r?edundant" in (opts.slice(1)))) {
        r = (opts[i])[3];
        opts = delete(opts, i);
    }
    if ((i = "a?ll" in (opts.slice(1)))) {
        if ((opts[i])[3])
            max = 0;
        opts = delete(opts, i);
    }
    if (opts) {
        if ((max = find i in (opts) where ((i[2]).is_numeric()))) {
            max = toint((opts[max])[2]);
            if (max < 1)
                return "Maximum levels must be greater than zero.";
        }
    }
    
    // do it
    line = ("-- Descendants of " + obj) + " [";
    .tell((line + (((obj.parents()).mmap('objname)).to_english())) + "]");
    if (max) {
        line = (max + " level") + ((max > 1) ? "s" : "");
        max++;
    } else {
        line = "all levels";
    }
    if (r)
        line += ", redundant entries";
    .tell("-- " + line);
    if (only)
        .tell("-- only objects with flag(s): +" + (only.join(" AND +")));
    if (not)
        .tell("-- not objects with flag(s): +" + (not.join(" OR +")));
    return [obj.format_descendants("", #[], 0, max, only, not, r), "--"];
};
new method
Adding protected method $programmer._grep__replace()

protected method $programmer._grep__replace() {
    arg regexp, objs, replace;
    var obj, method;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.is_writable_by(this()))) {
            .tell(("You cannot write on " + obj) + ", skipping..");
            continue;
        }
        for method in (obj.methods()) {
            (> ._grep__replace_method(obj, method, regexp, replace) <);
            refresh();
        }
        refresh();
    }
    return "Done.";
};
new method
Replacing protected method $programmer.display_cmd()

protected method $programmer.display_cmd() {
    arg cmdstr, cmd, args;
    var opts, slice, what, match, i, chop, f, gen, def, obj, out;
    
    (> .perms(caller(), 'command) <);
    opts = args[3];
    args = args[1];
    chop = 1;
    slice = opts.slice(1);
    if ((i = "c?hop" in slice) && (!((opts[i])[3])))
        chop = 0;
    else
        chop = .linelen();
    def = args[3];
    if ((i = "g?enerations" in slice)) {
        gen = (opts[i])[4];
        if (gen.is_numeric())
            gen = ['generations, toint(gen)];
        else if (gen)
            gen = ['ancestors_descending, (> .match_env_nice(gen) <)];
        else
            gen = ['ancestry, def];
        def = 0;
    } else {
        gen = ['generations, 1];
    }
    what = [args[1]] + ((| args[5] |) ? [args[5]] : []);
    obj = args[2];
    if (type(obj) == 'frob)
        return ["The target object was a frob.  Please use @exam instead."];
    out = $object_lib.format_object(obj, chop);
    if (!(args[4]))
        f = .get_setting("match-default", $programmer);
    else
        f = args[4];
    match = .get_setting("match-with", $programmer);
    catch ~perm {
        if ('method in what)
            out += ._display_methods(obj, obj.list_methods(gen, def, f, match), chop, f);
    } with {
        out += ["  ** No permission to list methods **"];
    }
    catch ~perm {
        if ('variable in what)
            out += ._display_variables(obj, obj.variable_info(gen, def, f, match), chop, f);
    } with {
        out += ["  ** No permission to show variables **"];
    }
    return out + ["---"];
};
new method
Adding protected method $programmer._grep__brief()

protected method $programmer._grep__brief() {
    arg regexp, objs;
    var obj, method, out, x, l, line, lines, code;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        out = [];
        for method in (obj.methods()) {
            code = obj.list_method(method);
            lines = [];
            for x in [1 .. listlen(code)] {
                l = code[x];
                if (match_regexp(l, regexp))
                    lines += [x];
                refresh();
            }
            if (lines)
                out += [(((obj + ".") + method) + "(): ") + (lines.to_english())];
            refresh();
        }
        if (out)
            .tell(out);
        refresh();
    }
    return "---";
};
new method
Replacing public method $programmer.eval_prefix()

public method $programmer.eval_prefix() {
    return dict_union(#[["me", ("me = " + this()) + ";"], ["here", ("here = " + (.location())) + ";"]], eval_prefix || #[]);
};
new method
Adding protected method $programmer._grep__replace_method()

protected method $programmer._grep__replace_method() {
    arg obj, method, regexp, replace;
    var old_code, code, x, l, lr, errs, what;
    
    old_code = (code = obj.list_method(method));
    for x in [1 .. listlen(code)] {
        l = code[x];
        if (!match_regexp(l, regexp))
            continue;
        lr = strsed(l, regexp, replace, "g");
        .tell([((((("Change " + obj) + ".") + method) + "() line ") + x) + " from:", "  " + l, "to:", "  " + lr]);
        what = (> .prompt("? (yes, no, abort, abort-all) [yes] ") <);
        if ((!what) || (what in ["yes", "y"])) {
            code = replace(code, x, lr);
        } else if (what == "abort") {
            .tell("Aborting method ..");
            return;
        } else if (what == "abort-all") {
            throw(~stop, "Aborting grep replace");
        } else if (!(what in ["no", "n"])) {
            .tell(("Unknown command '" + what) + "', assuming 'no'.");
        }
        refresh();
    }
    if ((old_code != code) && (errs = obj.add_method(code, method)))
        .tell(((([((("Error in compilation of updated method " + obj) + ".") + method) + "():"] + (errs.prefix("  "))) + ["-- Method code: "]) + (code.prefix("  "))) + ["--"]);
};
new method
Adding protected method $programmer._show__methods()

protected method $programmer._show__methods() {
    arg obj, f, match, chop;
    var methods, types, m, t, out;
    
    types = #[];
    for m in (obj.methods()) {
        if (tostr(m).(match)(f) != 0)
            types = types.add_elem(obj.method_access(m), ((("." + m) + "(") + ((obj.method_info(m))[1])) + ")");
    }
    
    // hard-listing the types guarantee's their order
    out = [];
    for t in (['root, 'driver, 'public, 'protected, 'private, 'frob]) {
        if (!(types.contains(t)))
            continue;
        out += [(((tostr(t).capitalize()) + " methods matching \"") + f) + "\":"];
        for m in (types[t])
            out += ["  " + m];
    }
    return out;
};
new method
Replacing public method $programmer.parse_methodcmd_options()

public method $programmer.parse_methodcmd_options() {
    arg syntax, args, @more;
    var o, opt, opts, out, r, l;
    
    [(o ?= []), (opts ?= [])] = more;
    o += [["pub?lic"], ["r?oot"], ["dr?iver"], ["pri?vate"], ["pro?tected"], ["no?override"], ["s?yncronized"], ["l?ocked"], ["na?tive"]];
    opts = dict_union(#[['exists, 0], ['ignore, 0], ['mflags, []], ['mstate, 'public], ['error, 0]], opts);
    args = $parse_lib.getopt(args, o);
    if (!(args[1])) {
        out = [];
        for opt in (o)
            out += ["  +|-" + (opt[1])];
        (> .tell_error(syntax, ["Valid options:"] + (out.lcolumnize())) <);
    }
    r = (| $parse_lib.ref((args[1]).join()) |);
    if (!r) {
        opts = opts.add('error, "Invalid <object>.<method> reference.");
        opts = opts.add('ignore, 1);
    }
    if (!((r[4]).valid_ident())) {
        opts = opts.add('error, (((r[2]) + ".") + tostr(r[4])) + "() is not a valid method reference.");
        opts = opts.add('ignore, 1);
    }
    r = replace(r, 4, tosym(r[4]));
    if ((r[2]) && (!((r[2]).is_writable_by(this())))) {
        opts = opts.add('error, ("You cannot program " + (r[2])) + ".");
        opts = opts.add('ignore, 1);
    }
    if ((| (r[2]).find_method(r[4]) |) == (r[2])) {
        opts = opts.add('mflags, (r[2]).method_flags(r[4]));
        opts = opts.add('mstate, (r[2]).method_access(r[4]));
        opts = opts.add('exists, 1);
    }
    opts = opts.add('object, r[2]);
    opts = opts.add('method, r[4]);
    for opt in (args[2]) {
        switch (opt[1]) {
            case "pub?lic", "r?oot", "dr?iver", "pri?vate", "pro?tected":
                opts = opts.add('mstate, (opt[1]).to_symbol());
            case "no?override", "s?yncronized":
                opts = opts.add('mflags, (opts['mflags]).setadd((opt[1]).to_symbol()));
            case "l?ocked":
                .tell("You cannot set the locked flag on a method.");
            case "n?ative":
                .tell("You cannot set the native flag on a method.");
            default:
                if (!(opt[1])) {
                    .tell(("Unknown option: \"" + (opt[2])) + "\"");
                    .tell("Valid options: " + ((o.slice(1)).to_english()));
                    continue;
                }
                opts = opts.add((opt[1]).to_symbol(), [opt[3], opt[4]]);
        }
    }
    return opts;
};
new method
Replacing protected method $programmer.managed_cmd()

protected method $programmer.managed_cmd() {
    arg cmdstr, cmd, args;
    var manager, managed, obj, out, len;
    
    (> .perms(caller(), 'command) <);
    if (!args)
        args = ".";
    manager = (| .match_environment(args) |);
    if (!manager) {
        manager = (| $user_db.search(args) |);
        if (!manager)
            return ("Unable to find \"" + args) + "\".";
    }
    managed = manager.managed();
    if (!managed)
        return (manager.namef('ref)) + " does not manage any objects.";
    out = [(manager.namef('ref)) + " manages:"];
    len = (.linelen()) / 2;
    for obj in (managed) {
        if (!valid(obj)) {
            .tell(("  ** invalid object (" + obj) + ") **");
            continue;
        }
        out += [(("  " + ((obj.namef('xref)).pad(len))) + " ") + ($object_lib.see_perms(obj, ["", ""]))];
    }
    return out + ["---"];
};
new method
Replacing protected method $programmer.list_cmd()

protected method $programmer.list_cmd() {
    arg cmdstr, cmd, args;
    var i, pattern, ref, methods, s, def, method, opts, str, m, d, out, type;
    
    (> .perms(caller(), 'command) <);
    if ((opts = .get_setting("@list-options", $programmer))) {
        opts = (> $parse_lib.opt(opts, "n?umbers", "t?extdump") <);
        opts = union(args[3], opts[2]);
    } else {
        opts = args[3];
    }
    if ((i = (| "n?umbers" in (opts.slice(1)) |)) && ((opts[i])[3]))
        type = 'numbered;
    else if ((i = (| "t?extdump" in (opts.slice(1)) |)) && ((opts[i])[3]))
        type = 'textdump;
    else
        type = 'normal;
    ref = args[1];
    if ((ref[1]) == 'variable)
        return ((("The reference " + (ref[3])) + ",") + ((ref[4]) || "")) + " is not for a method.";
    if ((ref[1]) == 'object)
        return ("The reference " + (ref[3])) + " is not for a method.";
    if (!((ref[2]).has_flag('methods)))
        return .tell(("You don't have permission to find methods on " + (ref[2])) + ".");
    if (!((ref[2]).has_flag('code)))
        return .tell(("You don't have permission to list methods on " + (ref[2])) + ".");
    def = (| (ref[2]).find_method(tosym(ref[4])) |);
    if (def) {
        pattern = ref[4];
        methods = [tosym(ref[4])];
    } else {
        if (ref[4])
            pattern = ref[4];
        else
            pattern = .get_setting("match-default", $programmer);
        def = ref[3];
        m = .get_setting("match-with", $programmer);
        methods = [];
        for method in (def.methods()) {
            if (tostr(method).(m)(pattern) != 0)
                methods += [method];
        }
        if (!methods)
            return .tell((("No method found matching " + def) + ".") + pattern);
    }
    cmd = .get_setting("@program-options", $programmer);
    out = [];
    for method in (methods) {
        .ptell(.format_method(def, method, type, cmd), #[]);
        pause();
    }
};
new method
Adding protected method $programmer._show__variables()

protected method $programmer._show__variables() {
    arg obj, f, match, chop;
    var parent, out, v, line, len;
    
    out = [];
    len = .linelen();
    for parent in (obj.data()) {
        if (valid(parent[1])) {
            out += [(((parent[1]) + " variables matching \"") + f) + "\":"];
            if ((parent[1]).has_flag('variables, this())) {
                for v in (parent[2]) {
                    if (tostr(v[1]).(match)(f) == 0)
                        continue;
                    line = (("  " + (v[1])) + ": ") + toliteral(v[2]);
                    if (chop)
                        line = line.chop(len);
                    out += [line];
                }
            } else {
                out += ["  ** Permission Denied **"];
            }
        } else {
            out += [($object_lib.get_name(parent[1])) + " Variables:"];
            for v in (parent[2]) {
                if (tostr(v[1]).(match)(f) == 0)
                    continue;
                line = (("  " + (v[1])) + ": ") + toliteral(v[2]);
                if (chop)
                    line = line.chop(len);
                out += [line];
            }
        }
        refresh();
    }
    return out;
};
new method
Replacing protected method $programmer.eval_cmd()

protected method $programmer.eval_cmd() {
    arg cmdstr, com, str;
    var result, adjust, vars, v, evalp, times, line, reg, obj, definer, ref, debug;
    
    (> .perms(caller(), 'command) <);
    evalp = .eval_prefix();
    vars = (evalp.keys()).join(", ");
    v = (evalp.values()).join();
    
    // clean it up
    str = strsed(str, "^;*", "");
    
    // perform escape substitution
    if (str && ((str[1]) == "|"))
        str = substr(str, 2);
    else
        str = (> .eval_subs(str) <);
    
    // check for debug flags
    if ((reg = regexp(str, "^(trace|debug|profile|ops|opcodes) *;*(.*)$"))) {
        [debug, str] = reg;
        if (debug == "ops")
            debug = "opcodes";
        debug = tosym(debug);
    } else {
        debug = 0;
    }
    
    // who are we evaluating as
    if ((reg = regexp(str, "^ *as +([^; ]+)"))) {
        catch ~objnf, ~namenf, ~ambig
            ref = $parse_lib.ref(reg[1]);
        with
            (> .tell_error("", (traceback()[1])[2]) <);
        obj = ref[2];
        definer = ref[3];
        str = strsed(str, "^ *as +([^; ]+)[ ;]+", "");
        if ((!(definer.is_writable_by(this()))) || (!(obj.is_writable_by(this()))))
            return ("You do not have permission to evaluate on " + (reg[1])) + ".";
        if (!(obj.is(definer)))
            return (obj + " isn't a child of ") + definer;
    } else {
        obj = (definer = this());
    }
    
    // are we just adjusting our offset?
    if (!str) {
        result = (> .evaluate(((("var " + vars) + ";") + v) + "return (> 1 <);", obj, definer, 'no_offset) <);
        result = replace(result[1], 1, ((result[1])[1]) - 1);
        if (eval_offset)
            line = strfmt("adjusted by %s ticks and %s.%6{0}r seconds.", (eval_offset[1]) - (result[1]), (eval_offset[2]) - (result[2]), abs((eval_offset[3]) - (result[3])));
        else
            line = strfmt("set to %s ticks and %s.%6{0}r seconds.", @result);
        eval_offset = result;
        return "Eval offset " + line;
    }
    
    // format it
    if (match_begin(str, "var") && (reg = regexp(str, "var ([^;]+)"))) {
        str = strsed(str, "var ([^;]+);", "");
        str = ((((("var " + vars) + ", ") + (reg.join(","))) + ";") + v) + str;
    } else if ("return" in str) {
        str = ((("var " + vars) + ";") + v) + str;
    } else {
        str = strsed(str, " *;* *$", "");
        str = ((((("var " + vars) + ";") + v) + "return (> ") + str) + " <);";
    }
    if (debug) {
        result = (> .evaluate(str, obj, definer, debug) <);
        debug = (| result[3] |);
    } else {
        result = (> .evaluate(str, obj, definer, debug) <);
    }
    [times, result] = result;
    
    // Display the errors, or the result.
    if ((result[1]) == 'errors) {
        .tell(result[2]);
    } else if ((result[1]) == 'traceback) {
        .tell((result[2]).fmt_tb());
        line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]);
        if (times[2])
            line += (" (" + ((times[1]) / (times[2]))) + " ticks per second)";
        return line + " ]";
    } else {
        if (type(result[2]) == 'objnum)
            .tell("=> " + ((| (result[2]).namef('xref) |) || (result[2])));
        else
            .tell("=> " + toliteral(result[2]));
        if (debug)
            .tell(debug);
        line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]);
        if (times[2])
            line += (" (" + ((times[1]) / (times[2]))) + " ticks per second)";
        return line + " ]";
    }
};
new method
Adding protected method $programmer._grep__full()

protected method $programmer._grep__full() {
    arg regexp, objs;
    var obj, method, out, x, l, code;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        out = [];
        for method in (obj.methods()) {
            code = obj.list_method(method);
            for x in [1 .. listlen(code)] {
                l = code[x];
                if (match_regexp(l, regexp))
                    out += [(((((obj + ".") + method) + "() line ") + x) + ": ") + l];
                refresh();
            }
            refresh();
        }
        if (out)
            .tell(out);
        refresh();
    }
    return "---";
};
new method
Replacing protected method $programmer.add_var_cmd()

protected method $programmer.add_var_cmd() {
    arg cmdstr, cmd, args;
    var ref, value, syn;
    
    (> .perms(caller(), 'command) <);
    syn = "@av <object>,<variable>[=<value>]";
    if (!args)
        (> .tell_error(syn, "Invalid obj,variable reference.") <);
    catch any
        ref = (> $parse_lib.ref(args.word(1)) <);
    with
        (> .tell_error(syn, (traceback()[1])[2]) <);
    if (((ref[1]) != 'variable) || (!(ref[4])))
        (> .tell_error(syn, "Invalid obj,variable reference.") <);
    if (" " in args) {
        args = substr(args, (" " in args) + 1);
        if (args && ((args[1]) == "="))
            args = substr(args, (" " in args) + 1);
        if (args) {
            value = .eval([("return " + args) + ";"]);
            if ((value[1]) == 'errors)
                (> .tell_error(syn, ("Unable to parse value \"" + args) + "\".") <);
            value = value[2];
        } else {
            value = 0;
        }
    } else {
        value = 0;
    }
    catch any {
        (> (ref[3]).add_var(tosym(ref[4]), value) <);
    } with {
        if (error() in [~varexists, ~symbol])
            return (traceback()[1])[2];
        rethrow(error());
    }
    return ((((("Object variable " + (ref[3])) + ",") + (ref[4])) + " added with value ") + value) + ".";
};
new method
Replacing protected method $programmer.show_cmd()

protected method $programmer.show_cmd() {
    arg cmdstr, com, args;
    var show, match, i, chop, f, obj, out;
    
    (> .perms(caller(), 'command) <);
    if (((args[1])[1]) == 'object)
        show = ['method, 'variable];
    else if ((args[1])[5])
        show = [(args[1])[1], (args[1])[5]];
    else
        show = [(args[1])[1]];
    if ((i = "c?hop" in ((args[3]).slice(1))))
        chop = ((args[3])[i])[3];
    else
        chop = 1;
    if ((args[1])[4])
        f = (args[1])[4];
    else
        f = .get_setting("match-default", $programmer);
    match = .get_setting("match-with", $programmer);
    obj = (args[1])[3];
    if (type(obj) == 'frob)
        return ["The target object was a frob.  Please use @exam instead."];
    .tell([((("Object:  " + obj) + " [") + ((obj.size()).to_english())) + " bytes]", "Parents: " + ((obj.parents()).join(", "))]);
    if ('method in show) {
        if (!(obj.has_flag('methods, this())))
            .tell("  ** No permission to list methods **");
        else
            .tell(._show__methods(obj, f, match, chop));
    }
    if ('variable in show) {
        if (!(obj.has_flag('variables, this())))
            .tell("  ** No permission to show variables **");
        else
            .tell(._show__variables(obj, f, match, chop));
    }
    .tell("---");
};
update objvar
Updating objvar $admin<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[["@del-t?ask|@kill", [["@del-t?ask|@kill", "*", "@del-t?ask|@kill <any>", 'del_task_cmd, #[[1, ['any, []]]]]]], ["@backup", [["@backup", "", "@backup", 'backup_cmd, #[]]]], ["@shutdown", [["@shutdown", "*", "@shutdown <any>", 'shutdown_cmd, #[[1, ['any, []]]]]]], ["@mojo", [["@mojo", "*", "@mojo <any>", 'mojo_cmd, #[[1, ['any, []]]]]]], ["@adjust|@promote", [["@adjust|@promote", "* to *", "@adjust|@promote <user> to <any>", 'adjust_cmd, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@new-password|@newpw?d", [["@new-password|@newpw?d", "*", "@new-password|@newpw?d <user>", 'new_password_cmd, #[[1, ['user, []]]]]]], ["@task?s", [["@task?s", "*", "@task?s <any>", 'tasks_cmd, #[[1, ['any, []]]]]]], ["@core", [["@core", "*", "@core <list object>", 'core_cmd, #[[1, ['list, ['object, []]]]]]]], ["@rehash-all", [["@rehash-all", "*", "@rehash-all <any:-p?urge>", 'rehash_all_cmd, #[[1, ['any_opt, ["p?urge"]]]]]]], ["@reap", [["@reap", "*", "@reap <any>", 'reap_cmd, #[[1, ['any, []]]]]]], ["@quota", [["@quota", "* to *", "@quota <object> to <any:+e?xempt>", 'quota_cmd, #[[1, ['object, []]], [3, ['any_opt, ["e?xempt"]]]]]]], ["@kick", [["@kick", "*", "@kick <any>", 'kick_cmd, #[[1, ['any, []]]]]]], ["@chman?age", [["@chman?age", "*", "@chman?age <any>", 'chmanage_cmd, #[[1, ['any, []]]]]]], ["@player-breakdown|@pb", [["@player-breakdown|@pb", "", "@player-breakdown|@pb", 'player_breakdown_cmd, #[]]]]];
  new = #[["@del-t?ask|@kill", [["@del-t?ask|@kill", "*", "@del-t?ask|@kill <any>", 'del_task_cmd, #[[1, ['any, []]]]]]], ["@backup", [["@backup", "", "@backup", 'backup_cmd, #[]]]], ["@shutdown", [["@shutdown", "*", "@shutdown <any>", 'shutdown_cmd, #[[1, ['any, []]]]]]], ["@mojo", [["@mojo", "*", "@mojo <any>", 'mojo_cmd, #[[1, ['any, []]]]]]], ["@adjust|@promote", [["@adjust|@promote", "* to *", "@adjust|@promote <user> to <any>", 'adjust_cmd, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@new-password|@newpw?d", [["@new-password|@newpw?d", "*", "@new-password|@newpw?d <user>", 'new_password_cmd, #[[1, ['user, []]]]]]], ["@task?s", [["@task?s", "*", "@task?s <any>", 'tasks_cmd, #[[1, ['any, []]]]]]], ["@core", [["@core", "*", "@core <list object>", 'core_cmd, #[[1, ['list, ['object, []]]]]]]], ["@rehash-all", [["@rehash-all", "*", "@rehash-all <any:-p?urge>", 'rehash_all_cmd, #[[1, ['any_opt, ["p?urge"]]]]]]], ["@reap", [["@reap", "*", "@reap <any>", 'reap_cmd, #[[1, ['any, []]]]]]], ["@quota", [["@quota", "* to *", "@quota <object> to <any:+e?xempt>", 'quota_cmd, #[[1, ['object, []]], [3, ['any_opt, ["e?xempt"]]]]]]], ["@kick", [["@kick", "*", "@kick <any>", 'kick_cmd, #[[1, ['any, []]]]]]], ["@chman?age", [["@chman?age", "*", "@chman?age <any>", 'chmanage_cmd, #[[1, ['any, []]]]]]], ["@scour", [["@scour", "*", "@scour <any>", 'scour_cmd, #[[1, ['any, []]]]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$admin<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $admin;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
old method
Deleting normal method $admin.player_breakdown_cmd()

object $admin;
eval {
  del_method('player_breakdown_cmd);
};
old method
Deleting normal method $admin.reap_list()

object $admin;
eval {
  del_method('reap_list);
};
old method
Deleting normal method $admin.reap_mail()

object $admin;
eval {
  del_method('reap_mail);
};
old method
Deleting normal method $admin.reap_user()

object $admin;
eval {
  del_method('reap_user);
};
new method
Adding public method $admin.scour_cmd()

public method $admin.scour_cmd() {
    arg cmdstr, cmd, line;
    var allopts, opts, parse, comp, neg, match, list, start, end, obj, pos, found, out, i, x, y;
    
    // command requires mojo for full search, so check it
    (> .check_mojo() <);
    
    // check to see if arguments have been provided
    if (!line)
        return .tell("Syntax: @scour <scope> [{comparison}] [range] [options]");
    
    // determine the scope of the search: method, variable, or setting
    if ((parse = line.regexp("\.([a-zA-Z0-9_]+)\((.*)\)")))
        parse = (| ['method, ".", (parse[1]).to_symbol(), fromliteral(("[" + (parse[2])) + "]")] |);
    else if ((parse = line.regexp(",([a-zA-Z0-9_]+)")))
        parse = (| ['variable, ",", (parse[1]).to_symbol()] |);
    else if ((parse = line.regexp(":([a-zA-Z0-9-]+)")))
        parse = (| ['setting, ":", parse[1]] |);
    else
        return .tell("Scope parse failed.");
    
    // if provided, find the basis of comparison
    refresh();
    comp = line.regexp("{(.+)}");
    if (comp) {
        comp = comp[1];
    
        //    if (line[line.index("{") - 1] == "!")
        if ((line[stridx(line, "{") - 1]) == "!")
            neg = 1;
    }
    
    // parse options and determine the objects to be scoured
    refresh();
    allopts = ["d?escend", "m?atch"];
    opts = ($parse_lib.opt(line, @allopts))[2];
    catch ~namenf {
        if ((pos = "d?escend" in (opts.slice(1)))) {
            start = $object_lib.to_dbref(((opts[pos])[4]).strip("'"));
            list = [start, @start.descendants()];
        } else if ((| ([start, end] = line.regexp("([^ .]+) ?\.\. ?([^ .]+)")) |)) {
            [start, end] = map i in ([start, end]) to ($object_lib.to_dbref(i));
            list = map i in [toint(start) .. toint(end)] to (refresh() && toobjnum(i));
            list = filter i in (list) where (refresh() && valid(i));
        } else {
            return .tell("You must specify a range of objects or an object from which to descend.");
        }
    } with {
        return .tell((traceback()[1])[2]);
    }
    if ((pos = "m?atch" in (opts.slice(1)))) {
        match = map i in ((allopts = ["r?egexp", "t?emplate", "e?quals"])) to (((opts[pos])[4]).match_template(i));
        if (match[1])
            match = 'regexp;
        else if (match[2])
            match = 'match_template;
        else if (match[3])
            match = 'equals;
        else
            return .tell((((opts[pos])[4]) + " is not a valid matching type: ") + (allopts.to_english()));
    }
    
    // defaults
    refresh();
    match ?= 'regexp;
    
    // scours the database and makes comparisons
    .tell(["Beginning analysis...", "".pad(79, "-")]);
    for obj in (list) {
        refresh();
        catch any {
            switch (parse[1]) {
                case 'method:
                    i = toliteral(obj.(parse[3])(@parse[4]));
                    if (comp) {
                        if (neg ? i.(match)(comp) : (!i.(match)(comp)))
                            continue;
                    }
                    found = 1;
                    .tell([tostr(obj), "  %20e  %55e".format((parse[2]) + tostr(parse[3]), i)]);
                case 'variable:
                    out = [];
                    for x in (obj.data()) {
                        refresh();
                        if (valid(x[1]) && ((parse[3]) in (((obj.data())[x[1]]).keys()))) {
                            i = toliteral(((obj.data())[x[1]])[parse[3]]);
                            if (comp) {
                                if (neg ? i.(match)(comp) : (!i.(match)(comp)))
                                    continue;
                            }
                            out += [("  <" + (x[1])) + ">", "    %20e  %50e".format((parse[2]) + tostr(parse[3]), i)];
                        }
                    }
                    if (!out)
                        continue;
                    found = 1;
                    .tell([tostr(obj), @out]);
                case 'setting:
                    if ((parse[3]) in ((pos = obj.all_defined_settings()).keys())) {
                        i = toliteral(obj.get_setting(parse[3], pos[parse[3]]));
                        if (comp) {
                            if (neg ? i.(match)(comp) : (!i.(match)(comp)))
                                continue;
                        }
                        found = 1;
                        .tell([tostr(obj), "  %20e  %55e".format((parse[2]) + (parse[3]), i)]);
                    }
                    continue;
            }
        } with {
            continue;
        }
    }
    if (!found)
        .tell("No matches found.");
    .tell(["".pad(79, "-"), "Finished."]);
    
    // $#Created: 22 Jul 98 20:09 $kirnamat
};
new method
Adding private method $admin._reap__user()

private method $admin._reap__user() {
    arg str;
    var user, ans, managed, obj, reapq, nuke, name, keep;
    
    user = (| $user_db.search(str) |);
    if (!user) {
        catch any
            user = $object_lib.to_dbref(str);
        with
            return ("Unable to find user " + str) + ".";
    }
    if (!(> $parse_lib.ask(("Reap " + (user.namef('ref))) + "? [no] ") <))
        return "Aborting reap.";
    managed = setremove(user.managed(), user);
    nuke = (keep = []);
    reapq = ["", ("Reap this object managed by " + (user.namef('ref))) + "? [yes] "];
    for obj in (managed) {
        .tell("");
        .tell($object_lib.format_object(obj, 0));
        if ((> $parse_lib.ask(reapq, "(yes|y)", "yes") <))
            nuke = setadd(nuke, obj);
        else
            keep = setadd(keep, obj);
    }
    if (nuke) {
        .tell(["WRT TST Object", "--- --- ------"]);
        for obj in (nuke)
            .tell(strfmt("%3r %3r %s", listlen(obj.writers('literal)), listlen(obj.trusted('literal)), obj.namef('ref)));
        .tell("");
        if ((> $parse_lib.ask("Destroy these objects? [yes] ", "(yes|y)", "yes") <)) {
            for obj in (nuke) {
                // must have been nuked already
                if (!valid(obj))
                    next;
                name = obj.namef('ref);
                catch any {
                    obj.destroy();
                } with {
                    .tell("--- While Destroying " + name);
                    .tell_traceback(traceback());
                }
            }
        }
    }
    for obj in (keep)
        .tell((("Changed Manager for " + (obj.namef('ref))) + " to ") + ($reaper.namef('ref)));
    if (!(> $parse_lib.ask(("Destroy " + (user.namef('ref))) + "? ") <))
        return "Not destroying " + (user.namef('ref));
    name = user.namef('ref);
    catch any {
        user.destroy();
    } with {
        .tell("--- While Destroying " + name);
        .tell_traceback(traceback());
    }
    return ("Done reaping " + name) + ".";
};
new method
Replacing protected method $admin.rehash_all_cmd()

protected method $admin.rehash_all_cmd() {
    arg cmdstr, cmd, args;
    var purge, o, objs, list;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    .tell("Rebuilding all caches..");
    pause();
    pause();
    
    // go atomic, we do not want confused users trying to run commands that
    // do not exist...
    $sys.atomic(1);
    
    // purge everything
    if ((o = (| "p?urge" in ((args[2]).slice(1)) |)))
        purge = ((args[2])[0])[3];
    else
        purge = 1;
    if (purge) {
        .tell("Purging caches..");
        for o in ($command_cache.descendants()) {
            (| o.purge_cache() |);
            refresh();
        }
    }
    
    // rehash non-general caches
    list = ($command_cache.children()).setremove($user_interfaces);
    list = ((list.mmap('descendants)).flatten()).compress();
    .tell(("Rehashing " + listlen(list)) + " general caches.");
    for o in (list) {
        if (!(o.is_general_cache())) {
            (| o.rehash_cache() |);
            refresh();
        }
    }
    $remote_cache.rehash_cache();
    
    // re-init user clients
    objs = (| $user_db.connected() |) || [this()];
    list = hash o in (objs) to ([(| o.location() |) || $void, 1]);
    for o in (objs + dict_keys(list)) {
        .tell("Initializing " + (o.namef('ref)));
        o.cache_client_init();
        refresh();
    }
    
    // ok, good...
    $sys.atomic(0);
    return "Done...";
};
new method
Replacing protected method $admin.reap_cmd()

protected method $admin.reap_cmd() {
    arg cmdstr, cmd, args;
    var opts, thresh, i;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    [args, opts] = (> $parse_lib.opt(args, "t?ime", "m?ail") <);
    args = args.join();
    if ((i = "t?ime" in (opts.slice(1)))) {
        catch any
            thresh = $time.from_english((opts[i])[4]);
        with
            return (traceback()[1])[2];
    }
    if ("m?ail" in (opts.slice(1)))
        return ._reap__mail(args, thresh || (86400 * 7));
    if (args)
        return (> ._reap__user(args) <);
    else
        return (> ._reap__list(thresh || ((86400 * 30) * 3)) <);
};
new method
Adding private method $admin._reap__list()

private method $admin._reap__list() {
    arg thresh;
    var t, reap, u, tl, m, v, n, last;
    
    t = time();
    reap = [];
    .tell([("--- Reap Possibilities (Not connected for " + ($time.to_english(thresh))) + ")", strfmt("E %21L %3l %10l %10l %10l %l", "User", "MNG", "Created", "Notified", "Last On", "Idle"), strfmt("- %21L %3l %10l %10l %10l %l", "----", "---", "-------", "-------", "-------", "----")]);
    for u in ($user.descendants()) {
        if ((u.connected()) || ((u.has_flag('core)) || (u.is($admin))))
            continue;
        tl = (last = abs(u.connected_at()));
        if ((tl + thresh) > t)
            continue;
        m = "";
        tl = t - tl;
        if (tl / 31449600) {
            v = tl / 31449600;
            m = (v + " yr") + ((v > 1) ? "s" : "");
            tl = tl % 31449600;
        }
        if (tl / 2592000) {
            v = tl / 2592000;
            m += (((m ? " " : "") + v) + " mnth") + ((v > 1) ? "s" : "");
            tl = tl % 2592000;
        }
        if (tl / 604800) {
            v = tl / 604800;
            m += (((m ? " " : "") + v) + " wk") + ((v > 1) ? "s" : "");
        }
        if (!m)
            m = "newborn";
        if (u._reap__notified())
            n = $time.format("%e-%b-%y", u._reap__notified());
        else
            n = "";
        reap += [[last, strfmt("%s %21L %3l %10l %10l %10l %l", ((u.get_setting("rl-email", $user_info))[2]) ? " " : "!", u.name(), listlen(u.managed()), $time.format("%e-%b-%y", u.created_on()), n, $time.format("%e-%b-%y", last), m)]];
    }
    .tell(((reap.sort()).slice(2)).reverse());
    return "---";
};
new method
Adding private method $admin._reap__mail()

private method $admin._reap__mail() {
    arg str, interval;
    var email, msg, subj, ps, po, user;
    
    user = (| $user_db.search(str) |);
    if (!user) {
        catch any
            user = $object_lib.to_dbref(str);
        with
            return ("Unable to find user " + str) + ".";
    }
    email = user.user_info("email");
    ps = (user.gender()).pronoun('ps);
    po = (user.gender()).pronoun('po);
    subj = ("[" + ($motd.server_name())) + "] IMMINENT USER REAPING";
    msg = (((((((((("Your user account " + (user.namef('ref))) + " on ") + ($motd.server_name())) + " is slated for reaping, possibly due to inactivity.  If you do not connect within ") + ($time.to_english(interval))) + " ") + ps) + " and all objects managed by ") + po) + " will be destroyed.  This is an automatic message sent to the supplied email address.  If this message is in error simply discard it.").wrap_lines(75);
    .tell("---");
    .tell("To: " + email);
    .tell("Subject: " + subj);
    .tell("");
    .tell(msg);
    .tell("---");
    if (!(> $parse_lib.ask("Send this email message? [yes] ", "(yes|y)", "yes") <))
        return "Message not sent.";
    catch any {
        $smtp.sendmail('admin, email, subj, msg);
    } with {
        .tell_traceback(traceback());
        return "** Unable to send message";
    }
    user.set_reap_notified(time());
    return "Message sent.";
};
update objvar
Updating objvar $introtut_mailbox<$root>,settings

public method $root.__upgrade_set_var() {
  var old, new;

  old = #[["closable", 1], ["closed", 0]];
  new = #[["closable", 1], ["closed", 1]];
  catch any {
  dblog("__upgrade_handle_var(1, settings)");
      settings = .__upgrade_handle_var(1, "$introtut_mailbox<$root>,settings", old, settings, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $introtut_mailbox;

eval {
  .__upgrade_set_var();
};

object $root;
eval {
  del_method('__upgrade_set_var);
};

// old public method $root.__upgrade_set_var();
new method
Replacing public method $trash.did_arrive()

public method $trash.did_arrive() {
    arg mover, place;
    var msg;
    
    (> pass(place) <);
    (| (items = items.add(sender(), time())) |);
};
add objvar
Adding objvar $realm_settings<$root>,credit

object $realm_settings;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
update objvar
Updating objvar $place<$root>,flags

object $place;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core, 'general_cache];
update objvar
Updating objvar $place<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[];
  new = #[["fribble", [["fribble", "*", "fribble <any>", 'fribble_cmd, #[[1, ['any, []]]]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$place<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $place;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
new method
Replacing public method $place.will_arrive()

public method $place.will_arrive() {
    arg mover, old_place;
    
    (> pass(mover, old_place) <);
    if (restrict_entry && ((!(mover.is($path))) && ((mover != $housekeeper) && ((!(.trusts(mover))) && ((| (mover.location()) != this() |) && (!(restrict_entry.try(mover))))))))
        throw(~locked, ((((.name()).capitalize()) + " is locked to ") + (restrict_entry.lock_name('place))) + ".");
};
new method
Replacing public method $place.will_attach()

public method $place.will_attach() {
    arg type, @by_whom;
    
    [(by_whom ?= sender())] = by_whom;
    if ((.realm()).is_buildable_by(by_whom))
        return 1;
    if ((| .trusts(by_whom) |))
        return 1;
    if (.get_setting("public-home", $place))
        return 1;
    throw(~perm, "Place is not publicly extendable.");
};
update objvar
Updating objvar $the_pit<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[];
  new = #[["zibble", [["zibble", "*", "zibble <any>", 'foo_cmd, #[[1, ['any, []]]]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$the_pit<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $the_pit;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
add objvar
Adding objvar $tutorial<$command_cache>,commands

object $tutorial;
var $command_cache commands = 0;
add objvar
Adding objvar $tutorial<$command_cache>,shortcuts

object $tutorial;
var $command_cache shortcuts = 0;
add objvar
Adding objvar $introtut_speaking<$event_handler>,hooked

object $introtut_speaking;
var $event_handler hooked = #[];
add objvar
Adding objvar $introtut_nonverbal<$event_handler>,hooked

object $introtut_nonverbal;
var $event_handler hooked = #[];
add objvar
Adding objvar $introtut_look<$event_handler>,hooked

object $introtut_look;
var $event_handler hooked = #[];
add objvar
Adding objvar $introtut_gender<$event_handler>,hooked

object $introtut_gender;
var $event_handler hooked = #[];
add objvar
Adding objvar $introtut_env<$event_handler>,hooked

object $introtut_env;
var $event_handler hooked = #[];
add objvar
Adding objvar $introtut_moving<$event_handler>,hooked

object $introtut_moving;
var $event_handler hooked = #[];
add objvar
Adding objvar $introtut_help_short<$event_handler>,hooked

object $introtut_help_short;
var $event_handler hooked = #[];
add objvar
Adding objvar $introtut_help_nav<$event_handler>,hooked

object $introtut_help_nav;
var $event_handler hooked = #[];
update objvar
Updating objvar $realm<$root>,flags

object $realm;
var $root flags = ['methods, 'code, 'variables, 'core, 'fertile];
add objvar
Adding objvar $realm<$root>,credit

object $realm;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
new method
Adding public method $realm.is_buildable_by()

public method $realm.is_buildable_by() {
    arg whom;
    
    if (.trusts(whom))
        return 1;
    else if (this() == definer())
        return 0;
    else
        return (parents()[1]).is_buildable_by(whom);
};
add objvar
Adding objvar $mail_postmaster<$mail_list>,last_received_on

object $mail_postmaster;
var $mail_list last_received_on = 0;
update objvar
Updating objvar $antisocial<$foundation>,msgs

object $antisocial;
var $foundation msgs = #[["ice", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pours a bucket of ice water over ", <$generator, ["who", [], [], 'gen_who]>, "'s head."], #[]]>], ["actor", <$ctext_frob, [["You pour a bucket of ice water over ", <$generator, ["who", [], [], 'gen_who]>, "'s head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pours a bucket of ice water over your head."], #[]]>]]], ["eye", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " eyes ", <$generator, ["who", [], [], 'gen_who]>, " warily."], #[]]>], ["actor", <$ctext_frob, [["You eye ", <$generator, ["who", [], [], 'gen_who]>, " warily."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " eyes you warily."], #[]]>]]], ["pat", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pats ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["actor", <$ctext_frob, [["You pat ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pats you onna head."], #[]]>]]], ["pummel", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pummels ", <$generator, ["who", [], [], 'gen_who]>, " into a milky white substance."], #[]]>], ["actor", <$ctext_frob, [["You pummel ", <$generator, ["who", [], [], 'gen_who]>, " into a milky white substance."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pummels you into a milky white substance. ouch."], #[]]>]]], ["prod", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " prods ", <$generator, ["who", [], [], 'gen_who]>, " with a cowpoke."], #[]]>], ["actor", <$ctext_frob, [["You prod ", <$generator, ["who", [], [], 'gen_who]>, " with a cowpoke."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " prods you with a cowpoke. ouch."], #[]]>]]], ["kick", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " kicks ", <$generator, ["who", [], [], 'gen_who]>, " firmly in the kiester."], #[]]>], ["actor", <$ctext_frob, [["You kick ", <$generator, ["who", [], [], 'gen_who]>, " firmly in the kiester."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " kicks you firmly in the kiester."], #[]]>]]], ["hug", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bear hugs ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You bear hug ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bear hugs you. oif."], #[]]>]]], ["beat", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["actor", <$ctext_frob, [["You pull out a stick and beat the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats you repeatedly."], #[]]>]]], ["hit", #[["general", <$ctext_frob, [["Boldly, ", <$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["actor", <$ctext_frob, [["Boldly, you pull out a stick and beat the ", <$generator, ["who", [], [], 'gen_who]>, " repeatedly."], #[]]>], ["who", <$ctext_frob, [["Boldly, ", <$generator, ["actor", [], [], 'gen_actor]>, " pulls out a stick and beats you repeatedly. oif."], #[]]>]]], ["peer", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " peers suspiciously at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You peer suspiciously at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " peers suspiciously at you."], #[]]>]]], ["bite", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " BITES ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You BITE ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " BITES you."], #[]]>]]], ["nip", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " nips at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["actor", <$ctext_frob, [["You nip at ", <$generator, ["who", [], [], 'gen_who]>, "."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " nips at you."], #[]]>]]], ["poke", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " firmly jabs ", <$generator, ["pro", [["actor", 1]], ["pp"], 'gen_pro]>, " index finger into ", <$generator, ["who", [], [], 'gen_who]>, "'s ribs."], #[]]>], ["actor", <$ctext_frob, [["You jab your index finger firmly into ", <$generator, ["who", [], [], 'gen_who]>, "'s ribs."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " firmly jabs ", <$generator, ["pro", [["actor", 1]], ["pp"], 'gen_pro]>, " index finger into your ribs. oif."], #[]]>]]], ["bonk", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " maliciously bonks ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["actor", <$ctext_frob, [["You maliciously bonk ", <$generator, ["who", [], [], 'gen_who]>, " onna head."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " maliciously bonks you onna head. oif."], #[]]>]]], ["fart", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " farts in ", <$generator, ["who", [], [], 'gen_who]>, "'s general direction."], #[]]>], ["actor", <$ctext_frob, [["You fart in ", <$generator, ["who", [], [], 'gen_who]>, "'s general direction."], #[]]>], ["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " farts in your general direction."], #[]]>]]], ["bounce", #[["who", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " bounces towards you obnoxiously!"], #[]]>], ["general", <$ctext_frob, [["You bounce obnoxiously towards ", <$generator, ["who", [], [], 'gen_who]>, "!"], #[]]>]]]];
update objvar
Updating objvar $antisocial<$has_commands>,local

public method $has_commands.__upgrade_set_var() {
  var old, new;

  old = #[["ice", [["ice", "*", "ice <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["eye", [["eye", "*", "eye <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["fart", [["fart", "*", "fart <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["kick", [["kick", "*", "kick <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pat", [["pat", "*", "pat <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pummel", [["pummel", "*", "pummel <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["poke", [["poke", "*", "poke <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["prod", [["prod", "*", "prod <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bonk", [["bonk", "*", "bonk <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hug", [["hug", "*", "hug <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hit", [["hit", "*", "hit <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["peer", [["peer", "*", "peer <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bite", [["bite", "*", "bite <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["nip", [["nip", "*", "nip <object>", 'anti_cmd, #[[1, ['object, []]]]]]]];
  new = #[["ice", [["ice", "*", "ice <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["eye", [["eye", "*", "eye <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["fart", [["fart", "*", "fart <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["kick", [["kick", "*", "kick <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pat", [["pat", "*", "pat <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pummel", [["pummel", "*", "pummel <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["poke", [["poke", "*", "poke <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["prod", [["prod", "*", "prod <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bonk", [["bonk", "*", "bonk <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hug", [["hug", "*", "hug <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["hit", [["hit", "*", "hit <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["peer", [["peer", "*", "peer <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bite", [["bite", "*", "bite <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["nip", [["nip", "*", "nip <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bounce", [["bounce", "*", "bounce <object>", 'anti_cmd, #[[1, ['object, []]]]]]]];
  catch any {
  dblog("__upgrade_handle_var(1, local)");
      local = .__upgrade_handle_var(1, "$antisocial<$has_commands>,local", old, local, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $antisocial;

eval {
  .__upgrade_set_var();
};

object $has_commands;
eval {
  del_method('__upgrade_set_var);
};

// old public method $has_commands.__upgrade_set_var();
update objvar
Updating objvar $antisocial<$foundation>,defined_msgs

object $antisocial;
var $foundation defined_msgs = #[["ice", #[['branches, ["general", "actor", "who"]]]], ["eye", #[['branches, ["general", "actor", "who"]]]], ["pat", #[['branches, ["general", "actor", "who"]]]], ["pummel", #[['branches, ["general", "actor", "who"]]]], ["prod", #[['branches, ["general", "actor", "who"]]]], ["kick", #[['branches, ["general", "actor", "who"]]]], ["hug", #[['branches, ["general", "actor", "who"]]]], ["beat", #[['branches, ["general", "actor", "who"]]]], ["hit", #[['branches, ["general", "actor", "who"]]]], ["peer", #[['branches, ["general", "actor", "who"]]]], ["bite", #[['branches, ["general", "actor", "who"]]]], ["nip", #[['branches, ["general", "actor", "who"]]]], ["poke", #[['branches, ["general", "actor", "who"]]]], ["bonk", #[['branches, ["general", "actor", "who"]]]], ["fart", #[['branches, ["general", "actor", "who"]]]], ["bounce", #[['branches, ["general", "actor", "who"]]]]];
clear objvar
Clearing objvar $settings_ui<$command_cache>,commands

object $settings_ui;
old var $command_cache commands;
clear objvar
Clearing objvar $settings_ui<$command_cache>,shortcuts

object $settings_ui;
old var $command_cache shortcuts;
update objvar
Updating objvar $smtp_connection<$root>,flags

object $smtp_connection;
var $root flags = ['core, 'variables, 'methods, 'code];
new method
Replacing public method $smtp.get_email_address()

public method $smtp.get_email_address() {
    arg type;
    var email, r, host;
    
    if (type(type) == 'objnum)
        (| (type = type.name()) |);
    if (type(type) != 'string)
        type = tostr(type);
    return .format_email_address((| .parse_recipient(type) |) || $mail_admin);
};
update objvar
Updating objvar $login_daemon<$root>,defined_settings

public method $root.__upgrade_set_var() {
  var old, new;

  old = #[["creation-disabled-msg", #[]], ["creation-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
  new = #[["creation-disabled-msg", #[]], ["creation-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["guests-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["guests-disabled-msg", #[]]];
  catch any {
  dblog("__upgrade_handle_var(3, defined_settings)");
      defined_settings = .__upgrade_handle_var(3, "$login_daemon<$root>,defined_settings", old, defined_settings, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $login_daemon;

eval {
  .__upgrade_set_var();
};

object $root;
eval {
  del_method('__upgrade_set_var);
};

// old public method $root.__upgrade_set_var();
update objvar
Updating objvar $login_daemon<$root>,settings

public method $root.__upgrade_set_var() {
  var old, new;

  old = #[["creation-disabled-msg", "Sorry, character creation is disabled."], ["creation-allowed", 1]];
  new = #[["creation-disabled-msg", "Sorry, character creation is disabled."], ["creation-allowed", 1], ["guests-allowed", 1], ["guests-disabled-msg", "Sorry, guests are disabled."]];
  catch any {
  dblog("__upgrade_handle_var(1, settings)");
      settings = .__upgrade_handle_var(1, "$login_daemon<$root>,settings", old, settings, new);
  } with {
      dblog("ERROR: " + traceback()[1][2]);
  }
};

object $login_daemon;

eval {
  .__upgrade_set_var();
};

object $root;
eval {
  del_method('__upgrade_set_var);
};

// old public method $root.__upgrade_set_var();
update objvar
Updating objvar $smtp_daemon<$smtp_daemon>,msg_id

object $smtp_daemon;
var $smtp_daemon msg_id = 352;
new method
Replacing frob method $thing_frob.match_name()

frob method $thing_frob.match_name() {
    arg this, str;
    var t, m;
    
    if (!str)
        return 0;
    if ((m = match_begin((this['name])[2], str)))
        return 1;
    if (this.contains('name_templates)) {
        for t in (this['name_templates]) {
            if ((m = match_template(str, t)))
                return 1;
        }
    }
    return 0;
};
new method
Replacing frob method $wearable_frob.discard()

frob method $wearable_frob.discard() {
    arg data;
    
    if (!(data['worn]))
        pass(data);
    if (data['worn])
        (data['worn]).shed((<this(), data>));
};
update objvar
Updating objvar $lock_frob<$lock_frob>,lock_types

object $lock_frob;
var $lock_frob lock_types = [["inside", $inside_lock_frob], ["indirect", $indirect_lock_frob], ["owner", #-1692], ["carry", $carry_lock_frob], ["parent", $parent_lock_frob]];
add objvar
Adding objvar $trie<$root>,credit

object $trie;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
new method
Replacing public method $trie.to_dict()

public method $trie.to_dict() {
    arg trie, @prefix;
    var n, i, dict;
    
    // This function will only convert single-valued tries (such as were
    // probably obtained from dictionaries
    [(prefix ?= "")] = prefix;
    dict = (trie[1]) ? #[[prefix + ((trie[1])[1]), (trie[1])[2]]] : #[];
    if (trie[2]) {
        for i in [1 .. (trie[2]).length()]
            dict = dict_union(dict, .to_dict(trie[2 + i], prefix + ((trie[2])[i])));
        refresh();
    }
    return dict;
};
new method
Replacing public method $ctext_frob.append()

public method $ctext_frob.append() {
    arg this, new, @br;
    var data, tmp, vars;
    
    data = this[1];
    vars = this[2];
    if (br) {
        switch (br[1]) {
            case "p":
                data += [(<$format, ["p", [], [], 'do_p]>)];
            case "br":
                data += [(<$format, ["br", [], [], 'do_br]>)];
            default:
                data += [$format.new_tag(br[1], [], [])];
        }
    }
    if (type(new) == 'list) {
        data += new;
    } else if ((type(new) == 'frob) && (class(new) == $ctext_frob)) {
        data += new._ctext();
        vars = dict_union(vars, new.vars());
    } else {
        data += [new];
    }
    return (<this(), [data, vars]>);
};
new method
Replacing public method $ctext_frob.uncompile()

public method $ctext_frob.uncompile() {
    arg this;
    var vars;
    
    vars = this[2];
    if (!(| vars['uncompiler] |))
        vars = dict_add(vars, 'uncompiler, $uncompiler);
    vars = dict_union(vars, (vars['uncompiler]).init());
    return ((vars['uncompiler])._eval_ctext(this[1], vars))[1];
};
new method
Replacing public method $ctext_frob.set_vars()

public method $ctext_frob.set_vars() {
    arg this, new;
    var vars, key;
    
    return (<this(), [this[1], dict_union(this[2], new)]>);
    vars = this[2];
    for key in (new.keys())
        vars = dict_add(vars, key, new[key]);
    return (<this(), [this[1], vars]>);
};
new method
Replacing public method $ctext_frob.eval_ctext()

public method $ctext_frob.eval_ctext() {
    arg this;
    var data, vars;
    
    vars = this[2];
    vars = dict_add(vars, 'time, 'pre);
    if (!(| vars['sender] |))
        vars = dict_add(vars, 'sender, sender());
    if (!(| vars['evaluator] |))
        vars = dict_add(vars, 'evaluator, $bs_eval);
    vars = dict_union(vars, (vars['evaluator]).init());
    return .new_with(@(vars['evaluator])._eval_ctext(this[1], vars));
};
new method
Replacing public method $ctext_frob.format()

public method $ctext_frob.format() {
    arg this;
    var vars;
    
    vars = this[2];
    vars = dict_add(vars, 'time, 'post);
    if (!(| vars['receiver] |))
        vars = dict_add(vars, 'receiver, sender());
    if (!(| vars['evaluator] |))
        vars = dict_add(vars, 'evaluator, $bs_eval);
    if (!(| vars['formatter] |))
        vars = dict_add(vars, 'formatter, $plain_format);
    vars = dict_union(vars, (vars['formatter]).init());
    return (vars['formatter]).format(this[1], vars);
};
add objvar
Adding objvar $rtree<$root>,credit

object $rtree;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
add objvar
Adding objvar $connection_interface<$command_cache>,commands

object $connection_interface;
var $command_cache commands = 0;
add objvar
Adding objvar $connection_interface<$command_cache>,shortcuts

object $connection_interface;
var $command_cache shortcuts = 0;
new method
Replacing protected method $login_interface.connect_guest_cmd()

protected method $login_interface.connect_guest_cmd() {
    arg cmdstr, cmd, args;
    var syn, msg, c, email, name, result, semail, user;
    
    if (!($login_daemon.get_setting("guests-allowed", $login_daemon)))
        return (> .tell_error("", $login_daemon.get_setting("guests-disabled-msg", $login_daemon)) <);
    syn = cmd + " <your name> <your email>";
    semail = $smtp.get_email_address('login);
    args = args.explode();
    c = .connection();
    if ((args.length()) < 2)
        (> .tell_error(syn) <);
    name = (args.subrange(1, (args.length()) - 1)).join();
    email = args[args.length()];
    if ($sys.validate_email_addresses()) {
        catch any {
            .print("Verifying Email Address..");
            msg = $smtp.verify_email_address(email);
            .print("SMTP Response: " + (msg.join(" ")));
        } with {
            .print("Aborting: " + ((traceback()[1])[2]));
            return;
        }
    }
    catch any
        user = (> $sys.create_user(name, 0, email, 'anonymous_user_class) <);
    with
        (> .tell_error(syn, (traceback()[1])[2], "If there is a problem contact: " + semail) <);
    c.change_interface(user);
};
new method
Replacing protected method $login_interface.help_cmd()

protected method $login_interface.help_cmd() {
    arg cmdstr, cmd;
    
    .print($motd.connect_help());
    if (!($login_daemon.get_setting("creation-allowed", $login_daemon)))
        .print(["", "NOTE: User creation is disabled, connect as a guest first."]);
};
update objvar
Updating objvar $http_interface<$http_interface>,info

object $http_interface;
var $http_interface info = #[['generate, 'change], ['script_name, "/aredit/change"], ['path_info, "/"], ['directory_object, $directories], ['lock_object, 0]];
add objvar
Adding objvar $http_interface<$root>,credit

object $http_interface;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
new method
Replacing public method $http_interface.parse_line()

public method $http_interface.parse_line() {
    arg line;
    var match, URI;
    
    if (!method) {
        if (!line)
            return;
        line = explode(line);
        if (listlen(line) != 3) {
            (.connection()).write(.response(400, "HTTP/0.9 not supported."));
            (.connection()).close();
            return;
        }
        if ((match = regexp(line[1], "^(GET|HEAD|POST)$"))) {
            info = #[['URI, line[2]]];
            method = match[1];
        } else {
            info = #[['URI, line[2]]];
            .respond(.response(405, ("Method: \"" + (line[1])) + "\"."));
            (.connection()).close();
            return;
        }
        http = line[3];
    } else if (line) {
        if ((match = regexp(line, "^([^:]+): *(.+)$"))) {
            if (((match[1]) == "Connection") && ((match[2]) == "Keep-Alive"))
                keep_alive = 1;
            else if ((match[1]) == "Authorization")
                .process_auth_info(match[2]);
            else
                header = header.add_elem(@match);
        }
    } else {
        // parse the URI
        match = $http_lib.explode_url(info['URI]);
        info = dict_union(info, match[1]);
        args = match[2];
        catch any {
            (> .(tosym("http_method_" + method))() <);
        } with {
            if (error() != ~stop)
                .respond($parse_lib.html_traceback(traceback(), (status = 500)));
        }
    }
};
new method
Replacing protected method $http_interface.http_method_POST()

protected method $http_interface.http_method_POST() {
    var len, body, part;
    
    len = (| header["Content-Length"] |);
    if ((len == ~keynf) || (!len))
        (> .respond(.response(400, "No Content-Length.")) <);
    body = (.connection()).handle_POST_input(toint(len[1]));
    
    // handle this differently in normal situations
    for part in (body)
        args = dict_union(args, $http_lib.explode_http_encoding(part));
    .http_method_GET();
};
new method
Adding public method $http_interface.info()

public method $http_interface.info() {
    return info;
};
clear objvar
Clearing objvar $pop3_interface<$pop3_interface>,messages

object $pop3_interface;
old var $pop3_interface messages;
old method
Deleting normal method $pop3_interface.message_size()

object $pop3_interface;
eval {
  del_method('message_size);
};
old method
Deleting normal method $pop3_interface.format_rfc822()

object $pop3_interface;
eval {
  del_method('format_rfc822);
};
old method
Deleting normal method $pop3_interface.unique_id()

object $pop3_interface;
eval {
  del_method('unique_id);
};
new method
Replacing protected method $pop3_interface.uidl_cmd()

protected method $pop3_interface.uidl_cmd() {
    arg argstr;
    var x;
    
    (> .check_state("UIDL", 'transaction) <);
    if (argstr) {
        (> .check_valid_message((x = toint(argstr))) <);
        .print((("+OK " + x) + " ") + ((mail_objects[x]).unique_id()));
    } else {
        .print("+OK");
        for x in [1 .. mail_objects.length()] {
            if (!(x in deleted))
                .print((x + " ") + ((mail_objects[x]).unique_id()));
        }
        .print(".");
    }
};
new method
Adding protected method $pop3_interface.mailbox_size()

protected method $pop3_interface.mailbox_size() {
    var x;
    
    return map x in (mail_objects) to (x.rfc822_size()).sum();
};
new method
Replacing protected method $pop3_interface.top_cmd()

protected method $pop3_interface.top_cmd() {
    arg argstr;
    var args, m, n, x, b;
    
    (> .check_state("TOP", 'transaction) <);
    if (((args = argstr.explode()).length()) != 2)
        throw(~stop, "-ERR command needs two arguments");
    if ((n = toint(args[2])) < 0)
        throw(~stop, "-ERR second argument must be a non-negative integer");
    (> .check_valid_message((m = toint(args[1]))) <);
    .print("+OK");
    for x in ((mail_objects[m]).format_rfc822()) {
        if (x)
            .print(((x[1]) == ".") ? ("." + x) : x);
        else
            .print(x);
        if (b) {
            if (--n <= 0)
                break;
        } else if (!x) {
            b++;
        }
    }
    .print(".");
};
new method
Replacing protected method $pop3_interface.retr_cmd()

protected method $pop3_interface.retr_cmd() {
    arg argstr;
    var msgnum, x;
    
    (> .check_state("RETR", 'transaction) <);
    (> .check_valid_message((msgnum = toint(argstr))) <);
    .print(("+OK " + ((mail_objects[msgnum]).rfc822_size())) + " octets");
    for x in ((mail_objects[msgnum]).format_rfc822()) {
        refresh();
        if (!x)
            .print(x);
        else
            .print(((x[1]) == ".") ? ("." + x) : x);
    }
    .print(".");
};
new method
Replacing protected method $pop3_interface.check_valid_message()

protected method $pop3_interface.check_valid_message() {
    arg num;
    
    if ((num < 1) || (num > (mail_objects.length())))
        throw(~stop, ("-ERR no such message, only " + (mail_objects.length())) + " messages in maildrop");
    else if (num in deleted)
        throw(~stop, "-ERR ", x, " refers to a deleted message");
};
new method
Replacing protected method $pop3_interface.pass_cmd()

protected method $pop3_interface.pass_cmd() {
    arg argstr;
    var x;
    
    (> .check_state("USER", 'authorization) <);
    if (!maildrop)
        throw(~stop, "-ERR issue USER command first");
    if (maildrop.check_password(argstr)) {
        catch any
            mail_objects = maildrop.mail();
        with
            throw(~stop, "-ERR could not open maildrop");
        state = 'transaction;
        .print(((((("+OK " + (maildrop.namef('ref))) + " has ") + (mail_objects.length())) + " messages (") + (.mailbox_size())) + " octets)");
    } else {
        throw(~stop, "-ERR authentication failed");
    }
};
new method
Replacing protected method $pop3_interface.list_cmd()

protected method $pop3_interface.list_cmd() {
    arg argstr;
    var x, m;
    
    (> .check_state("LIST", 'transaction) <);
    if (argstr) {
        (> .check_valid_message((x = toint(argstr))) <);
        .print("+OK " + ((mail_objects[x]).rfc822_size()));
    } else {
        .print(((("+OK " + ((m = .live_messages()).length())) + " messages (") + (.mailbox_size())) + " octets)");
        for x in [1 .. mail_objects.length()] {
            if (!(x in deleted))
                .print((x + " ") + ((mail_objects[x]).rfc822_size()));
        }
        .print(".");
    }
};
new method
Replacing protected method $pop3_interface.rset_cmd()

protected method $pop3_interface.rset_cmd() {
    arg argstr;
    
    (> .check_state("RSET", 'transaction) <);
    deleted = [];
    .print(((("+OK maildrop has " + (mail_objects.length())) + " messages (") + (.mailbox_size())) + " octets)");
};
new method
Replacing protected method $pop3_interface.stat_cmd()

protected method $pop3_interface.stat_cmd() {
    arg argstr;
    var x, m;
    
    (> .check_state("STAT", 'transaction) <);
    .print((("+OK " + ((m = .live_messages()).length())) + " ") + (.mailbox_size()));
};
new method
Replacing protected method $pop3_interface.live_messages()

protected method $pop3_interface.live_messages() {
    var x, r;
    
    r = [];
    for x in [1 .. mail_objects.length()] {
        if (!(x in deleted))
            r += [mail_objects[x]];
    }
    return r;
};
new method
Replacing public method $mail_message.add_reader(): nooverride 

public method $mail_message.add_reader(): nooverride  {
    arg who;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    readers = setadd(readers, who);
};
new method
Replacing public method $mail_message.send()

public method $mail_message.send() {
    arg @recips;
    var r, valid, invalid, from;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if (delivered)
        throw(~delivered, "This mail has already been delivered.");
    if (!recips)
        recips = .recipients();
    if (((recips.length()) == 1) && ((recips[1]) == $no_one))
        throw(~norcpt, "No recipients specified.");
    
    // Cache RFC822 size
    .rfc822_size();
    valid = [];
    invalid = [];
    for r in (recips) {
        if (r.has_ancestor($mail_list))
            valid += [r];
        else
            invalid += [r];
    }
    if (invalid)
        throw(~invrcpt, "Invalid mail recipients: " + (invalid.mmap('name)), invalid);
    recips = valid;
    invalid = [];
    
    // ok, now that we have that cleared up, lets set pertinent info...
    .set_time(time());
    if ((!(.from())) || (sender() != $no_one))
        .set_from(sender());
    
    // and now to finalize the recipients
    for r in (recips) {
        if ((r.list_is_inet()) && (!frominet)) {
            from = (sender().user_info("name")) || (sender().name());
            from += (" <" + (sender().user_info("email"))) + ">";
            r = r.get_setting("inet-list", $mail_list);
            $smtp.sendmail(from, r, header['subj], .body());
            delivered++;
        } else if (r.list_is_sendable_by(sender())) {
            r.add_mail();
            .add_recipient(r);
            delivered++;
        } else {
            invalid += [r];
        }
    }
    if (!delivered)
        throw(~delivered, "Unable to deliver message.");
    return invalid;
};
new method
Replacing public method $mail_message.add_recipient(): nooverride 

public method $mail_message.add_recipient(): nooverride  {
    arg whom;
    var current;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    current = (| header['rcpt] |) || [];
    if ((| whom in current |))
        throw(~type, "Recipient is already in the list of recipients");
    header = dict_add(header, 'rcpt, setadd(current, whom));
};
new method
Replacing public method $mail_message.format_rfc822()

public method $mail_message.format_rfc822() {
    var out, x, line;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if (.meta()) {
        out = [];
        for x in (.meta())
            out += [((x[1]) + ": ") + (x[2])];
    } else {
        out = ["Date: " + ($time.format("%a, %e %b %Y %T %Z", .time()))];
        out += ["From: " + ($smtp.get_email_address(.from()))];
        out += ["To: " + (((.recipients()).omap($smtp, 'get_email_address)).join(", "))];
        out += [((("Message-ID: <" + (.unique_id())) + "@") + ($sys.server_info('server_hostname))) + ">"];
        out += ["Subject: " + (.subject())];
        out += ["X-UIDL: " + (.unique_id())];
    }
    out += [""];
    for line in (.body()) {
        refresh();
        if ((line.length()) > 79)
            out += line.wrap_lines(75);
        else
            out += [line];
    }
    return out;
};
new method
Adding public method $mail_message.unique_id()

public method $mail_message.unique_id() {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if (!(header.contains('uidl)))
        header = header.add('uidl, $mail_lib.generate_unique_id(this()));
    return header['uidl];
};
update objvar
Updating objvar $note<$root>,flags

object $note;
var $root flags = ['core, 'fertile, 'code, 'methods, 'variables];
add objvar
Adding objvar $page<$root>,credit

object $page;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $page_home_index<$root>,credit

object $page_home_index;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $page_bin_index<$root>,credit

object $page_bin_index;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
new method
Replacing public method $page_bin_index._show_object()

public method $page_bin_index._show_object() {
    arg obj, what;
    var top, middle, bottom, desc, alert, nalert, line;
    
    middle = (bottom = []);
    top = [("<h1>" + (._make_object_href(obj))) + "</h1>"];
    
    // CORENOTE: merge this with a central location (likely $directories)
    alert = ("<p><font size=\"+1\" color=\"#" + (($cml_color.get_color("red"))[1])) + "\"><b>";
    nalert = "</b></font>";
    top += ["<table>"];
    top += [("<tr><td><b>Perms</b>:</td><td>" + (((obj.flags()).prefix("+")).join())) + "</td></tr>", ("<tr><td><b>Size</b>:</td><td>" + ((obj.size()).to_english())) + " bytes (on disk)</td></tr>", ("<tr><td><b>Manager</b>:</td><td>" + (._make_object_href(obj.manager()))) + "</td></tr>", ._show_header_objs(obj.writers('literal), "Writer"), ._show_header_objs(obj.parents(), "Parent")];
    if (obj.has_ancestor($located))
        top += [("<tr><td><b>Location</b>:</td><td>" + (._make_object_href(obj.location()))) + "</td></tr>"];
    if (obj.help_node())
        top += [((("<tr><td><b>Associated Help</b>:</td><td><a href=\"/bin/help?node=" + (obj.help_node())) + "\">") + (obj.help_node())) + "</a></td></tr>"];
    top += [("<tr><td><b>Credit</b>:</td><td>" + join(obj.credit(), "<br>")) + "</td></tr>"];
    top += ["</table><p><hr size=1 noshade><p>"];
    if (obj.has_ancestor($described)) {
        if (what['desc]) {
            bottom += ["<p><b>Description</b>:<blockquote><pre>"];
            desc = obj.prose();
            switch (type(desc)) {
                case 'frob:
                    for line in (desc.uncompile())
                        bottom += line.wrap_lines(79, " ");
                case 'list:
                    bottom += desc;
                case 'string:
                    bottom += [desc];
            }
            bottom += ["</pre></blockquote>"];
            middle += [._make_show_object_href("Hide Description", obj, what, 'desc, 0)];
        } else {
            middle += [._make_show_object_href("Show Description", obj, what, 'desc, 1)];
        }
        top += ["</td></tr>"];
    }
    if (what['methods]) {
        if (!(obj.has_flag('methods, this())))
            bottom += [(alert + "** No permission to List Methods **") + nalert];
        else
            bottom += (["<p><b>Methods:</b><blockquote><pre>"] + (._show_methods(obj))) + ["</pre></blockquote>"];
        middle += [._make_show_object_href("Hide Methods", obj, what, 'methods, 0)];
    } else {
        middle += [._make_show_object_href("List Methods", obj, what, 'methods, 1)];
    }
    if (what['vars]) {
        if (!(obj.has_flag('variables, this())))
            bottom += [(alert + "** No permission to Show Variables **") + nalert];
        else
            bottom += (["<p><b>Variables:</b><blockquote><pre>"] + (._show_variables(obj))) + ["</pre></blockquote>"];
        middle += [._make_show_object_href("Hide Variables", obj, what, 'vars, 0)];
    } else {
        middle += [._make_show_object_href("Show Variables", obj, what, 'vars, 1)];
    }
    return (((top + middle) + ["<p>"]) + bottom) + ["<p>"];
};
add objvar
Adding objvar $page_desktop_login<$root>,credit

object $page_desktop_login;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $page_file_index<$root>,credit

object $page_file_index;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $page_root_index<$root>,credit

object $page_root_index;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $page_login<$root>,credit

object $page_login;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $plain_page<$root>,credit

object $plain_page;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $page_web_prefs<$root>,credit

object $page_web_prefs;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
update objvar
Updating objvar $character<$located>,location

object $character;
var $located location = $nowhere;
update objvar
Updating objvar $path<$foundation>,msgs

object $path;
var $foundation msgs = #[["invoke", #[["actor", <$ctext_frob, [["You take ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["source", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " goes through ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["dest", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " arrives."], #[['this, $path]]]>]]], ["exit-close", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " closes ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["actor", <$ctext_frob, [["You close ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>]]], ["exit-open", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " opens ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["actor", <$ctext_frob, [["You open ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>]]], ["lock-fail", #[["actor", <$ctext_frob, [[<$generator, ["this", [], [], 'gen_this]>, " is locked."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is locked."], #[]]>]]], ["lock-try", #[["actor", <$ctext_frob, [["You use ", <$generator, ["lock", [], [], 'gen_lock]>, " on ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[], #[['this, $path]]]>]]], ["lock-unlock", #[["actor", <$ctext_frob, [["You unlock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " unlocks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>]]], ["lock-lock", #[["actor", <$ctext_frob, [["You lock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " locks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $path]]]>]]], ["exit-closed", #[["actor", <$ctext_frob, [["You try to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is closed."], #[]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to go through ", <$generator, ["this", [], [], 'gen_this]>, ", but it is closed."], #[]]>]]]];
add objvar
Adding objvar $climate<$root>,credit

object $climate;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
new method
Replacing public method $climate.ctext_variables()

public method $climate.ctext_variables() {
    arg current, season;
    var vars;
    
    vars = #[["weather", current.name()], ["weather_desc", current.prose()], ["season", season]];
    vars = dict_union(vars, current.attribute_vars());
    return vars;
};
add objvar
Adding objvar $weather<$root>,credit

object $weather;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
new method
Replacing public method $weather.attribute_vars()

public method $weather.attribute_vars() {
    var i, attr, extra, a;
    
    a = .attributes();
    attr = $weather_attributes.alist_dict(a);
    for i in ($weather_attributes.extra_attributes())
        dict_add(attr, @i);
    return attr;
};
new method
Replacing public method $db.exact_match()

public method $db.exact_match() {
    arg key;
    var match;
    
    // get an exact match of a key, return the value
    match = (| (type(database) == 'dictionary) ? (database[key]) : ((database.match_exact(key))[2]) |);
    if (match == ~keynf)
        throw(~matchnf, ("No object by the key \"" + key) + "\" exists.");
    return match;
};
new method
Replacing public method $registry.exact_match()

public method $registry.exact_match() {
    arg name;
    
    // returns a direct match of the name (if there is one)
    if (!(.has_flag('variables)))
        throw(~perm, "Database is not readable by sender.");
    name = .strip_key(name);
    return (> pass(name) <);
};
new method
Replacing root method $mail_db.core_mail_db()

root method $mail_db.core_mail_db() {
    .set_database(#[["news", $mail_list_news], ["bugs", $mail_list_bugs], ["admin", $mail_admin], ["tracebacks", $mail_list_tracebacks], ["postmaster", $mail_postmaster]]);
};
update objvar
Updating objvar $help_coldcore<$help_node>,body

object $help_coldcore;
var $help_node body = <$ctext_frob, [[<$format, ["img", [["plain", <$format, ["quote", [], ["\n        ___     _    _   _  _     _        ___         _\n       / __|___| |__| | | || |___| |_ __  / __|_  _ __| |_ ___ _ __\n      | (__/ _ \ / _` | | __ / -_) | '_ \ \__ \ || (_-<  _/ -_) '  \ \n       \___\___/_\__,_| |_||_\___|_| .__/ |___/\_, /__/\__\___|_|_|_|\n                                   |_|         |__/\n"], 'do_quote]>], ["src", "http://www.cold.org/coldcore/cold-help.jpg"]], [], 'do_img]>, <$format, ["p", [], [], 'do_p]>, "Welcome to ", <$generator, ["servname", [], [], 'gen_servname]>, ". This is a hypertext help system. If you are on an interactive login you can type ", <$format, ["tt", [], ["@help help"], 'do_tt]>, " for help on how to use this help system. Following is a list of Launch Points to the help system:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help"]], ["Help"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How to use this help system"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_general"]], ["General"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["General Information"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_building"]], ["Building"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Extending your Environment"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_prog"]], ["Programming"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Topics about programming"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_admin"]], ["Administration"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["ColdCore Administration"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_reference"]], ["Reference"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Core Reference Information"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_updates"]], ["Updates"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["ChangeLog for this system"], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_administrators"]], ["Administrators"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["List of Administrators and Roles"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_credit"]], ["Credit"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Credit and Copyright Information"], 'do_dd]>], 'do_dl]>], #[['links, #[["Help", "$help_help"], ["General", "$help_general"], ["Building", "$help_building"], ["Programming", "$help_prog"], ["Administration", "$help_admin"], ["Reference", "$help_reference"], ["Updates", "$help_updates"], ["Administrators", "$help_administrators"], ["Credit", "$help_credit"]]]]]>;
update objvar
Updating objvar $help_environment<$help_node>,links

object $help_environment;
var $help_node links = #[["@context", $help_cmd_context], ["@remember", $help_cmd_remember]];
update objvar
Updating objvar $help_environment<$help_node>,body

object $help_environment;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Your environment is where the system tries to find things, when you name something. It does this by first checking everything in your contents, and everything in the location you are in. ", <$format, ["subj", [["level", "2"]], ["Context"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The system will also check your recent context. The server records the last object you named, as well as all of the last objects you named (with a gender). You can list your recent context with the command ", <$format, ["link", [["node", "$help_cmd_context"]], ["@context"], 'do_link]>, ", receiving a result similar to:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["Last thing: the Magazine Rack\nLast it:    the Magazine Rack      \nLast her:   Squeak the lemming\nLast him:   Miro"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the system is attempting to find a named object, it first checks in your context. This allows you to name objects by their gender (if you remember it correctly). For instance:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], [<$format, ["quote", [], ["> get bottle\nYou take the bottle.\n> drop it\nYou drop the bottle."], 'do_quote]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Multiple Matches"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "In the case where multiple objects would match a single name, you can use ordinal references, such as ", <$format, ["tt", [], ["the 3rd bottle"], 'do_tt]>, " or ", <$format, ["tt", [], ["the second key"], 'do_tt]>, ". ", <$format, ["subj", [["level", "2"]], ["Posessive Matching"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "If something is located in something else, in your environment (either being carried by somebody, or in a box, etc), you can refer to it posessively. For instance, if the user 'Joe' is holding a note, you can look at it with the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["nobound", 1]], ["> look at Joe's note"], 'do_dfn]>, " ", <$format, ["subj", [["level", "2"]], ["Keywords"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "There are also two words known by the system. The first is ", <$format, ["tt", [], ["me"], 'do_tt]>, ", which is always you. The second is ", <$format, ["tt", [], ["here"], 'do_tt]>, ", which is always your location. ", <$format, ["subj", [["level", "2"]], ["Remembering"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "If you are having a hard time remembering an items object name, or typing it's full name, you can remember it as a shorter name, with the command ", <$format, ["link", [["node", "$help_cmd_remember"]], ["@remember"], 'do_link]>, "."], #[['links, #[["@context", "$help_cmd_context"], ["@remember", "$help_cmd_remember"]]]]]>;
update objvar
Updating objvar $help_appearance<$help_node>,body

object $help_appearance;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Anything in the virtual environment will always have some common attributes, such as name, description and gender. If you manage the item, you can change these attributes and alter its appearance (this includes yourself). Everything that can be changed is described in more detail in the following sections:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_desc"]], ["Description"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_gender"]], ["Gender"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_wearing"]], ["Wearing"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["Names", "$help_app_names"], ["Description", "$help_app_desc"], ["Gender", "$help_app_gender"], ["Wearing", "$help_app_wearing"]]]]]>;
update objvar
Updating objvar $help_interface_client<$help_node>,body

object $help_interface_client;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When you connect to a Virtual Environment System you use a ", <$format, ["i", [], ["client"], 'do_i]>, ". A client is simply a program you run from your machine. This program connects you with the server somewhere on the network. If you used ", <$format, ["tt", [], ["telnet"], 'do_tt]>, " to get here, your client is ", <$format, ["tt", [], ["telnet"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "This system is not designed for use with ", <$format, ["tt", [], ["telnet"], 'do_tt]>, ". It has many customized aspects which telnet simply does not support. Because of this it is suggested for your own benefit and enjoyment that you get a supported client. ", <$format, ["np", [], [], 'do_np]>, "Currently supported clients are: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "25%,75%"]], [<$format, ["tr", [], [<$format, ["td", [], ["Tinyfugue"], 'do_td]>, <$format, ["td", [], [<$format, ["web", [["src", "ftp://tf.tcp.com/pub/tinyfugue"], ["name", "ftp://tf.tcp.com/pub/tinyfugue"]], [], 'do_web]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["TkMOO-lite"], 'do_td]>, <$format, ["td", [], [<$format, ["web", [["src", "http://www.cs.cf.ac.uk/User/Andrew.Wilson/tkMOO-light/"], ["name", "http://www.cs.cf.ac.uk/User/Andrew.Wilson/tkMOO-light/"]], [], 'do_web]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>;
update objvar
Updating objvar $help_groups<$help_node>,body

object $help_groups;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The group system is an all purpose classification system which can be used for a wide array of purposes. Groups can work in one of two ways: either they are simply a list of objects, and can be tested against for permissions sake, or they use a logical expression as their condition. ", <$format, ["subj", [["level", "2"]], ["Object Groups"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Object groups are heirarchial, so for an example consider the following group heirarchy:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["$group [*-mvc]\n  $staff_group [*-mvc]\n    $building_group [*fmvc]"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If a user is added to the staff group, and something tests against the building group, the staff members are included so it will evaluate true--even though they are not in the building group. ", <$format, ["subj", [["level", "2"]], ["Groups and Security"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Groups can be specified as a writer on an object, and when testing against writer permissions for that object, it will also include anybody in the group, or evaluate against the condition of the group. ", <$format, ["subj", [["level", "2"]], ["Programmer API"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "To use a group in ColdC code, simply call the method ", <$format, ["method", [["$group.includes", 1]], [".includes"], 'do_method]>, "() on the group, with a single argument of the object which is in question. ", <$format, ["subj", [["level", "2"]], ["Available Groups"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "To see a list of all available groups, use the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@descend $group +all +only=core"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All groups have a setting of '", <$format, ["tt", [], ["group"], 'do_tt]>, "', which is a list of objects--except for $conditional_group and its descendants, where it is a logical expression."], #[]]>;
update objvar
Updating objvar $help_cml_formatters<$help_node>,body

object $help_cml_formatters;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The standard formatter tags are loosely based on HTML 3.0: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "11%,89%"]], [<$format, ["tr", [], [<$format, ["td", [], ["action"], 'do_td]>, <$format, ["td", [], ["One flag of ", <$format, ["tt", [], ["cmd"], 'do_tt]>, ", which is run if the action is triggered (either by clicking on it, or using the action-trigger command ", <$format, ["tt", [], ["'>'."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["b"], 'do_td]>, <$format, ["td", [], ["Bold or strong."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["br"], 'do_td]>, <$format, ["td", [], ["Line Break. Differs from {p} in that it can be stacked multiple times, for multiple breaks. Use of {p} is preferred."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dd"], 'do_td]>, <$format, ["td", [], ["Dictionary Definition, must be an argument to a Dictionary List (", <$format, ["tt", [], ["dl"], 'do_tt]>, ")."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["detail"], 'do_td]>, <$format, ["td", [], ["Generate a description detail. One required option of ", <$format, ["tt", [], ["name"], 'do_tt]>, " which is unique to this detail througout the entire description. Details may be nested."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dfn"], 'do_td]>, <$format, ["td", [], ["Definition. Used to indent a block of text. Arguments can be ", <$format, ["tt", [], ["ind"], 'do_tt]>, ", which is an integer representing the spaces to indent (in plaintext this defaults to eight); and ", <$format, ["tt", [], ["nobound"], 'do_tt]>, ", which effects the line breaks after the definition."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dl"], 'do_td]>, <$format, ["td", [], ["Dictionary list. Arguments can contain tags dt (dictionary title) and dd (dictionary definition)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dt"], 'do_td]>, <$format, ["td", [], ["Dictionary Title, must be an argument to a Dictionary List (", <$format, ["tt", [], ["dl"], 'do_tt]>, ")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["i"], 'do_td]>, <$format, ["td", [], ["Italics or Emphasis."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["img"], 'do_td]>, <$format, ["td", [], ["Place image in description. Image is only visible in HTML formats."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["lh"], 'do_td]>, <$format, ["td", [], ["List Header, must be an argument for ", <$format, ["tt", [], ["ol"], 'do_tt]>, " or ", <$format, ["tt", [], ["ul."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["li"], 'do_td]>, <$format, ["td", [], ["List Element, must be an argument for ", <$format, ["tt", [], ["ol"], 'do_tt]>, " or ", <$format, ["tt", [], ["ul."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["link"], 'do_td]>, <$format, ["td", [], ["Creates a hypertext link to the help node (as an objname) specified with the option ", <$format, ["tt", [], ["node."], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["np"], 'do_td]>, <$format, ["td", [], ["New Paragraph, similar to {p}, but in plaintext it breaks with two lines rather than one."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["ol"], 'do_td]>, <$format, ["td", [], ["Ordered list. Within arguments use tags lh (list header) and li (list element)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["p"], 'do_td]>, <$format, ["td", [], ["Paragraph Break, similar to {np}, but in plaintext it only breaks with one line."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["subj"], 'do_td]>, <$format, ["td", [], ["Rougly equivalent to HTML's header <h?> tags. Argument ", <$format, ["tt", [], ["level"], 'do_tt]>, " specifies which level of subject to use (1-4) and defaults to a value of 4."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["table"], 'do_td]>, <$format, ["td", [], ["Similar to tables in HTML. Options are ", <$format, ["tt", [], ["ind"], 'do_tt]>, " (how many spaces to indent the table before formatting) and ", <$format, ["tt", [], ["cols"], 'do_tt]>, " (column definition). ", <$format, ["tt", [], ["cols"], 'do_tt]>, " must be defined. It is a comma seperated list of column specs, which can either be in specific character units or percentages (the whole list must be either one or the other). Arguments consist of ", <$format, ["tt", [], ["tr"], 'do_tt]>, " (table row) tags."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["td"], 'do_td]>, <$format, ["td", [], ["Table Cell, options include ", <$format, ["tt", [], ["colspan"], 'do_tt]>, " and ", <$format, ["tt", [], ["rowspan"], 'do_tt]>, " which can be used to span columns and rows with the Table Cell."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["tr"], 'do_td]>, <$format, ["td", [], ["Table Row, arguments consist of ", <$format, ["tt", [], ["td"], 'do_tt]>, " tags for each table cell in the row."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["tt"], 'do_td]>, <$format, ["td", [], ["Fixed-width font (typewriter), also used for literal text."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["ul"], 'do_td]>, <$format, ["td", [], ["Unordered list. Within arguments use tags lh (list header) and li (list element)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["web"], 'do_td]>, <$format, ["td", [], ["Creates a www hypertext link. This tag requires ", <$format, ["tt", [], ["src"], 'do_tt]>, " and ", <$format, ["tt", [], ["name"], 'do_tt]>, " options. The ", <$format, ["tt", [], ["src"], 'do_tt]>, " should have a valid URL as the value and the ", <$format, ["tt", [], ["name"], 'do_tt]>, " should have the name of the URL to be displayed."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[]]>;
update objvar
Updating objvar $help_cml_generators<$help_node>,body

object $help_cml_generators;
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "16%,84%"]], [<$format, ["tr", [], [<$format, ["td", [], ["columnize"], 'do_td]>, <$format, ["td", [], ["Generates a list of columnized strings taken from the argument list. Option ", <$format, ["tt", [], ["cols"], 'do_tt]>, " defines column information."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["def"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["var"], 'do_tt]>, " which is the name of a variable. Creates a new variable generator with that name, which has the value of the first argument. Will ", <$format, ["i", [], ["not"], 'do_i]>, " evaluate arguments, instead stores the unparsed first argument. Similar to ", <$format, ["tt", [], ["set"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["english"], 'do_td]>, <$format, ["td", [], ["Generates an english-formatted list from the arguments. Options can include ", <$format, ["tt", [], ["sep"], 'do_tt]>, " (element seperator, defaulting to \",\"), ", <$format, ["tt", [], ["empty"], 'do_tt]>, " (what to print if the argument list is empty, defaulting to \"nothing\"), ", <$format, ["tt", [], ["and"], 'do_tt]>, " (what to print as a seperator before the last element, defaulting to \"and\")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["foreach"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["list"], 'do_tt]>, ". Will iterate over body for each element in list. Additional option ", <$format, ["tt", [], ["var"], 'do_tt]>, " may be defined for iteration variable, defaults to ", <$format, ["tt", [], ["iterator"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["join"], 'do_td]>, <$format, ["td", [], ["Joins arguments. Options can include ", <$format, ["tt", [], ["seperator"], 'do_tt]>, " which is either ", <$format, ["tt", [], ["none"], 'do_tt]>, ", ", <$format, ["tt", [], ["english"], 'do_tt]>, " or a string literal. If ", <$format, ["tt", [], ["none"], 'do_tt]>, " the list is forwarded to the caller, rather than joined to a string"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["name"], 'do_td]>, <$format, ["td", [], ["Generates the names of the objects in the arguments list. Options can include ", <$format, ["tt", [], ["seperator"], 'do_tt]>, " which is either ", <$format, ["tt", [], ["none"], 'do_tt]>, ", ", <$format, ["tt", [], ["english"], 'do_tt]>, " or a string literal. If ", <$format, ["tt", [], ["none"], 'do_tt]>, " is given a list is generated, otherwise a string is generated"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["pro"], 'do_td]>, <$format, ["td", [], ["Generates a pronoun. Required option is ", <$format, ["tt", [], ["obj"], 'do_tt]>, " which defines the object for the pronoun generation. First argument is taken as the type of pronoun to use, as defined on $gender"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["random"], 'do_td]>, <$format, ["td", [], ["Returns a random number ranging from ", <$format, ["tt", [], ["low"], 'do_tt]>, " to ", <$format, ["tt", [], ["high"], 'do_tt]>, " which are given as options. Low can be omitted, one is used then instead."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["servname"], 'do_td]>, <$format, ["td", [], ["The name of the server, as is set on ", <$format, ["tt", [], ["@set $motd:server-name"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["set"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["var"], 'do_tt]>, " which is the name of a variable. Creates a new variable generator with that name, which has the value of the first argument. Will evaluate arguments and store results. Similar to ", <$format, ["tt", [], ["def"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["switch"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["value"], 'do_tt]>, " which is evaluated. The resulting value is then used to select a result. Currently switch uses every other item in the argument list as a case/value pair (use the ", <$format, ["tt", [], ["join"], 'do_tt]>, " generator for arguments with spaces). If there is a remaining odd element is is considered the default result"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["time"], 'do_td]>, <$format, ["td", [], ["Arguments are sent to the native method $time.format()"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["vars"], 'do_td]>, <$format, ["td", [], ["Returns the names of variables available. Option ", <$format, ["tt", [], ["separator"], 'do_tt]>, " is the same as in ", <$format, ["tt", [], ["name"], 'do_tt]>, " generator"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "4"]], ["Other tags"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Each cml processor can also create extra generators. Also, caller to the cml can create extra variables that are available for generators."], #[]]>;
update objvar
Updating objvar $help_cml_customizing<$help_node>,body

object $help_cml_customizing;
var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], ["Interface"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Ctext frobs are created by calling the .", <$format, ["method", [["compiler.compile_cml", 1]], ["compile_cml"], 'do_method]>, "() method off the cml compiler object. On a ctext frob, you may call .", <$format, ["method", [["ctext_frob.uncompile", 1]], ["uncompile"], 'do_method]>, "() to return the original text. A call to .", <$format, ["method", [["ctext_frob.eval_ctext", 1]], ["eval_ctext"], 'do_method]>, "() evaluates the generators, but will not touch the formatters. This is used to speed up message dispatching. Calling ", <$format, ["method", [["ctext_frob.format", 1]], ["format"], 'do_method]>, "() provides the final formatting of the ctext, evaluating everything, including the formatters. You can add/modify variables on a ctext frob by calling .", <$format, ["method", [["ctext_frob.set_var", 1]], ["set_var"], 'do_method]>, "(", <$format, ["var", [], ["variable"], 'do_var]>, ", ", <$format, ["var", [], ["value"], 'do_var]>, "), or .", <$format, ["method", [["ctext_frob.set_vars", 1]], ["set_vars"], 'do_method]>, "(", <$format, ["var", [], ["dict"], 'do_var]>, "), which does the same, but assigning multiple variables at once. ", <$format, ["subj", [["level", "3"]], ["Adding new evaluators"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "An evaluator is an object which contains methods for generation or formatting. An evaluation object that is descended from a vanilla evaluator (like $bs_eval) will try to store the evaluation results in a list, and is therefore most suitable for adding new generators. On the other hand, evaluators descended from a formatter object create a string, and try to evaluate and concatenate lists until a string is obtained. Hence, they should be used for formatting. To add a new generator or formatter, simply add a do_format or gen_generator method on the object, where 'format' or 'generator' is the name of the new tag that you wish to add. Make sure that the object is in the evaluation path (by explicitly adding an 'evaluator, 'formatter or even an 'uncompiler field to the ctext frob.)"], #[]]>;
update objvar
Updating objvar $help_coldc_methods_access<$help_node>,links

object $help_coldc_methods_access;
var $help_node links = #[["Frobbed Method Calls", $help_coldc_methods_frob], ["method_access()", $help_func_method_access], ["set_method_access()", $help_func_set_method_access]];
update objvar
Updating objvar $help_coldc_methods_access<$help_node>,body

object $help_coldc_methods_access;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "It is possible to restrict what calls a method by setting the method's access. By default all methods are ", <$format, ["i", [], ["public"], 'do_i]>, " methods. The available settings for method access are: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "15%,85%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["public"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This access state is the default. A public method can be called by any object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["protected"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Protected methods can only be called by the defining object, or descendants of the defining object (sender() must be this())."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["private"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Private methods can only be called by the object they were defined on (caller() must be this())."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["root"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Root methods can only be called by the ", <$format, ["tt", [], ["$root"], 'do_tt]>, " object (caller() must be ", <$format, ["tt", [], ["$root"], 'do_tt]>, ")."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["driver"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Driver methods can only be called by the driver."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["frob"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This access state only allows ", <$format, ["link", [["node", "$help_coldc_methods_frob"]], ["Frobbed Method Calls"], 'do_link]>, "."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Method access can be manipulated using the functions ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_method_access"]], ["method_access()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_method_access"]], ["set_method_access()"], 'do_link]>], 'do_tt]>, "."], #[['links, #[["Frobbed Method Calls", "$help_coldc_methods_frob"], ["method_access()", "$help_func_method_access"], ["set_method_access()", "$help_func_set_method_access"]]]]]>;
update objvar
Updating objvar $help_coldc_tasks_tasks<$help_node>,links

object $help_coldc_tasks_tasks;
var $help_node links = #[["task_id()", $help_func_task_id], ["task_info()", $help_func_task_info], ["tasks()", $help_func_tasks], ["stack()", $help_func_stack], ["user()", $help_func_user], ["set_user()", $help_func_set_user], ["atomic()", $help_func_atomic]];
update objvar
Updating objvar $help_coldc_tasks_tasks<$help_node>,body

object $help_coldc_tasks_tasks;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "One or more frames executed in a series is called a ", <$format, ["i", [], ["task"], 'do_i]>, ". Tasks will originate from either a connection, a heartbeat, or by a fork in another task. There is no restriction on how many frames a task can execute. ", <$format, ["np", [], [], 'do_np]>, "Several different functions return information about a task, or are used on a task-wide scale: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "23%,77%"]], [<$format, ["tr", [], [<$format, ["th", [], ["FUNCTION"], 'do_th]>, <$format, ["th", [], ["BEHAVIOUR"], 'do_th]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_id"]], ["task_id()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns unique ID for the current task"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_info"]], ["task_info()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns information on a task"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_tasks"]], ["tasks()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns a list of all paused or preempted tasks"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_stack"]], ["stack()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns full execution frame stack"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_user"]], ["user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns task user"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_user"]], ["set_user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Sets task user"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Used to turn on/off Atomic execution"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["task_id()", "$help_func_task_id"], ["task_info()", "$help_func_task_info"], ["tasks()", "$help_func_tasks"], ["stack()", "$help_func_stack"], ["user()", "$help_func_user"], ["set_user()", "$help_func_set_user"], ["atomic()", "$help_func_atomic"]]]]]>;
update objvar
Updating objvar $help_func_backup<$help_node>,body

object $help_func_backup;
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " backup()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function synchronizes the running database to disk and starts an asyncrynous backup (Genesis copies the files to the file ", <$format, ["i", [], ["binary"], 'do_i]>, ".bak, where ", <$format, ["i", [], ["binary"], 'do_i]>, " is the binary database directory name specified upon bootup). This function executes atomically, and a slight pause may be noticed while it synchronizes the object cache to disk and copies the index files. ", <$format, ["np", [], [], 'do_np]>, "The return value of ", <$format, ["tt", [], ["backup()"], 'do_tt]>, " is always ", <$format, ["tt", [], ["1"], 'do_tt]>, ", and should be ignored. If a backup is in progress the error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown. The error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown if there are file or directory problems. When the asyncrynous backup is finished the driver calls ", <$format, ["tt", [], ["$sys.backup_done()"], 'do_tt]>, "."], #[]]>;
new method
Replacing public method $help_administrators.body()

public method $help_administrators.body() {
    arg @ignored;
    var admins, a, output, def, role, c1, c2, o;
    
    admins = [];
    def = "General Administrator";
    for a in ($sys.admins()) {
        role = a.get_setting("admin-role", $admin);
        if (match_begin(role, "Arch"))
            role = "0 " + role;
        else if (role && ((role[1]) in ($string.alphabet())))
            role = "00 " + role;
        else if (!role)
            role = "000 " + def;
        admins += [[role, a]];
    }
    output = [];
    for a in (admins.sort()) {
        o = $cml_lib.format_obj_tag('look, a[2], (a[2]).name());
        c1 = $cml_lib.format_td_tag(o);
        role = strsed(a[1], "^0+ ", "");
        c2 = $cml_lib.format_td_tag(role);
        output += [$cml_lib.format_tr_tag(c1, c2)];
    }
    return $ctext_frob.new_with([$cml_lib.format_dfn_tag(["Administrators:", $cml_lib.format_p_tag(), $cml_lib.format_table_tag("25%,75%", @output)])]);
};
update objvar
Updating objvar $help_cmd_paste<$help_node>,body

object $help_cmd_paste;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@paste [to <target>]"], 'do_tt]>, <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "The non-VR interaction command ", <$format, ["tt", [], ["@paste"], 'do_tt]>, " is used to display blocks of text either to the room or to a specific person (<target>). If no target is specified, it is displayed to the room. You will be prompted for the text. When you are finished typing in the text, type a period at the beginning of a line, followed by no other characters. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["> @paste\nReceiving input. Enter \".\" to finish or \"@abort\" to abort.\n> USER     PID   %CPU %MEM   VSZ  RSS  COMMAND\n> brandon  10267  0.0 19.4  5800 5928  ./genesis\n> .\n-------------- Brandon (@paste's) ---------------\nUSER     PID   %CPU %MEM   VSZ  RSS  COMMAND\nbrandon  10267  0.0 19.4  5800 5928  ./genesis\n------------------- + Finis + -------------------\n2 lines of text pasted"], 'do_quote]>], 'do_dfn]>], #[]]>;
update objvar
Updating objvar $help_cmd_display<$help_node>,body

object $help_cmd_display;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@d?isplay <objref> [options]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Shows general information about an object, including it's size, owner, parents, location, and what permissions it has. You can optionally have it list all the public methods you have defined on an object, or all the variables, and which object defines them as below. ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Example:"], 'do_b]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire\nObject:   $vampire (Vampire)\nCreated:  Mon Jan 13 18:19:17 1997\nQuota:    75000 bytes\nPerms:\nSize:     6,132 bytes (on disk)\nManager:  $vampire (Vampire)\nWriters:  (none)\nParents:  $admin (Generic Admin) and $antisocial\nLocation: $the_pit (The Pit)\n---"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire,\nObject Variables matching \"*\"\n  ,test_dict: #[]\n  ,test: 0\n"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["dfn", [], [<$format, ["quote", [], [">@display $vampire.\nPublic Methods matching \"*\":\n ----   34 .edit_cmd(cmdstr, com, args)\n ----   14 .quit_editor()\n ----   49 .pulse()\n ----   24 .startup()\n ----    8 .dict_test(cmdstr, cmd, @str)\n ----   51 .tmp_pulse()\n"], 'do_quote]>], 'do_dfn]>, " Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+c?hop"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Chops lines longer than the players cols ", <$format, ["link", [["node", "$help_interface_settings"]], ["setting"], 'do_link]>, "."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+g?enerations"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Sets which object to go back from."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['links, #[["setting", "$help_interface_settings"]]]]]>;
update objvar
Updating objvar $help_cmd_backup<$help_node>,body

object $help_cmd_backup;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: @backup"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Start an asynchronous backup of the binary database."], #[]]>;
update objvar
Updating objvar $help_cmd_describe<$help_node>,links

object $help_cmd_describe;
var $help_node links = #[["CML", $help_cml], ["@edit", $help_cmd_edit]];
update objvar
Updating objvar $help_cmd_describe<$help_node>,body

object $help_cmd_describe;
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@desc?ribe|@prose <what> [as <description>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Sets the description (prose) for an object. If nothing other than the target object is given on the command line, you will be prompted for the description. Otherwise it will take anything after the preposition '", <$format, ["i", [], ["as"], 'do_i]>, "' as the description. ", <$format, ["np", [], [], 'do_np]>, "The description is not written in plaintext, but is in ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, ". Because of this, all plaintext formatting you include will be disregarded. Use CML tags for any desired formatting. ", <$format, ["np", [], [], 'do_np]>, "Note: This will overwrite the current description. To edit the description on the object, use the ", <$format, ["link", [["node", "$help_cmd_edit"]], ["@edit"], 'do_link]>, " command."], #[['links, #[["CML", "$help_cml"], ["@edit", "$help_cmd_edit"]]]]]>;
update objvar
Updating objvar $help_cmd_new<$help_node>,body

object $help_cmd_new;
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@new <parent> [named <name>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Creates a new VR object with the given parent, and optionally set the name. This command is preferred when working with VR objects, as it will correctly handle both real and ", <$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frob"], 'do_link]>, " instances. The alternative is ", <$format, ["link", [["node", "$help_cmd_spawn"]], ["@spawn"], 'do_link]>, " which will always create new objects. If you want to create a new non-VR object, use @spawn or call the parent's .new() method.", <$format, ["p", [], [], 'do_p]>, "See also: ", <$format, ["link", [["node", "$help_cmd_destroy"]], ["@destroy"], 'do_link]>], #[['links, #[["Frob", "$help_coldc_types_frobs"], ["@spawn", "$help_cmd_spawn"], ["@destroy", "$help_cmd_destroy"]]]]]>;
update objvar
Updating objvar $help_cmd_spawn<$help_node>,body

object $help_cmd_spawn;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@spawn <parent>[named <name>]"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Create a new object with the given parent, and optionally set the name. This command is generally used only by programmers, as it always creates a real object and does not create a frob instance, and it will create any type of object, not just a VR object. In general the command ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>, " is used instead."], #[['links, #[["@new", "$help_cmd_new"]]]]]>;
update objvar
Updating objvar $help_cmd_bugs<$has_name>,name

object $help_cmd_bugs;
var $has_name name = ['prop, "@bugs|@pr|@problems", "@bugs|@pr|@problems"];
update objvar
Updating objvar $help_obj_mail_list<$help_node>,body

object $help_obj_mail_list;
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The Mail List is a generic recipient for mail. To create a mailing list simply spawn a new object from $mail_list, and name it as appropriate for your list. You can configure the following settings on a mailing list: mail-notify, mail-senders, mail-readers and inet-list. The first three settings can be set as logically true or false (i.e. anybody, everybody, nobody, etc), or they can be set to the token \"writers\", or they can be a list of objects. If they are the token \"writers\" it includes whoever is included as a writer. If it is a list of objects, only those objects are included. ", <$format, ["subj", [["level", "2"]], ["mail-notify"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "A list of people who will receive notification, if false or true no notification is made to anybody. ", <$format, ["subj", [["level", "2"]], ["mail-senders"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Who can send to the list, or if true anybody can send to the list. ", <$format, ["subj", [["level", "2"]], ["mail-readers"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Who who can read the list. If true anybody can read the list. ", <$format, ["subj", [["level", "2"]], ["inet-list"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Can be set to an email address. If so, it will treat this Mail List as an Internet Mailing List. This behaviour is special in that it will forward to the specified email address if mail is received from within the Virtual Environment--but if mail is received from the SMTP gateway it will be stored on the list as normal.", <$format, ["p", [], [], 'do_p]>, "To setup an internet list in this way, simply set this setting to be the internet list address, and also subscribe the SMTP name for the ColdCore list (list-<name>@domain) to the internet list. For this to work as an internet list hook, you must also setup SMTP forwarding from your operating system, or bind the SMTP port directly to port 25. More information on this can be found at: ", <$format, ["web", [["src", "http://www.cold.org/sitenames.html"], ["name", "http://www.cold.org/sitenames.html"]], [], 'do_web]>, <$format, ["p", [], [], 'do_p]>, "This setting can only be set by administrators, look for a mail-forward setting in the future, which will have configurable access restrictions."], #[]]>;
update objvar
Updating objvar $editor_parser<$editor_parser>,commands

object $editor_parser;
var $editor_parser commands = #[["ap?pend", 'append_cmd], ["a?fter", 'after_cmd], ["d?elete|e?rase", 'delete_cmd], ["done|quit", 'quit_cmd], ["h?elp", 'help_cmd], ["i?nsert", 'insert_cmd], ["line", 'line_cmd], ["l?ist|ls", 'list_cmd], ["m?ove|mv", 'move_cmd], ["save|comp?ile", 'save_cmd], ["store", 'store_cmd], ["sed|sub", 'subst_cmd], ["send|mail", 'send_cmd], ["c?opy|cp", 'copy_cmd], ["f?ill|w?rap", 'fill_cmd], ["j?oin", 'join_cmd]];
update objvar
Updating objvar $editor_parser<$editor_parser>,command_help

object $editor_parser;
var $editor_parser command_help = #[['insert_cmd, ["Syntax: i?nsert [<text>] OR '<text>", "", "Add <text> before current line.  You may also use a single-quote (') as a shortcut character.  If text does not exist you will be prompted for the input."]], ['after_cmd, ["Syntax: a?fter [<text>] OR _<text>", "", "Add <text> after current line.  You may also use an underscore (_) as a shortcut character.  If text does not exist you will be prompted for the input."]], ['append_cmd, ["Syntax: ap?pend <text> OR ,<text>", "", "Add <text> after current line.  You may also use a comma (,) as a shortcut character."]], ['delete_cmd, ["Syntax: d?elete [<range>]", "", "Delete <range> or current line."]], ['copy_cmd, ["Syntax: copy [<range>] [to] <line>", "", "Copy <range> of text or current line to <line>."]], ['quit_cmd, ["Syntax: done|quit", "", "Close editor without saving changes."]], ['fill_cmd, ["Syntax: fill <range> <line width>", "", "Fill <range> of lines to fit within <line width> appropriately (either by expanding or joining)."]], ['help_cmd, ["Syntax: help [<command>]", "", "Basic editor help."]], ['line_cmd, ["Syntax: line <line>", "", "Change the current line to <line>.  You can also use a period (.) as a shortcut character."]], ['move_cmd, ["Syntax: move [<range>] [to] <line>", "", "Move <range> or current line to <line>."]], ['list_cmd, ["Syntax: list [<range>] [-n?umbers]", "", "List <range> or all of edit buffer.  The option -n?umbers may be used to not specify line numbers."]], ['subst_cmd, ["Syntax: s?ub|sed <old> <new> [<range>] [<options>]", "", "Search for <old> and replace it with <new> in <range> (defaulting to the current line).  The character following the command is used as a seperator (a space in the example).  This allows for the sed-like syntax: s/old/new/. The command 'sed' will use strsed() with regular expressions, the command 'sub' or 's' will use strsub() with literal matching.  Options are any one of:", "", "        g      Globally match and replace (do it multiple times)", "        s      Single match and replace (do it only on the first occurance)", "        c      Case matters when matching.", "        i      Case doesn't matter when matching.", "", "Option defaults for sed are: si", "Option defaults for sub are: gi"]], ['save_cmd, ["Syntax: save|comp?ile [as] [<ref>]", "", "Save document, if arguments are given will save alternate copy."]], ['store_cmd, ["Syntax: store", "", "Store editor--do not save changes.  Editor can be resumed with @reedit."]], ['send_cmd, ["Syntax: send|mail <mail-recipient>", "", "Used to send current contents of editor to a mail recipient."]], ['join_cmd, ["Syntax: j?oin <range> \"<sep>\"", "", "Join <range> lines together as one line, seperated by <sep> (default as space)"]]];
new method
Adding public method $editor_session.join_cmd()

public method $editor_session.join_cmd() {
    arg cmd, tmpl, args;
    var range, width, sep, spos, epos;
    
    (> .perms(caller(), 'command) <);
    catch any
        range = ._parse_range(args.word(1));
    with
        return "Illegal range, can't join.";
    if (" " in args)
        sep = ((substr(args, (" " in args) + 1).trim()).unquote()) || " ";
    else
        sep = " ";
    [spos, epos] = range;
    text = (sublist(text, 1, spos - 1) + [join(sublist(text, spos, (epos - spos) + 1), sep)]) + sublist(text, epos + 1);
    modified = 1;
    line = spos;
    return ("Join completed. Current set to " + line) + ".";
};
new method
Replacing public method $editor_session.sed()

public method $editor_session.sed() {
    arg start, end, search, replace, opts;
    var x, line, changed;
    
    if (end > listlen(text))
        end = listlen(text);
    for x in [start .. end] {
        line = strsed(text[x], search, replace, opts);
        if (strcmp(line, text[x])) {
            text = replace(text, x, line);
            changed++;
        }
    }
    return changed;
};
new method
Replacing public method $editor_session.sub()

public method $editor_session.sub() {
    arg start, end, search, replace, opts;
    var x, line, changed, i;
    
    if (end > listlen(text))
        end = listlen(text);
    for x in [start .. end] {
        line = strsub(text[x], search, replace, opts);
        if (strcmp(line, text[x])) {
            text = replace(text, x, line);
            changed++;
        }
    }
    return changed;
};
add objvar
Adding objvar $adapter<$root>,credit

object $adapter;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $math<$root>,credit

object $math;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
new method
Adding public method $time.realm_time()

public method $time.realm_time() {
    arg realm, @season;
    var d, lt, hr, pm, min, tm;
    
    d = realm.get_setting("weather-time", $realm);
    lt = ((d[5]).local_time()) + (d[6]);
    hr = ((lt / 3600) + (d[6])) % 24;
    if (hr >= 12) {
        pm = "PM";
        if (hr > 12)
            hr -= 12;
    } else {
        pm = "AM";
    }
    min = (lt / 60) % 60;
    tm = strfmt("%2{0}r:%2{0}r ", hr, min) + pm;
    return [tm + (season ? ((" (" + (d[2])) + "time)") : ""), (d[3]).realm()];
};
add objvar
Adding objvar $heap<$root>,credit

object $heap;
var $root credit = ["Miroslav Silovic <silovic@zesoi.fer.hr>"];
new method
Adding public method $cml_lib.fmt_table()

public method $cml_lib.fmt_table() {
    arg cols, @contents;
    
    return (<$format, ["table", [["cols", cols]], contents, 'do_table]>);
};
new method
Adding public method $cml_lib.fmt_invoke()

public method $cml_lib.fmt_invoke() {
    arg object, method, name;
    
    return (<$format, ["invoke", [["object", object], ["method", method]], [name], 'do_invoke]>);
};
new method
Adding public method $cml_lib.fmt_subj()

public method $cml_lib.fmt_subj() {
    arg text, @level;
    
    [(level ?= 4)] = level;
    return (<$format, ["subj", [["level", level]], [text], 'do_subj]>);
};
new method
Adding public method $cml_lib.fmt_br()

public method $cml_lib.fmt_br() {
    return br;
};
new method
Adding public method $cml_lib.fmt_obj()

public method $cml_lib.fmt_obj() {
    arg context, object, name, @args;
    var opt, src;
    
    if (args) {
        [opt, (src ?= sender())] = args;
        return (<$format, ["obj", [["context", context], ["name", name], ["options", opt]], [object, src], 'do_obj]>);
    } else {
        return (<$format, ["obj", [["context", context], ["name", name]], [object], 'do_obj]>);
    }
};
new method
Adding public method $cml_lib.gen_join()

public method $cml_lib.gen_join() {
    arg list, @sep;
    
    [(sep ?= ", ")] = sep;
    return (<$generator, ["join", [["separator", sep]], list, 'gen_join]>);
};
new method
Adding public method $cml_lib.fmt_input()

public method $cml_lib.fmt_input() {
    arg @flags;
    
    return (<$format, ["input", flags, [], 'do_input]>);
};
new method
Adding public method $cml_lib.fmt_td()

public method $cml_lib.fmt_td() {
    arg contents, @flags;
    var spanning, color;
    
    return (<$format, ["td", flags, [contents], 'do_td]>);
};
new method
Adding public method $cml_lib.fmt_textarea()

public method $cml_lib.fmt_textarea() {
    arg contents, @flags;
    
    return (<$format, ["textarea", flags, [contents], 'do_textarea]>);
};
new method
Adding public method $cml_lib.fmt_tr()

public method $cml_lib.fmt_tr() {
    arg @contents;
    
    return (<$format, ["tr", [], contents, 'do_tr]>);
};
new method
Adding public method $cml_lib.fmt_pre()

public method $cml_lib.fmt_pre() {
    arg args;
    
    return (<$format, ["pre", [], [args], 'do_pre]>);
};
new method
Adding public method $cml_lib.fmt_quote()

public method $cml_lib.fmt_quote() {
    arg args;
    
    return (<$format, ["quote", [], [args], 'do_quote]>);
};
new method
Adding public method $cml_lib.fmt_b()

public method $cml_lib.fmt_b() {
    arg contents;
    
    return (<$format, ["b", [], [contents], 'do_b]>);
};
new method
Adding public method $cml_lib.fmt_href()

public method $cml_lib.fmt_href() {
    arg url, str;
    
    return (<$format, ["a", [["href", url]], [str], 'do_href]>);
};
new method
Adding public method $cml_lib.fmt_sep()

public method $cml_lib.fmt_sep() {
    return sep;
};
new method
Adding public method $cml_lib.fmt_p()

public method $cml_lib.fmt_p() {
    return p;
};
new method
Replacing public method $cml_lib.format_dfn_tag()

public method $cml_lib.format_dfn_tag() {
    arg args;
    
    return (<$format, ["dfn", [], args, 'do_dfn]>);
};
new method
Adding public method $cml_lib.gen_english()

public method $cml_lib.gen_english() {
    arg list;
    
    return (<$generator, ["english", [], list, 'gen_english]>);
};
new method
Adding public method $cml_lib.fmt_form()

public method $cml_lib.fmt_form() {
    arg form, @flags;
    
    return (<$format, ["form", flags, form, 'do_form]>);
};
new method
Replacing public method $cml_lib.format_td_tag()

public method $cml_lib.format_td_tag() {
    arg contents, @flags;
    var spanning, color;
    
    return (<$format, ["td", flags, [contents], 'do_td]>);
};
new method
Adding public method $cml_lib.fmt_dfn()

public method $cml_lib.fmt_dfn() {
    arg args;
    
    return (<$format, ["dfn", [], args, 'do_dfn]>);
};
new method
Adding public method $cml_lib.fmt_hr()

public method $cml_lib.fmt_hr() {
    arg @flags;
    
    if (flags)
        return (<$format, ["hr", flags, [], 'do_hr]>);
    return hr;
};
add objvar
Adding objvar $converters<$root>,credit

object $converters;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $security_lib<$root>,credit

object $security_lib;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
add objvar
Adding objvar $directories<$root>,credit

object $directories;
var $root credit = ["Brad Roberts <braddr@puremagic.com>", "Bruce Mitchener, Jr. <bruce@puremagic.com>"];
update objvar
Updating objvar $conditional_group<$group>,group

object $conditional_group;
var $group group = <$false_lock_frob, #[]>;
maintenance

object $root;
eval {
  del_method('__upgrade_handle_var);
};
old obj
Removing $owner_lock_frob...

old object $owner_lock_frob;