<?xml version="1.0"?>

<!DOCTYPE MOO [
 
<!ELEMENT MOO (OBJECT*)>
<!ELEMENT OBJECT (NAME, PROPERTY*, VERB*, OBJECT*)>
<!ELEMENT VERB (NAME, CODE)>
<!ELEMENT PROPERTY (NAME, VALUE?)>
<!ELEMENT CODE (#PCDATA)>
<!ELEMENT VALUE (#PCDATA)>
<!ELEMENT NAME (#PCDATA)>

<!ATTLIST OBJECT
  ID ID #REQUIRED
  FLAGS NMTOKENS #IMPLIED
  OWNER CDATA #REQUIRED
  LOCATION CDATA #REQUIRED
>
<!ATTLIST VERB
  OWNER CDATA #REQUIRED
  PERMS NMTOKENS #IMPLIED
  DOBJ CDATA #REQUIRED
  IOBJ CDATA #REQUIRED
  PREP CDATA #REQUIRED
>
<!ATTLIST PROPERTY
  OWNER CDATA #REQUIRED
  PERMS NMTOKENS #IMPLIED
>

]>
<!-- ** LambdaMOO Database, Format Version 4 ** -->
<MOO>
  <OBJECT ID="obj1" FLAGS="f r" OWNER="obj2" LOCATION="obj-1">
    <NAME>Root Class</NAME>
    <PROPERTY OWNER="obj2" PERMS="c">
      <NAME>key</NAME>
      <VALUE>0</VALUE>
    </PROPERTY>
    <PROPERTY OWNER="obj2" PERMS="c r">
      <NAME>aliases</NAME>
      <VALUE>{}</VALUE>
    </PROPERTY>
    <PROPERTY OWNER="obj2" PERMS="c r">
      <NAME>description</NAME>
      <VALUE>""</VALUE>
    </PROPERTY>
    <PROPERTY OWNER="obj36" PERMS="r">
      <NAME>object_size</NAME>
      <VALUE>{21823, 919123664}</VALUE>
    </PROPERTY>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>initialize</NAME>
      <CODE>
        if (typeof(this.owner.owned_objects) == LIST)
        this.owner.owned_objects = setadd(this.owner.owned_objects, this);
        endif
        if ((caller == this) || $perm_utils:controls(caller_perms(), this))
        if (is_clear_property(this, "object_size"))
        "If this isn't clear, then we're being hacked.";
        this.object_size = {0, 0};
        endif
        this.key = 0;
        else
        return E_PERM;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>recycle</NAME>
      <CODE>
        if ((caller == this) || $perm_utils:controls(caller_perms(), this))
        try
        if ((typeof(this.owner.owned_objects) == LIST) &amp;&amp; (!is_clear_property(this.owner, "owned_objects")))
        this.owner.owned_objects = setremove(this.owner.owned_objects, this);
        $recycler.lost_souls = setadd($recycler.lost_souls, this);
        endif
        except (ANY)
        "Oy, doesn't have a .owned_objects??, or maybe .owner is $nothing";
        "Should probably do something...like send mail somewhere.";
        endtry
        else
        return E_PERM;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>set_name</NAME>
      <CODE>
        "set_name(newname) attempts to change this.name to newname";
        "  =&gt; E_PERM   if you don't own this or aren't its parent, or are a player trying to do an end-run around $player_db...";
        if ((!caller_perms().wizard) &amp;&amp; (is_player(this) || ((caller_perms() != this.owner) &amp;&amp; (this != caller))))
        return E_PERM;
        else
        return (typeof(e = `this.name = args[1] ! ANY') != ERR) || e;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>title</NAME>
      <CODE>
        return this.name;
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>titlec</NAME>
      <CODE>
        return `this.namec ! E_PROPNF =&gt; $string_utils:capitalize(this:title())';
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>set_aliases</NAME>
      <CODE>
        "set_aliases(alias_list) attempts to change this.aliases to alias_list";
        "  =&gt; E_PERM   if you don't own this or aren't its parent";
        "  =&gt; E_TYPE   if alias_list is not a list";
        "  =&gt; E_INVARG if any element of alias_list is not a string";
        "  =&gt; 1        if aliases are set exactly as expected (default)";
        "  =&gt; 0        if aliases were set differently than expected";
        "              (children with custom :set_aliases should be aware of this)";
        if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
        return E_PERM;
        elseif (typeof(aliases = args[1]) != LIST)
        return E_TYPE;
        else
        for s in (aliases)
        if (typeof(s) != STR)
        return E_INVARG;
        endif
        endfor
        this.aliases = aliases;
        return 1;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>match</NAME>
      <CODE>
        c = this:contents();
        return $string_utils:match(args[1], c, "name", c, "aliases");
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>match_object</NAME>
      <CODE>
        ":match_object(string [,who])";
        args[2..1] = {this};
        return $string_utils:match_object(@args);
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>set_description</NAME>
      <CODE>
        "set_description(newdesc) attempts to change this.description to newdesc";
        "  =&gt; E_PERM   if you don't own this or aren't its parent";
        if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
        return E_PERM;
        elseif (typeof(desc = args[1]) in {LIST, STR})
        this.description = desc;
        return 1;
        else
        return E_TYPE;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>description</NAME>
      <CODE>
        return this.description;
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>look_self</NAME>
      <CODE>
        desc = this:description();
        if (desc)
        player:tell_lines(desc);
        else
        player:tell("You see nothing special.");
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>notify</NAME>
      <CODE>
        if (is_player(this))
        notify(this, args[1]);
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>tell</NAME>
      <CODE>
        this:notify(tostr(@args));
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>tell_lines</NAME>
      <CODE>
        lines = args[1];
        if (typeof(lines) == LIST)
        for line in (lines)
        this:tell(line);
        endfor
        else
        this:tell(lines);
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>accept</NAME>
      <CODE>
        set_task_perms(caller_perms());
        return this:acceptable(@args);
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>moveto</NAME>
      <CODE>
        set_task_perms(this.owner);
        return `move(this, args[1]) ! ANY';
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>eject eject_nice eject_basic</NAME>
      <CODE>
        "eject(victim) --- usable by the owner of this to remove victim from this.contents.  victim goes to its home if different from here, or $nothing or $player_start according as victim is a player.";
        "eject_basic(victim) --- victim goes to $nothing or $player_start according as victim is a player; victim:moveto is not called.";
        what = args[1];
        nice = verb != "eject_basic";
        perms = caller_perms();
        if ((!perms.wizard) &amp;&amp; (perms != this.owner))
        raise(E_PERM);
        elseif ((!(what in this.contents)) || what.wizard)
        return 0;
        endif
        if ((((nice &amp;&amp; $object_utils:has_property(what, "home")) &amp;&amp; (typeof(where = what.home) == OBJ)) &amp;&amp; (where != this)) &amp;&amp; (is_player(what) ? `where:accept_for_abode(what) ! ANY' | `where:acceptable(what) ! ANY'))
        else
        where = is_player(what) ? $player_start | $nothing;
        endif
        fork (0)
        if (what.location == this)
        "It didn't move when we asked it to, or :moveto is broken. Force it.";
        move(what, where);
        endif
        endfork
        return nice ? `what:moveto(where) ! ANY' | `move(what, where) ! ANY';
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>is_unlocked_for</NAME>
      <CODE>
        return (this.key == 0) || $lock_utils:eval_key(this.key, args[1]);
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>huh</NAME>
      <CODE>
        set_task_perms((caller_perms() != #-1) ? caller_perms() | player);
        $command_utils:do_huh(verb, args);
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>set_message</NAME>
      <CODE>
        ":set_message(msg_name,new_value)";
        "Does the actual dirty work of @&lt;msg_name&gt; object is &lt;new_value&gt;";
        "changing the raw value of the message msg_name to be new_value.";
        "Both msg_name and new_value should be strings, though their interpretation is up to the object itself.";
        " =&gt; error value (use E_PROPNF if msg_name isn't recognized)";
        " =&gt; string error message if something else goes wrong.";
        " =&gt; 1 (true non-string) if the message is successfully set";
        " =&gt; 0 (false non-error) if the message is successfully `cleared'";
        if (!((caller == this) || $perm_utils:controls(caller_perms(), this)))
        return E_PERM;
        else
        return `this.(args[1] + "_msg") = args[2] ! ANY' &amp;&amp; 1;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>do_examine</NAME>
      <CODE>
        "do_examine(examiner)";
        "the guts of examine";
        "call a series of verbs and report their return values to the player";
        who = args[1];
        "if (caller == this || caller == who)";
        if (caller == who)
        "set_task_perms();";
        who:notify_lines(this:examine_names(who) || {});
        "this:examine_names(who);";
        who:notify_lines(this:examine_owner(who) || {});
        "this:examine_owner(who);";
        who:notify_lines(this:examine_desc(who) || {});
        "this:examine_desc(who);";
        who:notify_lines(this:examine_key(who) || {});
        "this:examine_key(who);";
        who:notify_lines(this:examine_contents(who) || {});
        who:notify_lines(this:examine_verbs(who) || {});
        else
        return E_PERM;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>examine_key</NAME>
      <CODE>
        "examine_key(examiner)";
        "return a list of strings to be told to the player, indicating what the key on this type of object means, and what this object's key is set to.";
        "the default will only tell the key to a wizard or this object's owner.";
        who = args[1];
        if (((caller == this) &amp;&amp; $perm_utils:controls(who, this)) &amp;&amp; (this.key != 0))
        return {tostr("Key:  ", $lock_utils:unparse_key(this.key))};
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>examine_names</NAME>
      <CODE>
        "examine_names(examiner)";
        "Return a list of strings to be told to the player, indicating the name and aliases (and, by default, the object number) of this.";
        return {tostr(this.name, " (aka ", $string_utils:english_list({tostr(this), @this.aliases}), ")")};
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>examine_desc</NAME>
      <CODE>
        "examine_desc(who) - return the description, probably";
        "who is the player examining";
        "this should probably go away";
        desc = this:description();
        if (desc)
        if (typeof(desc) != LIST)
        desc = {desc};
        endif
        return desc;
        else
        return {"(No description set.)"};
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>examine_contents</NAME>
      <CODE>
        "examine_contents(examiner)";
        "by default, calls :tell_contents.";
        "Should probably go away.";
        who = args[1];
        if (caller == this)
        try
        this:tell_contents(this.contents, this.ctype);
        except (ANY)
        "Just ignore it. We shouldn't care about the contents unless the object wants to tell us about them via :tell_contents ($container, $room)";
        endtry
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>examine_verbs</NAME>
      <CODE>
        "Return a list of strings to be told to the player.  Standard format says \"Obvious verbs:\" followed by a series of lines explaining syntax for each usable verb.";
        if (caller != this)
        return E_PERM;
        endif
        who = args[1];
        name = dobjstr;
        vrbs = {};
        commands_ok = `this:examine_commands_ok(who) ! ANY =&gt; 0';
        dull_classes = {$root_class, $room, $player, $prog, $builder};
        what = this;
        hidden_verbs = this:hidden_verbs(who);
        while (what != $nothing)
        $command_utils:suspend_if_needed(0);
        if (!(what in dull_classes))
        for i in [1..length(verbs(what))]
        $command_utils:suspend_if_needed(0);
        info = verb_info(what, i);
        syntax = verb_args(what, i);
        if (this:examine_verb_ok(what, i, info, syntax, commands_ok, hidden_verbs))
        {dobj, prep, iobj} = syntax;
        if (syntax == {"any", "any", "any"})
        prep = "none";
        endif
        if (prep != "none")
        for x in ($string_utils:explode(prep, "/"))
        if (length(x) &lt;= length(prep))
        prep = x;
        endif
        endfor
        endif
        "This is the correct way to handle verbs ending in *";
        vname = info[3];
        while (j = index(vname, "* "))
        vname = tostr(vname[1..j - 1], "&lt;anything&gt;", vname[j + 1..$]);
        endwhile
        if (vname[$] == "*")
        vname = vname[1..$ - 1] + "&lt;anything&gt;";
        endif
        vname = strsub(vname, " ", "/");
        rest = "";
        if (prep != "none")
        rest = " " + ((prep == "any") ? "&lt;anything&gt;" | prep);
        if (iobj != "none")
        rest = tostr(rest, " ", (iobj == "this") ? name | "&lt;anything&gt;");
        endif
        endif
        if (dobj != "none")
        rest = tostr(" ", (dobj == "this") ? name | "&lt;anything&gt;", rest);
        endif
        vrbs = setadd(vrbs, ("  " + vname) + rest);
        endif
        endfor
        endif
        what = parent(what);
        endwhile
        if ($code_utils:verb_or_property(this, "help_msg"))
        vrbs = {@vrbs, tostr("  help ", dobjstr)};
        endif
        return vrbs &amp;&amp; {"Obvious verbs:", @vrbs};
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>get_message</NAME>
      <CODE>
        ":get_message(msg_name)";
        "Use this to obtain a given user-customizable message's raw value, i.e., the value prior to any pronoun-substitution or incorporation of any variant elements --- the value one needs to supply to :set_message().";
        "=&gt; error (use E_PROPNF if msg_name isn't recognized)";
        "=&gt; string or list-of-strings raw value";
        "=&gt; {2, @(list of {msg_name_n,rawvalue_n} pairs to give to :set_message)}";
        "=&gt; {1, other kind of raw value}";
        "=&gt; {E_NONE, error message} ";
        if (!((caller == this) || $perm_utils:controls(caller_perms(), this)))
        return E_PERM;
        elseif (((t = typeof(msg = `this.(args[1] + "_msg") ! ANY')) in {ERR, STR}) || (((t == LIST) &amp;&amp; msg) &amp;&amp; (typeof(msg[1]) == STR)))
        return msg;
        else
        return {1, msg};
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>room_announce*_all_but</NAME>
      <CODE>
        try
        this.location:(verb)(@args);
        except (ANY)
        endtry
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>init_for_core</NAME>
      <CODE>
        if (caller_perms().wizard)
        vnum = 1;
        while (vnum &lt;= length(verbs(this)))
        $command_utils:suspend_if_needed(0);
        info = verb_info(this, vnum)[3];
        if (index(info, "(old)"))
        delete_verb(this, vnum);
        else
        vnum = vnum + 1;
        endif
        endwhile
        if (this == $root_class)
        set_verb_code(this, "initialize", verb_code(this, "initialize(core)"));
        delete_verb(this, "initialize(core)");
        endif
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>contents</NAME>
      <CODE>
        "Returns a list of the objects that are apparently inside this one.  Don't confuse this with .contents, which is a property kept consistent with .location by the server.  This verb should be used in `VR' situations, for instance when looking in a room, and does not necessarily have anything to do with the value of .contents (although the default implementation does).  `Non-VR' commands (like @contents) should look directly at .contents.";
        return this.contents;
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>examine_verb_ok</NAME>
      <CODE>
        "examine_verb_ok(loc, index, info, syntax, commands_ok, hidden_verbs)";
        "loc is the object that defines the verb; index is which verb on the object; info is verb_info; syntax is verb_args; commands_ok is determined by this:commands_ok, probably, but passed in so we don't have to calculate it for each verb.";
        "hidden_verbs is passed in for the same reasons.  It should be a list, each of whose entries is either a string with the full verb name to be hidden (e.g., \"d*rop th*row\") or a list of the form {verb location, full verb name, args}.";
        if ((caller == this) || $perm_utils:controls(caller_perms(), this))
        {loc, index, info, syntax, commands_ok, hidden_verbs} = args;
        vname = info[3];
        return (((((syntax[2..3] != {"none", "this"}) &amp;&amp; (!index(vname, "("))) &amp;&amp; (commands_ok || ("this" in syntax))) &amp;&amp; `verb_code(loc, index) ! ANY') &amp;&amp; (!(vname in hidden_verbs))) &amp;&amp; (!({loc, vname, syntax} in hidden_verbs));
        else
        return E_PERM;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>is_listening</NAME>
      <CODE>
        "return 1 if the object can hear a :tell, or cares. Useful for active objects that want to stop when nothing is listening.";
        return 0;
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>hidden_verbs</NAME>
      <CODE>
        "hidden_verbs(who)";
        "returns a list of verbs on this that should be hidden from examine";
        "the player who's examining is passed in, so objects can hide verbs from specific players";
        "verbs are returned as {location, full_verb_name, args} or just full_verb_name.  full_verb name is what shows up in verb_info(object, verb)[2], for example \"d*op th*row\".";
        if ((caller == this) || $perm_utils:controls(caller_perms(), this))
        hidden = {};
        what = this;
        while (what != $nothing)
        for i in [1..length(verbs(what))]
        info = verb_info(what, i);
        if (!index(info[2], "r"))
        hidden = setadd(hidden, {what, info[3], verb_args(what, i)});
        endif
        endfor
        what = parent(what);
        endwhile
        return hidden;
        else
        return E_PERM;
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>examine_owner</NAME>
      <CODE>
        "examine_owner(examiner)";
        "Return a list of strings to be told to the player, indicating who owns this.";
        return {tostr("Owned by ", this.owner.name, ".")};
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>announce*_all_but</NAME>
      <CODE>
        return;
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>tell_lines_suspended</NAME>
      <CODE>
        lines = args[1];
        if (typeof(lines) == LIST)
        for line in (lines)
        this:tell(line);
        $command_utils:suspend_if_needed(0);
        endfor
        else
        this:tell(lines);
        endif
      </CODE>
    </VERB>
    <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
      <NAME>acceptable</NAME>
      <CODE>
        return 0;
        "intended as a 'quiet' way to determine if :accept will succeed. Currently, some objects have a noisy :accept verb since it is the only thing that a builtin move() call is guaranteed to call.";
        "if you want to tell, before trying, whether :accept will fail, use :acceptable instead. Normally, they'll do the same thing.";
      </CODE>
    </VERB>
    <OBJECT ID="obj0" FLAGS="r" OWNER="obj2" LOCATION="obj-1">
      <NAME>The System Object</NAME>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>builder</NAME>
        <VALUE>#4</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>login</NAME>
        <VALUE>#10</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>last_huh</NAME>
        <VALUE>#11</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>guest_log</NAME>
        <VALUE>#12</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>last_restart_time</NAME>
        <VALUE>923782066</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>biglist</NAME>
        <VALUE>#13</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>big_mail_recipient</NAME>
        <VALUE>#14</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>limbo</NAME>
        <VALUE>#15</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>registration_db</NAME>
        <VALUE>#16</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>new_player_log</NAME>
        <VALUE>#17</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>verb_help</NAME>
        <VALUE>#18</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>core_help</NAME>
        <VALUE>#19</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>prog_help</NAME>
        <VALUE>#22</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>wiz_help</NAME>
        <VALUE>#23</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>shutdown_task</NAME>
        <VALUE>E_NONE</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>wiz_utils</NAME>
        <VALUE>#24</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>site_db</NAME>
        <VALUE>#25</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>math_utils</NAME>
        <VALUE>#26</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>set_utils</NAME>
        <VALUE>#27</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>builtin_function_help</NAME>
        <VALUE>#28</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>new_prog_log</NAME>
        <VALUE>#29</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>generic_help</NAME>
        <VALUE>#30</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>guest</NAME>
        <VALUE>#31</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>spell</NAME>
        <VALUE>#32</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>seq_utils</NAME>
        <VALUE>#33</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>quota_log</NAME>
        <VALUE>#34</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>you</NAME>
        <VALUE>#35</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>max_seconds</NAME>
        <VALUE>5</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>max_ticks</NAME>
        <VALUE>30000</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>hacker</NAME>
        <VALUE>#36</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>generic_db</NAME>
        <VALUE>#37</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>shutdown_message</NAME>
        <VALUE>"Wizard (#2): updated"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>shutdown_time</NAME>
        <VALUE>919226973</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>no_one</NAME>
        <VALUE>#38</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>player_db</NAME>
        <VALUE>#39</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>class_registry</NAME>
        <VALUE>{{"generics", "Generic objects intended for use as the parents of new objects", {#3, #7, #5, #9, #54, #8, #1, #6, #58, #57, #50, #45, #46}}, {"utilities", "Objects holding useful general-purpose verbs", {#20, #55, #24, #27, #41, #26, #43, #51, #52, #53, #56, #42, #21, #33, #13, #80, #82, #59, #92, #94}}}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>player_class</NAME>
        <VALUE>#40</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>gender_utils</NAME>
        <VALUE>#41</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>trig_utils</NAME>
        <VALUE>#26</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>time_utils</NAME>
        <VALUE>#43</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>editor_help</NAME>
        <VALUE>#44</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>mail_recipient</NAME>
        <VALUE>#45</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>mail_agent</NAME>
        <VALUE>#46</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>mail_editor</NAME>
        <VALUE>#47</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>note_editor</NAME>
        <VALUE>#48</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>verb_editor</NAME>
        <VALUE>#49</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>generic_editor</NAME>
        <VALUE>#50</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>match_utils</NAME>
        <VALUE>#51</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>object_utils</NAME>
        <VALUE>#52</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>lock_utils</NAME>
        <VALUE>#53</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>gripe_recipients</NAME>
        <VALUE>{#2}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>letter</NAME>
        <VALUE>#54</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>dump_interval</NAME>
        <VALUE>3600</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>list_utils</NAME>
        <VALUE>#55</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>command_utils</NAME>
        <VALUE>#56</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>player</NAME>
        <VALUE>#6</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>wiz</NAME>
        <VALUE>#57</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>prog</NAME>
        <VALUE>#58</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>code_utils</NAME>
        <VALUE>#59</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>help</NAME>
        <VALUE>#60</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>nothing</NAME>
        <VALUE>#-1</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>failed_match</NAME>
        <VALUE>#-3</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>ambiguous_match</NAME>
        <VALUE>#-2</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>perm_utils</NAME>
        <VALUE>#42</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>building_utils</NAME>
        <VALUE>#21</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>string_utils</NAME>
        <VALUE>#20</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>news</NAME>
        <VALUE>#61</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>note</NAME>
        <VALUE>#9</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>container</NAME>
        <VALUE>#8</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>thing</NAME>
        <VALUE>#5</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>exit</NAME>
        <VALUE>#7</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>room</NAME>
        <VALUE>#3</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>player_start</NAME>
        <VALUE>#62</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>root_class</NAME>
        <VALUE>#1</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>recycler</NAME>
        <VALUE>#63</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>garbage</NAME>
        <VALUE>#64</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>mail_options</NAME>
        <VALUE>#65</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>edit_options</NAME>
        <VALUE>#66</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>display_options</NAME>
        <VALUE>#67</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>generic_options</NAME>
        <VALUE>#68</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>maxint</NAME>
        <VALUE>2147483647</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>minint</NAME>
        <VALUE>-2147483648</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>error</NAME>
        <VALUE>#69</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>newt_log</NAME>
        <VALUE>#70</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>toad_log</NAME>
        <VALUE>#70</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>site_log</NAME>
        <VALUE>#70</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>housekeeper</NAME>
        <VALUE>#71</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>network</NAME>
        <VALUE>#72</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>generic_biglist_home</NAME>
        <VALUE>#73</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>feature</NAME>
        <VALUE>#74</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>local</NAME>
        <VALUE>#-1</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>gopher</NAME>
        <VALUE>#75</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>prog_options</NAME>
        <VALUE>#76</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>build_options</NAME>
        <VALUE>#77</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>generic_utils</NAME>
        <VALUE>#78</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>quota_utils</NAME>
        <VALUE>#79</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>paranoid_db</NAME>
        <VALUE>#80</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>no_connect_message</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>sysobj</NAME>
        <VALUE>#0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>byte_quota_utils</NAME>
        <VALUE>#79</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>object_quota_utils</NAME>
        <VALUE>#81</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>server_options</NAME>
        <VALUE>#82</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>feature_warehouse</NAME>
        <VALUE>#83</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>builder_help</NAME>
        <VALUE>#84</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>mail_help</NAME>
        <VALUE>#85</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>ftp</NAME>
        <VALUE>#86</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>password_verifier</NAME>
        <VALUE>#87</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>new_password_log</NAME>
        <VALUE>#-1</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>frand_class</NAME>
        <VALUE>#89</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>mail_recipient_class</NAME>
        <VALUE>#40</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>stage_talk</NAME>
        <VALUE>#90</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>pasting_feature</NAME>
        <VALUE>#91</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>core_history</NAME>
        <VALUE>{{"LambdaMOO", "1.8.0r5", 919117596}}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>matrix_utils</NAME>
        <VALUE>#92</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>force_input_count</NAME>
        <VALUE>5085382</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>frand_help</NAME>
        <VALUE>#93</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>convert_utils</NAME>
        <VALUE>#94</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>gendered_object</NAME>
        <VALUE>#88</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c">
        <NAME>key</NAME>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>aliases</NAME>
        <VALUE>{"The System Object"}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>description</NAME>
        <VALUE>"The known universe."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>object_size</NAME>
        <VALUE>{21070, 919123664}</VALUE>
      </PROPERTY>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>do_login_command</NAME>
        <CODE>
          "...This code should only be run as a server task...";
          if (callers())
          return E_PERM;
          endif
          if (typeof(h = $network:incoming_connection(player)) == OBJ)
          "connected to an object";
          return h;
          elseif (h)
          return 0;
          endif
          host = $string_utils:connection_hostname(connection_name(player));
          if ($login:redlisted(host))
          boot_player(player);
          server_log(tostr("REDLISTED: ", player, " from ", host));
          return 0;
          endif
          if (!$login:maybe_limit_commands())
          args = $login:parse_command(@args);
          return $login:(args[1])(@listdelete(args, 1));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>server_started</NAME>
        <CODE>
          if (!callers())
          $last_restart_time = time();
          $network:server_started();
          $login:server_started();
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>core_objects</NAME>
        <CODE>
          saved = {#0};
          for p in (properties(#0))
          v = #0.(p);
          if ((typeof(v) == OBJ) &amp;&amp; valid(v))
          saved = setadd(saved, v);
          endif
          endfor
          for o in (saved)
          p = parent(o);
          while (valid(p))
          saved = setadd(saved, p);
          p = parent(p);
          endwhile
          endfor
          return $list_utils:sort(saved);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>init_for_core</NAME>
        <CODE>
          if (caller_perms().wizard)
          pass();
          if ("server_started" in verbs(this))
          code = {"if (!callers())", "$last_restart_time = time(); $network:server_started(); $login:server_started(); endif"};
          set_verb_code(this, "server_started", code);
          endif
          if ("uptime_since" in verbs(this))
          delete_verb(this, "uptime_since");
          endif
          if ("do_command" in verbs(this))
          delete_verb(this, "do_command");
          endif
          `delete_verb(this, "checkpoint_finished") ! E_VERBNF';
          $core_history = {{$network.MOO_name, server_version(), time()}, @$core_history};
          $shutdown_message = "";
          $shutdown_time = 0;
          $dump_interval = 3600;
          $gripe_recipients = {player};
          $class_registry = {{"generics", "Generic objects intended for use as the parents of new objects", {$room, $exit, $thing, $note, $letter, $container, $root_class, $player, $prog, $wiz, $generic_editor, $mail_recipient, $mail_agent}}, {"utilities", "Objects holding useful general-purpose verbs", children($generic_utils)}};
          `set_verb_code(this, "user_connected", verb_code(this, "user_connected(core)")) ! ANY';
          `delete_verb(this, "user_connected(core)") ! ANY';
          `set_verb_code(this, "user_reconnected", verb_code(this, "user_reconnected(core)")) ! ANY';
          `delete_verb(this, "user_reconnected(core)") ! ANY';
          for v in ({"do_login_command", "server_started"})
          c = {};
          for i in (verb_code(this, v))
          c = {@c, strsub(i, "$local.login", "$login")};
          endfor
          set_verb_code(#0, v, c);
          endfor
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>user_created user_connected</NAME>
        <CODE>
          "Copied from The System Object (#0):user_connected by Slartibartfast (#4242) Sun May 21 18:14:16 1995 PDT";
          if (callers())
          return;
          endif
          user = args[1];
          set_task_perms(user);
          try
          user.location:confunc(user);
          user:confunc();
          except id (ANY)
          user:tell("Confunc failed: ", id[2], ".");
          for tb in (id[4])
          user:tell("... called from ", tb[4], ":", tb[2], (tb[4] != tb[1]) ? tostr(" (this == ", tb[1], ")") | "", ", line ", tb[6]);
          endfor
          user:tell("(End of traceback)");
          endtry
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>user_disconnected user_client_disconnected</NAME>
        <CODE>
          if (callers())
          return;
          endif
          if (args[1] &lt; #0)
          "not logged in user.  probably should do something clever here involving Carrot's no-spam hack.  --yduJ";
          return;
          endif
          user = args[1];
          user.last_disconnect_time = time();
          set_task_perms(user);
          where = user.location;
          `user:disfunc() ! ANY =&gt; 0';
          if (user.location != where)
          `where.location:disfunc(user) ! ANY =&gt; 0';
          endif
          `user.location:disfunc(user) ! ANY =&gt; 0';
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_chparent chparent</NAME>
        <CODE>
          "chparent(object, new-parent) -- see help on the builtin.";
          who = caller_perms();
          {what, papa} = args;
          if (typeof(what) != OBJ)
          retval = E_TYPE;
          elseif (!valid(what))
          retval = E_INVARG;
          elseif (typeof(papa) != OBJ)
          retval = E_TYPE;
          elseif ((!valid(papa)) &amp;&amp; (papa != #-1))
          retval = E_INVIND;
          elseif (!$perm_utils:controls(who, what))
          retval = E_PERM;
          elseif ((is_player(what) &amp;&amp; (!$object_utils:isa(papa, $player_class))) &amp;&amp; (!who.wizard))
          retval = E_PERM;
          elseif ((is_player(what) &amp;&amp; (!$object_utils:isa(what, $player_class))) &amp;&amp; (!who.wizard))
          retval = E_PERM;
          elseif ((children(what) &amp;&amp; $object_utils:isa(what, $player_class)) &amp;&amp; (!$object_utils:isa(papa, $player_class)))
          retval = E_PERM;
          elseif ((!valid(papa)) || ($perm_utils:controls(who, papa) || papa.f))
          retval = `chparent(@args) ! ANY';
          else
          retval = E_PERM;
          endif
          return ((typeof(retval) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(retval) | retval;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_add_verb add_verb</NAME>
        <CODE>
          "add_verb() -- see help on the builtin for more information. This verb is called by the server when $server_options.protect_add_verb exists and is true and caller_perms() are not wizardly.";
          who = caller_perms();
          {what, info, verbargs} = args;
          if (typeof(what) != OBJ)
          retval = E_TYPE;
          elseif (!valid(what))
          retval = E_INVARG;
          elseif ((!$perm_utils:controls(who, what)) &amp;&amp; (!what.w))
          "caller_perms() is not allowed to hack on the object in question";
          retval = E_PERM;
          elseif (!$perm_utils:controls(who, info[1]))
          "caller_perms() is not permitted to add a verb with the specified owner.";
          retval = E_PERM;
          elseif (index(info[2], "w") &amp;&amp; (!$server_options.permit_writable_verbs))
          retval = E_INVARG;
          elseif (!$quota_utils:verb_addition_permitted(who))
          retval = E_QUOTA;
          elseif (((what.owner != who) &amp;&amp; (!who.wizard)) &amp;&amp; (!$quota_utils:verb_addition_permitted(what.owner)))
          retval = E_QUOTA;
          elseif (!who.programmer)
          retval = E_PERM;
          else
          "we now know that the caller's perms control the object or the object is writable, and we know that the caller's perms control the prospective verb owner (by more traditional means)";
          retval = `add_verb(@args) ! ANY';
          endif
          return ((typeof(retval) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(retval) | retval;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_add_property add_property</NAME>
        <CODE>
          "add_property() -- see help on the builtin for more information. This verb is called by the server when $server_options.protect_add_property exists and is true and caller_perms() are not wizardly.";
          who = caller_perms();
          {what, propname, value, info} = args;
          if (typeof(what) != OBJ)
          retval = E_TYPE;
          elseif (!valid(what))
          retval = E_INVARG;
          elseif ((!$perm_utils:controls(who, what)) &amp;&amp; (!what.w))
          retval = E_PERM;
          elseif (!$perm_utils:controls(who, info[1]))
          retval = E_PERM;
          elseif (!$quota_utils:property_addition_permitted(who))
          retval = E_QUOTA;
          elseif (((what.owner != who) &amp;&amp; (!who.wizard)) &amp;&amp; (!$quota_utils:property_addition_permitted(what.owner)))
          retval = E_QUOTA;
          "elseif (!who.programmer)";
          "  return E_PERM;     I wanted to do this, but $builder:@newmessage relies upon nonprogs being able to call add_property.  --Nosredna";
          elseif ((propname in {"object_size", "size_quota", "queued_task_limit"}) &amp;&amp; (!who.wizard))
          retval = E_PERM;
          else
          "we now know that the caller's perms control the object (or the object is writable), and that the caller's perms are permitted to control the new property's owner.";
          retval = `add_property(@args) ! ANY';
          endif
          return ((typeof(retval) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(retval) | retval;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_recycle recycle</NAME>
        <CODE>
          "recycle(object) -- see help on the builtin. This verb is called by the server when $server_options.protect_recycle exists and is true and caller_perms() are not wizardly.";
          if (!valid(what = args[1]))
          retval = E_INVARG;
          elseif (!$perm_utils:controls(who = caller_perms(), what))
          retval = E_PERM;
          elseif ((p = is_player(what)) &amp;&amp; (!who.wizard))
          for p in ($wiz_utils:connected_wizards_unadvertised())
          p:tell($string_utils:pronoun_sub("%N (%#) is currently trying to recycle %t (%[#t])", who, what));
          endfor
          retval = E_PERM;
          else
          if (p)
          $wiz_utils:unset_player(what);
          endif
          retval = `recycle(what) ! ANY';
          if (typeof(retval) != ERR)
          $recycler:kill_all_tasks(what);
          endif
          endif
          return ((typeof(retval) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(retval) | retval;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>user_reconnected</NAME>
        <CODE>
          if (callers())
          return;
          endif
          if ($object_utils:isa(user = args[1], $guest))
          "from $guest:boot";
          oldloc = user.location;
          move(user, $nothing);
          "..force enterfunc to be called so that the newbie gets a room description.";
          move(user, user.home);
          user:do_reset();
          if ($object_utils:isa(oldloc, $room))
          oldloc:announce("In the distance you hear someone's alarm clock going off.");
          if (oldloc != user.location)
          oldloc:announce(user.name, " wavers and vanishes into insubstantial mist.");
          else
          oldloc:announce(user.name, " undergoes a wrenching personality shift.");
          endif
          endif
          set_task_perms(user);
          `user:confunc() ! ANY';
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_set_verb_info set_verb_info</NAME>
        <CODE>
          "set_verb_info() -- see help on the builtin for more information. This verb is called by the server when $server_options.protect_set_verb_info exists and is true and caller_perms() are not wizardly.";
          {o, v, i} = args;
          if (typeof(vi = `verb_info(o, v) ! ANY') == ERR)
          "probably verb doesn't exist";
          retval = vi;
          elseif (!$perm_utils:controls(cp = caller_perms(), vi[1]))
          "perms don't control the current verb owner";
          retval = E_PERM;
          elseif ((typeof(i) != LIST) || (typeof(no = i[1]) != OBJ))
          "info is malformed";
          retval = E_TYPE;
          elseif ((!valid(no)) || (!is_player(no)))
          "invalid new verb owner";
          retval = E_INVARG;
          elseif (!$perm_utils:controls(cp, no))
          "perms don't control prospective verb owner";
          retval = E_PERM;
          elseif (index(i[2], "w") &amp;&amp; (!`$server_options.permit_writable_verbs ! E_PROPNF, E_INVIND =&gt; 1'))
          retval = E_INVARG;
          else
          retval = `set_verb_info(o, v, i) ! ANY';
          endif
          return ((typeof(retval) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(retval) | retval;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_match match</NAME>
        <CODE>
          m = `match(@args) ! ANY';
          return ((typeof(m) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(m) | m;
          if ((length(args[1]) &gt; 256) &amp;&amp; index(args[2], "*"))
          return E_INVARG;
          else
          return match(@args);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_rmatch rmatch</NAME>
        <CODE>
          r = `rmatch(@args) ! ANY';
          return ((typeof(r) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(r) | r;
          if ((length(args[1]) &gt; 256) &amp;&amp; index(args[2], "*"))
          return E_INVARG;
          else
          return rmatch(@args);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>do_out_of_band_command doobc</NAME>
        <CODE>
          "do_out_of_band_command -- a cheap and very dirty do_out_of_band verb.  Forwards to verb on player with same name if it exists, otherwise forwards to $login.  May only be called by the server in response to an out of band command, otherwise E_PERM is returned.";
          if (((caller == #-1) &amp;&amp; (caller_perms() == #-1)) &amp;&amp; (callers() == {}))
          if (valid(player) &amp;&amp; is_player(player))
          set_task_perms(player);
          player:do_out_of_band_command(@args);
          else
          $login:do_out_of_band_command(@args);
          endif
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>handle_uncaught_error</NAME>
        <CODE>
          if (!callers())
          {code, msg, value, stack, traceback} = args;
          if (!$object_utils:connected(player))
          "Mail the player the traceback if e isn't connected.";
          $mail_agent:send_message(#0, player, {"traceback", $gripe_recipients}, traceback);
          endif
          "now let the player do something with it if e wants...";
          return `player:(verb)(@args) ! ANY';
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_force_input</NAME>
        <CODE>
          "Copied from Jay (#3920):bf_force_input Mon Jun 16 20:55:27 1997 PDT";
          "force_input(conn, line [, at-front])";
          "see help on the builtin for more information. This verb is called by the server when $server_options.protect_force_input exists and is true and caller_perms() are not wizardly.";
          {conn, line, ?at_front = 0} = args;
          if (caller_perms() != conn)
          retval = E_PERM;
          elseif (conn in $login.newted)
          retval = E_PERM;
          else
          retval = `force_input(@args) ! ANY';
          this.force_input_count = this.force_input_count + 1;
          endif
          return ((typeof(retval) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(retval) | retval;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>moveto</NAME>
        <CODE>
          "Let's keep bozos from partying.  --Nosredna the partypooper";
          return pass(#-1);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bf_set_property_info set_property_info</NAME>
        <CODE>
          who = caller_perms();
          retval = 0;
          try
          {what, propname, info} = args;
          except (E_ARGS)
          retval = E_ARGS;
          endtry
          try
          {owner, perms, ?newname = 0} = info;
          except (E_ARGS)
          retval = E_ARGS;
          except (E_TYPE)
          retval = E_TYPE;
          endtry
          if (retval != 0)
          elseif ((newname in {"object_size", "size_quota", "queued_task_limit"}) &amp;&amp; (!who.wizard))
          retval = E_PERM;
          else
          set_task_perms(who);
          retval = `set_property_info(@args) ! ANY';
          endif
          return ((typeof(retval) == ERR) &amp;&amp; $code_utils:dflag_on()) ? raise(retval) | retval;
        </CODE>
      </VERB>
    </OBJECT>
    <OBJECT ID="obj3" FLAGS="f r" OWNER="obj2" LOCATION="obj-1">
      <NAME>generic room</NAME>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>who_location_msg</NAME>
        <VALUE>"%T"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>free_home</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>victim_ejection_msg</NAME>
        <VALUE>"You have been expelled from %i by %n."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>ejection_msg</NAME>
        <VALUE>"You expel %d from %i."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>oejection_msg</NAME>
        <VALUE>"%N unceremoniously %{!expels} %d from %i."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>residents</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>free_entry</NAME>
        <VALUE>1</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c">
        <NAME>entrances</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>blessed_object</NAME>
        <VALUE>#-1</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>blessed_task</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c">
        <NAME>exits</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>dark</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>ctype</NAME>
        <VALUE>3</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c">
        <NAME>key</NAME>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>aliases</NAME>
        <VALUE>{"generic room"}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>description</NAME>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>object_size</NAME>
        <VALUE>{27919, 919123664}</VALUE>
      </PROPERTY>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>confunc</NAME>
        <CODE>
          if ((((cp = caller_perms()) == player) || $perm_utils:controls(cp, player)) || (caller == this))
          "Need the first check because guests don't control themselves";
          this:look_self(player.brief);
          this:announce($string_utils:pronoun_sub("%N %&lt;has&gt; connected.", player));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>disfunc</NAME>
        <CODE>
          if ((((cp = caller_perms()) == player) || $perm_utils:controls(cp, player)) || (caller == this))
          this:announce($string_utils:pronoun_sub("%N %&lt;has&gt; disconnected.", player));
          "need the first check since guests don't control themselves";
          if (!$object_utils:isa(player, $guest))
          "guest disfuncs are handled by $guest:disfunc. Don't add them here";
          $housekeeper:move_players_home(player);
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="x r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>say</NAME>
        <CODE>
          try
          player:tell("You say, \"", argstr, "\"");
          this:announce(player.name, " ", $gender_utils:get_conj("says", player), ", \"", argstr, "\"");
          except (ANY)
          "Don't really need to do anything but ignore the idiot who has a bad :tell";
          endtry
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>emote</NAME>
        <CODE>
          if ((argstr != "") &amp;&amp; (argstr[1] == ":"))
          this:announce_all(player.name, argstr[2..length(argstr)]);
          else
          this:announce_all(player.name, " ", argstr);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>announce</NAME>
        <CODE>
          for dude in (setremove(this:contents(), player))
          try
          dude:tell(@args);
          except (ANY)
          "Just skip the dude with the bad :tell";
          continue dude;
          endtry
          endfor
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>match_exit</NAME>
        <CODE>
          what = args[1];
          if (what)
          yes = $failed_match;
          for e in (this.exits)
          if (valid(e) &amp;&amp; (what in {e.name, @e.aliases}))
          if (yes == $failed_match)
          yes = e;
          elseif (yes != e)
          return $ambiguous_match;
          endif
          endif
          endfor
          return yes;
          else
          return $nothing;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>add_exit</NAME>
        <CODE>
          set_task_perms(caller_perms());
          return `this.exits = setadd(this.exits, args[1]) ! E_PERM' != E_PERM;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>tell_contents</NAME>
        <CODE>
          {contents, ctype} = args;
          if ((!this.dark) &amp;&amp; (contents != {}))
          if (ctype == 0)
          player:tell("Contents:");
          for thing in (contents)
          player:tell("  ", thing:title());
          endfor
          elseif (ctype == 1)
          for thing in (contents)
          if (is_player(thing))
          player:tell($string_utils:pronoun_sub(tostr("%N ", $gender_utils:get_conj("is", thing), " here."), thing));
          else
          player:tell("You see ", thing:title(), " here.");
          endif
          endfor
          elseif (ctype == 2)
          player:tell("You see ", $string_utils:title_list(contents), " here.");
          elseif (ctype == 3)
          players = things = {};
          for x in (contents)
          if (is_player(x))
          players = {@players, x};
          else
          things = {@things, x};
          endif
          endfor
          if (things)
          player:tell("You see ", $string_utils:title_list(things), " here.");
          endif
          if (players)
          player:tell($string_utils:title_listc(players), (length(players) == 1) ? " " + $gender_utils:get_conj("is", players[1]) | " are", " here.");
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@exits</NAME>
        <CODE>
          if (!$perm_utils:controls(valid(caller_perms()) ? caller_perms() | player, this))
          player:tell("Sorry, only the owner of a room may list its exits.");
          elseif (this.exits == {})
          player:tell("This room has no conventional exits.");
          else
          try
          for exit in (this.exits)
          try
          player:tell(exit.name, " (", exit, ") leads to ", valid(exit.dest) ? exit.dest.name | "???", " (", exit.dest, ") via {", $string_utils:from_list(exit.aliases, ", "), "}.");
          except (ANY)
          player:tell("Bad exit or missing .dest property:  ", $string_utils:nn(exit));
          continue exit;
          endtry
          endfor
          except (E_TYPE)
          player:tell("Bad .exits property. This should be a list of exit objects. Please fix this.");
          endtry
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>look_self</NAME>
        <CODE>
          {?brief = 0} = args;
          player:tell(this:title());
          if (!brief)
          pass();
          endif
          this:tell_contents(setremove(this:contents(), player), this.ctype);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>acceptable</NAME>
        <CODE>
          what = args[1];
          return this:is_unlocked_for(what) &amp;&amp; (((this:free_entry(@args) || ((what == this.blessed_object) &amp;&amp; (task_id() == this.blessed_task))) || (what.owner == this.owner)) || ((typeof(this.residents) == LIST) &amp;&amp; ((what in this.residents) || (what.owner in this.residents))));
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>add_entrance</NAME>
        <CODE>
          set_task_perms(caller_perms());
          return `this.entrances = setadd(this.entrances, args[1]) ! E_PERM' != E_PERM;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>bless_for_entry</NAME>
        <CODE>
          if (caller in {@this.entrances, this})
          this.blessed_object = args[1];
          this.blessed_task = task_id();
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@entrances</NAME>
        <CODE>
          if (!$perm_utils:controls(valid(caller_perms()) ? caller_perms() | player, this))
          player:tell("Sorry, only the owner of a room may list its entrances.");
          elseif (this.entrances == {})
          player:tell("This room has no conventional entrances.");
          else
          try
          for exit in (this.entrances)
          try
          player:tell(exit.name, " (", exit, ") comes from ", valid(exit.source) ? exit.source.name | "???", " (", exit.source, ") via {", $string_utils:from_list(exit.aliases, ", "), "}.");
          except (ANY)
          player:tell("Bad entrance object or missing .source property: ", $string_utils:nn(exit));
          continue exit;
          endtry
          endfor
          except (E_TYPE)
          player:tell("Bad .entrances property. This should be a list of exit objects. Please fix this.");
          endtry
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>go</NAME>
        <CODE>
          if ((!args) || (!(dir = args[1])))
          player:tell("You need to specify a direction.");
          return E_INVARG;
          elseif (valid(exit = player.location:match_exit(dir)))
          exit:invoke();
          if (length(args) &gt; 1)
          old_room = player.location;
          "Now give objects in the room we just entered a chance to act.";
          suspend(0);
          if (player.location == old_room)
          "player didn't move or get moved while we were suspended";
          player.location:go(@listdelete(args, 1));
          endif
          endif
          elseif (exit == $failed_match)
          player:tell("You can't go that way (", dir, ").");
          else
          player:tell("I don't know which direction `", dir, "' you mean.");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>l*ook</NAME>
        <CODE>
          if ((dobjstr == "") &amp;&amp; (!prepstr))
          this:look_self();
          elseif ((prepstr != "in") &amp;&amp; (prepstr != "on"))
          if ((!dobjstr) &amp;&amp; (prepstr == "at"))
          dobjstr = iobjstr;
          iobjstr = "";
          else
          dobjstr = dobjstr + (prepstr &amp;&amp; ((dobjstr &amp;&amp; " ") + prepstr));
          dobjstr = dobjstr + (iobjstr &amp;&amp; ((dobjstr &amp;&amp; " ") + iobjstr));
          endif
          dobj = this:match_object(dobjstr);
          if (!$command_utils:object_match_failed(dobj, dobjstr))
          dobj:look_self();
          endif
          elseif (!iobjstr)
          player:tell(verb, " ", prepstr, " what?");
          else
          iobj = this:match_object(iobjstr);
          if (!$command_utils:object_match_failed(iobj, iobjstr))
          if (dobjstr == "")
          iobj:look_self();
          elseif ((thing = iobj:match(dobjstr)) == $failed_match)
          player:tell("I don't see any \"", dobjstr, "\" ", prepstr, " ", iobj.name, ".");
          elseif (thing == $ambiguous_match)
          player:tell("There are several things ", prepstr, " ", iobj.name, " one might call \"", dobjstr, "\".");
          else
          thing:look_self();
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>announce_all</NAME>
        <CODE>
          for dude in (this:contents())
          try
          dude:tell(@args);
          except (ANY)
          "Just ignore the dude with the stupid :tell";
          continue dude;
          endtry
          endfor
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>announce_all_but</NAME>
        <CODE>
          ":announce_all_but(LIST objects to ignore, text)";
          {ignore, @text} = args;
          contents = this:contents();
          for l in (ignore)
          contents = setremove(contents, l);
          endfor
          for listener in (contents)
          try
          listener:tell(@text);
          except (ANY)
          "Ignure listener with bad :tell";
          continue listener;
          endtry
          endfor
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>enterfunc</NAME>
        <CODE>
          object = args[1];
          if (is_player(object) &amp;&amp; (object.location == this))
          player = object;
          this:look_self(player.brief);
          endif
          if (object == this.blessed_object)
          this.blessed_object = #-1;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>exitfunc</NAME>
        <CODE>
          return;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>remove_exit</NAME>
        <CODE>
          exit = args[1];
          if (caller != exit)
          set_task_perms(caller_perms());
          endif
          return `this.exits = setremove(this.exits, exit) ! E_PERM' != E_PERM;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>remove_entrance</NAME>
        <CODE>
          exit = args[1];
          if (caller != exit)
          set_task_perms(caller_perms());
          endif
          return `this.entrances = setremove(this.entrances, exit) ! E_PERM' != E_PERM;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@add-exit</NAME>
        <CODE>
          set_task_perms(player);
          if (!dobjstr)
          player:tell("Usage:  @add-exit &lt;exit-number&gt;");
          return;
          endif
          exit = this:match_object(dobjstr);
          if ($command_utils:object_match_failed(exit, dobjstr))
          return;
          endif
          if (!($exit in $object_utils:ancestors(exit)))
          player:tell("That doesn't look like an exit object to me...");
          return;
          endif
          try
          dest = exit.dest;
          except (E_PERM)
          player:tell("You can't read the exit's destination to check that it's consistent!");
          return;
          endtry
          try
          source = exit.source;
          except (E_PERM)
          player:tell("You can't read that exit's source to check that it's consistent!");
          return;
          endtry
          if (source != this)
          player:tell("That exit wasn't made to be attached here; it was made as an exit from ", source.name, " (", source, ").");
          return;
          elseif (((typeof(dest) != OBJ) || (!valid(dest))) || (!($room in $object_utils:ancestors(dest))))
          player:tell("That exit doesn't lead to a room!");
          return;
          endif
          if (!this:add_exit(exit))
          player:tell("Sorry, but you must not have permission to add exits to this room.");
          else
          player:tell("You have added ", exit, " as an exit that goes to ", exit.dest.name, " (", exit.dest, ") via ", $string_utils:english_list(setadd(exit.aliases, exit.name)), ".");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@add-entrance</NAME>
        <CODE>
          set_task_perms(player);
          if (!dobjstr)
          player:tell("Usage:  @add-entrance &lt;exit-number&gt;");
          return;
          endif
          exit = this:match_object(dobjstr);
          if ($command_utils:object_match_failed(exit, dobjstr))
          return;
          endif
          if (!($exit in $object_utils:ancestors(exit)))
          player:tell("That doesn't look like an exit object to me...");
          return;
          endif
          try
          dest = exit.dest;
          except (E_PERM)
          player:tell("You can't read the exit's destination to check that it's consistent!");
          return;
          endtry
          if (dest != this)
          player:tell("That exit doesn't lead here!");
          return;
          endif
          if (!this:add_entrance(exit))
          player:tell("Sorry, but you must not have permission to add entrances to this room.");
          else
          player:tell("You have added ", exit, " as an entrance that gets here via ", $string_utils:english_list(setadd(exit.aliases, exit.name)), ".");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>recycle</NAME>
        <CODE>
          "Make a mild attempt to keep people and objects from ending up in #-1 when people recycle a room";
          if ((caller == this) || $perm_utils:controls(caller_perms(), this))
          "... first try spilling them out onto the floor of enclosing room if any";
          if (valid(this.location))
          for x in (this.contents)
          try
          x:moveto(this.location);
          except (ANY)
          continue x;
          endtry
          endfor
          endif
          "... try sending them home...";
          for x in (this.contents)
          if (is_player(x))
          if ((typeof(x.home) == OBJ) &amp;&amp; valid(x.home))
          try
          x:moveto(x.home);
          except (ANY)
          continue x;
          endtry
          endif
          if (x.location == this)
          move(x, $player_start);
          endif
          elseif (valid(x.owner))
          try
          x:moveto(x.owner);
          except (ANY)
          continue x;
          endtry
          endif
          endfor
          pass(@args);
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>e east w west s south n north ne northeast nw northwest se southeast sw southwest u up d down</NAME>
        <CODE>
          set_task_perms((caller_perms() == #-1) ? player | caller_perms());
          exit = this:match_exit(verb);
          if (valid(exit))
          exit:invoke();
          elseif (exit == $failed_match)
          player:tell("You can't go that way.");
          else
          player:tell("I don't know which direction `", verb, "' you mean.");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@eject @eject! @eject!!</NAME>
        <CODE>
          set_task_perms(player);
          if ($command_utils:object_match_failed(dobj, dobjstr))
          return;
          elseif (dobj.location != this)
          is = $gender_utils:get_conj("is", dobj);
          player:tell(dobj.name, "(", dobj, ") ", is, " not here.");
          return;
          elseif (!$perm_utils:controls(player, this))
          player:tell("You are not the owner of this room.");
          return;
          elseif (dobj.wizard)
          player:tell("Sorry, you can't ", verb, " a wizard.");
          dobj:tell(player.name, " tried to ", verb, " you.");
          return;
          endif
          iobj = this;
          player:tell(this:ejection_msg());
          this:((verb == "@eject") ? "eject" | "eject_basic")(dobj);
          if (verb != "@eject!!")
          dobj:tell(this:victim_ejection_msg());
          endif
          this:announce_all_but({player, dobj}, this:oejection_msg());
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>ejection_msg oejection_msg victim_ejection_msg</NAME>
        <CODE>
          return $gender_utils:pronoun_sub(this.(verb));
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>accept_for_abode</NAME>
        <CODE>
          who = args[1];
          return this:basic_accept_for_abode(who) &amp;&amp; this:acceptable(who);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@resident*s</NAME>
        <CODE>
          if (!$perm_utils:controls(player, this))
          player:tell("You must own this room to manipulate the legal residents list.  Try contacting ", this.owner.name, ".");
          else
          if (typeof(this.residents) != LIST)
          this.residents = {this.residents};
          endif
          if (!dobjstr)
          "First, remove !valid objects from this room...";
          for x in (this.residents)
          if ((typeof(x) != OBJ) || (!valid(x)))
          player:tell("Warning: removing ", x, ", an invalid object, from the residents list.");
          this.residents = setremove(this.residents, x);
          endif
          endfor
          player:tell("Allowable residents in this room:  ", $string_utils:english_list($list_utils:map_prop(this.residents, "name"), "no one"), ".");
          return;
          elseif (dobjstr[1] == "!")
          notflag = 1;
          dobjstr = dobjstr[2..$];
          else
          notflag = 0;
          endif
          result = $string_utils:match_player_or_object(dobjstr);
          if (!result)
          return;
          else
          "a one element list was returned to us if it won.";
          result = result[1];
          if (notflag)
          if (!(result in this.residents))
          player:tell(result.name, " doesn't appear to be in the residents list of ", this.name, ".");
          else
          this.residents = setremove(this.residents, result);
          player:tell(result.name, " removed from the residents list of ", this.name, ".");
          endif
          else
          if (result in this.residents)
          is = $gender_utils:get_conj("is", result);
          player:tell(result.name, " ", is, " already an allowed resident of ", this.name, ".");
          else
          this.residents = {@this.residents, result};
          player:tell(result.name, " added to the residents list of ", this.name, ".");
          endif
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>match</NAME>
        <CODE>
          target = {@this:contents(), @this:exits()};
          return $string_utils:match(args[1], target, "name", target, "aliases");
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@remove-exit</NAME>
        <CODE>
          set_task_perms(player);
          if (!dobjstr)
          player:tell("Usage:  @remove-exit &lt;exit&gt;");
          return;
          endif
          exit = this:match_object(dobjstr);
          if (!(exit in this.exits))
          if ($command_utils:object_match_failed(exit, dobjstr))
          return;
          endif
          player:tell("Couldn't find \"", dobjstr, "\" in the exits list of ", this.name, ".");
          return;
          elseif (!this:remove_exit(exit))
          player:tell("Sorry, but you do not have permission to remove exits from this room.");
          else
          name = valid(exit) ? exit.name | "&lt;recycled&gt;";
          player:tell("Exit ", exit, " (", name, ") removed from exit list of ", this.name, " (", this, ").");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@remove-entrance</NAME>
        <CODE>
          set_task_perms(player);
          if (!dobjstr)
          player:tell("Usage:  @remove-entrance &lt;entrance&gt;");
          return;
          endif
          entrance = $string_utils:match(dobjstr, this.entrances, "name", this.entrances, "aliases");
          if (!valid(entrance))
          "Try again to parse it.  Maybe they gave object number.  Don't complain if it's invalid though; maybe it's been recycled in some nefarious way.";
          entrance = this:match_object(dobjstr);
          endif
          if (!(entrance in this.entrances))
          player:tell("Couldn't find \"", dobjstr, "\" in the entrances list of ", this.name, ".");
          return;
          elseif (!this:remove_entrance(entrance))
          player:tell("Sorry, but you do not have permission to remove entrances from this room.");
          else
          name = valid(entrance) ? entrance.name | "&lt;recycled&gt;";
          player:tell("Entrance ", entrance, " (", name, ") removed from entrance list of ", this.name, " (", this, ").");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>moveto</NAME>
        <CODE>
          if ((caller in {this, this.owner}) || $perm_utils:controls(caller_perms(), this))
          return pass(@args);
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>who_location_msg</NAME>
        <CODE>
          return (msg = `this.(verb) ! ANY') ? $string_utils:pronoun_sub(msg, args[1]) | "";
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>exits entrances</NAME>
        <CODE>
          if ((caller == this) || $perm_utils:controls(caller_perms(), this))
          return this.(verb);
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>obvious_exits obvious_entrances</NAME>
        <CODE>
          exits = {};
          for exit in (`(verb == "obvious_exits") ? this.exits | this.entrances ! ANY =&gt; {}')
          if (`exit.obvious ! ANY')
          exits = setadd(exits, exit);
          endif
          endfor
          return exits;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>here_huh</NAME>
        <CODE>
          ":here_huh(verb,args)  -- room-specific :huh processing.  This should return 1 if it finds something interesting to do and 0 otherwise; see $command_utils:do_huh.";
          "For the generic room, we check for the case of the caller specifying an exit for which a corresponding verb was never defined.";
          set_task_perms(caller_perms());
          if (args[2] || ($failed_match == (exit = this:match_exit(verb = args[1]))))
          "... okay, it's not an exit.  we give up...";
          return 0;
          elseif (valid(exit))
          exit:invoke();
          else
          "... ambiguous exit ...";
          player:tell("I don't know which direction `", verb, "' you mean.");
          endif
          return 1;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>room_announce*_all_but</NAME>
        <CODE>
          this:(verb[6..$])(@args);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>examine_commands_ok</NAME>
        <CODE>
          return this == args[1].location;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>examine_key</NAME>
        <CODE>
          "examine_key(examiner)";
          "return a list of strings to be told to the player, indicating what the key on this type of object means, and what this object's key is set to.";
          "the default will only tell the key to a wizard or this object's owner.";
          who = args[1];
          if (((caller == this) &amp;&amp; $perm_utils:controls(who, this)) &amp;&amp; (this.key != 0))
          return {tostr(this:title(), " will accept only objects matching the following key:"), tostr("  ", $lock_utils:unparse_key(this.key))};
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>examine_contents</NAME>
        <CODE>
          "examine_contents(who)";
          if (caller == this)
          this:tell_contents(this.contents, this.ctype);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>free_entry</NAME>
        <CODE>
          return this.free_entry;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>dark</NAME>
        <CODE>
          return this.(verb);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>announce_lines_x</NAME>
        <CODE>
          "Copied from generic room (#3):announce by Haakon (#2) Thu Oct 24 16:15:01 1996 PDT";
          for dude in (setremove(this:contents(), player))
          try
          dude:tell_lines(@args);
          except id (ANY)
          endtry
          endfor
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>basic_accept_for_abode</NAME>
        <CODE>
          who = args[1];
          return valid(who) &amp;&amp; ((this.free_home || $perm_utils:controls(who, this)) || ((typeof(residents = this.residents) == LIST) ? who in this.residents | (who == this.residents)));
        </CODE>
      </VERB>
      <OBJECT ID="obj50" FLAGS="f r" OWNER="obj36" LOCATION="obj-1">
        <NAME>Generic Editor</NAME>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>readable</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>times</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>commands2</NAME>
          <VALUE>{{"say", "emote", "lis*t", "ins*ert", "n*ext,p*rev", "del*ete", "f*ind", "s*ubst", "m*ove,c*opy", "join*l", "fill"}, {"y*ank", "w*hat", "abort", "q*uit,done,pause"}}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>help</NAME>
          <VALUE>#44</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>no_text_msg</NAME>
          <VALUE>"There are no lines of text."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>commands</NAME>
          <VALUE>{{"say", "&lt;text&gt;"}, {"emote", "&lt;text&gt;"}, {"lis*t", "[&lt;range&gt;] [nonum]"}, {"ins*ert", "[&lt;ins&gt;] [\"&lt;text&gt;]"}, {"n*ext,p*rev", "[n] [\"&lt;text&gt;]"}, {"del*ete", "[&lt;range&gt;]"}, {"f*ind", "/&lt;str&gt;[/[c][&lt;range&gt;]]"}, {"s*ubst", "/&lt;str1&gt;/&lt;str2&gt;[/[g][c][&lt;range&gt;]]"}, {"m*ove,c*opy", "[&lt;range&gt;] to &lt;ins&gt;"}, {"join*l", "[&lt;range&gt;]"}, {"fill", "[&lt;range&gt;] [@&lt;col&gt;]"}, {"w*hat", ""}, {"abort", ""}, {"q*uit,done,pause", ""}, {"enter", ""}, {"y*ank", "from &lt;text-source&gt;"}}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>invoke_task</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>exit_on_abort</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>previous_session_msg</NAME>
          <VALUE>""</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>stateprops</NAME>
          <VALUE>{{"texts", 0}, {"changes", 0}, {"inserting", 1}, {"readable", 0}}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>depart_msg</NAME>
          <VALUE>"%N heads off to the Generic Editing Room."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>return_msg</NAME>
          <VALUE>"%N comes back from the Generic Editing Room."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>no_littering_msg</NAME>
          <VALUE>"Keeping your [whatever] for later work.  Since this the Generic Editor, you have to do your own :set_changed(0) so that we'll know to get rid of whatever it you're working on when you leave.  Please don't litter... especially in the Generic Editor."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>no_change_msg</NAME>
          <VALUE>"There have been no changes since the last save."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>change_msg</NAME>
          <VALUE>"Text has been altered since the last save."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>nothing_loaded_msg</NAME>
          <VALUE>"You're not currently editing anything."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" >
          <NAME>texts</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>active</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" >
          <NAME>changes</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" >
          <NAME>inserting</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>original</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>who_location_msg</NAME>
          <VALUE>"%L [editing]"</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>free_home</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>victim_ejection_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>ejection_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>oejection_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>residents</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>free_entry</NAME>
          <VALUE>1</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c">
          <NAME>entrances</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>blessed_object</NAME>
          <VALUE>#-1</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>blessed_task</NAME>
          <VALUE>170400074</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c">
          <NAME>exits</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>dark</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>ctype</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c">
          <NAME>key</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>aliases</NAME>
          <VALUE>{"Generic Editor", "gedit", "edit"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>description</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>object_size</NAME>
          <VALUE>{51272, 919123695}</VALUE>
        </PROPERTY>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>say</NAME>
          <CODE>
            if ((caller != player) &amp;&amp; (caller_perms() != player))
            return E_PERM;
            endif
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            else
            this:insert_line(who, argstr);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>emote</NAME>
          <CODE>
            if ((caller != player) &amp;&amp; (caller_perms() != player))
            return E_PERM;
            endif
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            else
            this:append_line(who, argstr);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
          <NAME>enter</NAME>
          <CODE>
            if (!this:loaded(player))
            player:tell(this:nothing_loaded_msg());
            else
            lines = $command_utils:read_lines();
            if (typeof(lines) == ERR)
            player:notify(tostr(lines));
            return;
            endif
            this:insert_line(this:loaded(player), lines, 0);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>lis*t view</NAME>
          <CODE>
            nonum = 0;
            if (verb == "view")
            if (!args)
            l = {};
            for i in [1..length(this.active)]
            if (this.readable[i])
            l = {@l, this.active[i]};
            endif
            endfor
            if (l)
            player:tell("Players having readable texts in this editor:  ", $string_utils:names_of(l));
            else
            player:tell("No one has published anything in this editor.");
            endif
            return;
            elseif ($command_utils:player_match_result(plyr = $string_utils:match_player(args[1]), args[1])[1])
            "...no such player";
            return;
            elseif ((!(who = this:loaded(plyr))) || (!this:readable(who)))
            player:tell(plyr.name, "(", plyr, ") has not published anything in this editor.");
            return;
            endif
            args = listdelete(args, 1);
            elseif (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            return;
            endif
            len = length(this.texts[who]);
            ins = this.inserting[who];
            window = 8;
            if (len &lt; (2 * window))
            default = {"1-$"};
            elseif (ins &lt;= window)
            default = {tostr("1-", 2 * window)};
            else
            default = {tostr(window, "_-", window, "^"), tostr(2 * window, "$-$")};
            endif
            if (typeof(range = this:parse_range(who, default, @args)) != LIST)
            player:tell(tostr(range));
            elseif (range[3] &amp;&amp; (!(nonum = "nonum" == $string_utils:trim(range[3]))))
            player:tell("Don't understand this:  ", range[3]);
            elseif (nonum)
            player:tell_lines(this.texts[who][range[1]..range[2]]);
            else
            for line in [range[1]..range[2]]
            this:list_line(who, line);
            if ($command_utils:running_out_of_time())
            suspend(0);
            if (!(who = this:loaded(player)))
            player:tell("ack!  something bad happened during a suspend...");
            return;
            endif
            endif
            endfor
            if ((ins &gt; len) &amp;&amp; (len == range[2]))
            player:tell("^^^^");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
          <NAME>ins*ert n*ext p*revious .</NAME>
          <CODE>
            if (i = index(argstr, "\""))
            text = argstr[i + 1..$];
            argstr = argstr[1..i - 1];
            else
            text = 0;
            endif
            spec = $string_utils:trim(argstr);
            if (index("next", verb) == 1)
            verb = "next";
            spec = "+" + (spec || "1");
            elseif (index("prev", verb) == 1)
            verb = "prev";
            spec = "-" + (spec || "1");
            else
            spec = spec || ".";
            endif
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            elseif (ERR == typeof(number = this:parse_insert(who, spec)))
            if (verb in {"next", "prev"})
            player:tell("Argument must be a number.");
            else
            player:tell("You must specify an integer or `$' for the last line.");
            endif
            elseif ((number &gt; (max = length(this.texts[who]) + 1)) || (number &lt; 1))
            player:tell("That would take you out of range (to line ", number, "?).");
            else
            this.inserting[who] = number;
            if (typeof(text) == STR)
            this:insert_line(who, text);
            else
            if (verb != "next")
            (number &gt; 1) ? this:list_line(who, number - 1) | player:tell("____");
            endif
            if (verb != "prev")
            (number &lt; max) ? this:list_line(who, number) | player:tell("^^^^");
            endif
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>del*ete</NAME>
          <CODE>
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            elseif (typeof(range = this:parse_range(who, {"_", "1"}, @args)) != LIST)
            player:tell(range);
            elseif (range[3])
            player:tell("Junk at end of cmd:  ", range[3]);
            else
            player:tell_lines((text = this.texts[who])[from = range[1]..to = range[2]]);
            player:tell("---Line", (to &gt; from) ? "s" | "", " deleted.  Insertion point is before line ", from, ".");
            this.texts[who] = {@text[1..from - 1], @text[to + 1..$]};
            if (!this.changes[who])
            this.changes[who] = 1;
            this.times[who] = time();
            endif
            this.inserting[who] = from;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>f*ind</NAME>
          <CODE>
            if (callers() &amp;&amp; (caller != this))
            return E_PERM;
            endif
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            elseif (typeof(subst = this:parse_subst(argstr &amp;&amp; (argstr[1] + argstr), "c", "Empty search string?")) != LIST)
            player:tell(tostr(subst));
            elseif (typeof(start = subst[4] ? this:parse_insert(who, subst[4]) | this.inserting[who]) == ERR)
            player:tell("Starting from where?", subst[4] ? ("  (can't parse " + subst[4]) + ")" | "");
            else
            search = subst[2];
            case = !index(subst[3], "c", 1);
            text = this.texts[who];
            tlen = length(text);
            while ((start &lt;= tlen) &amp;&amp; (!index(text[start], search, case)))
            start = start + 1;
            endwhile
            if (start &gt; tlen)
            player:tell("`", search, "' not found.");
            else
            this.inserting[who] = start + 1;
            this:list_line(who, start);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>m*ove c*opy</NAME>
          <CODE>
            verb = (is_move = verb[1] == "m") ? "move" | "copy";
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            return;
            endif
            wargs = args;
            t = to_pos = 0;
            while (t = "to" in (wargs = wargs[t + 1..$]))
            to_pos = to_pos + t;
            endwhile
            range_args = args[1..to_pos - 1];
            if ((!to_pos) || (ERR == typeof(dest = this:parse_insert(who, $string_utils:from_list(wargs, " ")))))
            player:tell(verb, " to where? ");
            elseif ((dest &lt; 1) || (dest &gt; ((last = length(this.texts[who])) + 1)))
            player:tell("Destination (", dest, ") out of range.");
            elseif (("from" in range_args) || ("to" in range_args))
            player:tell("Don't use that kind of range specification with this command.");
            elseif (typeof(range = this:parse_range(who, {"_", "^"}, @args[1..to_pos - 1])) != LIST)
            player:tell(range);
            elseif (range[3])
            player:tell("Junk before `to':  ", range[3]);
            elseif ((is_move &amp;&amp; (dest &gt;= range[1])) &amp;&amp; (dest &lt;= (range[2] + 1)))
            player:tell("Destination lies inside range of lines to be moved.");
            else
            from = range[1];
            to = range[2];
            ins = this.inserting[who];
            text = this.texts[who];
            if (!is_move)
            this.texts[who] = {@text[1..dest - 1], @text[from..to], @text[dest..last]};
            if (ins &gt;= dest)
            this.inserting[who] = ((ins + to) - from) + 1;
            endif
            else
            "oh shit... it's a move";
            if (dest &lt; from)
            newtext = {@text[1..dest - 1], @text[from..to], @text[dest..from - 1], @text[to + 1..last]};
            if ((ins &gt;= dest) &amp;&amp; (ins &lt;= to))
            ins = (ins &gt; from) ? (ins - from) + dest | (((ins + to) - from) + 1);
            endif
            else
            newtext = {@text[1..from - 1], @text[to + 1..dest - 1], @text[from..to], @text[dest..last]};
            if ((ins &gt; from) &amp;&amp; (ins &lt; dest))
            ins = (ins &lt;= to) ? ((ins + dest) - to) - 1 | (((ins - to) + from) - 1);
            endif
            endif
            this.texts[who] = newtext;
            this.inserting[who] = ins;
            endif
            if (!this.changes[who])
            this.changes[who] = 1;
            this.times[who] = time();
            endif
            player:tell("Lines ", is_move ? "moved." | "copied.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>join*literal</NAME>
          <CODE>
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            elseif (typeof(range = this:parse_range(who, {"_-^", "_", "^"}, @args)) != LIST)
            player:tell(range);
            elseif (range[3])
            player:tell("Junk at end of cmd:  ", range[3]);
            elseif (!(result = this:join_lines(who, @range[1..2], length(verb) &lt;= 4)))
            player:tell((result == 0) ? "Need at least two lines to join." | result);
            else
            this:list_line(who, range[1]);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>fill</NAME>
          <CODE>
            fill_column = 70;
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            elseif (typeof(range = this:parse_range(who, {"_", "1"}, @args)) != LIST)
            player:tell(range);
            elseif (range[3] &amp;&amp; ((range[3][1] != "@") || ((fill_column = toint(range[3][2..$])) &lt; 10)))
            player:tell("Usage:  fill [&lt;range&gt;] [@ column]   (where column &gt;= 10).");
            else
            join = this:join_lines(who, @range[1..2], 1);
            newlines = this:fill_string((text = this.texts[who])[from = range[1]], fill_column);
            if (fill = ((nlen = length(newlines)) &gt; 1) || (newlines[1] != text[from]))
            this.texts[who] = {@text[1..from - 1], @newlines, @text[from + 1..$]};
            if (((insert = this.inserting[who]) &gt; from) &amp;&amp; (nlen &gt; 1))
            this.inserting[who] = (insert + nlen) - 1;
            endif
            endif
            if (fill || join)
            for line in [from..(from + nlen) - 1]
            this:list_line(who, line);
            endfor
            else
            player:tell("No changes.");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
          <NAME>pub*lish perish unpub*lish depub*lish</NAME>
          <CODE>
            if (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            return;
            endif
            if (typeof(e = this:set_readable(who, index("publish", verb) == 1)) == ERR)
            player:tell(e);
            elseif (e)
            player:tell("Your text is now globally readable.");
            else
            player:tell("Your text is read protected.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="none" PREP="none" IOBJ="none">
          <NAME>w*hat</NAME>
          <CODE>
            if (!(this:ok(who = player in this.active) &amp;&amp; (typeof(this.texts[who]) == LIST)))
            player:tell(this:nothing_loaded_msg());
            else
            player:tell("You are editing ", this:working_on(who), ".");
            player:tell("Your insertion point is ", (this.inserting[who] &gt; length(this.texts[who])) ? "after the last line: next line will be #" | "before line ", this.inserting[who], ".");
            player:tell(this.changes[who] ? this:change_msg() | this:no_change_msg());
            if (this.readable[who])
            player:tell("Your text is globally readable.");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
          <NAME>abort</NAME>
          <CODE>
            if (!this.changes[who = player in this.active])
            player:tell("No changes to throw away.  Editor cleared.");
            else
            player:tell("Throwing away session for ", this:working_on(who), ".");
            endif
            this:reset_session(who);
            if (this.exit_on_abort)
            this:done();
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="none" PREP="none" IOBJ="none">
          <NAME>done q*uit pause</NAME>
          <CODE>
            if (!(caller in {this, player}))
            return E_PERM;
            elseif (!(who = player in this.active))
            player:tell("You are not actually in ", this.name, ".");
            return;
            elseif (!valid(origin = this.original[who]))
            player:tell("I don't know where you came here from.");
            else
            player:moveto(origin);
            if (player.location == this)
            player:tell("Hmmm... the place you came from doesn't want you back.");
            else
            if (msg = this:return_msg())
            player.location:announce($string_utils:pronoun_sub(msg));
            endif
            return;
            endif
            endif
            player:tell("You'll have to use 'home' or a teleporter.");
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>huh2</NAME>
          <CODE>
            "This catches subst and find commands that don't fit into the usual model, e.g., s/.../.../ without the space after the s, and find commands without the verb `find'.  Still behaves in annoying ways (e.g., loses if the search string contains multiple whitespace), but better than before.";
            set_task_perms(caller_perms());
            if ((c = callers()) &amp;&amp; ((c[1][1] != this) || (length(c) &gt; 1)))
            return pass(@args);
            endif
            verb = args[1];
            v = 1;
            vmax = min(length(verb), 5);
            while ((v &lt;= vmax) &amp;&amp; (verb[v] == "subst"[v]))
            v = v + 1;
            endwhile
            argstr = $code_utils:argstr(verb, args[2]);
            if (((v &gt; 1) &amp;&amp; (v &lt;= length(verb))) &amp;&amp; (((vl = verb[v]) &lt; "A") || (vl &gt; "Z")))
            argstr = (verb[v..$] + (argstr &amp;&amp; " ")) + argstr;
            return this:subst();
            elseif ("/" == verb[1])
            argstr = (verb + (argstr &amp;&amp; " ")) + argstr;
            return this:find();
            else
            pass(@args);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>insertion</NAME>
          <CODE>
            return this:ok(who = args[1]) &amp;&amp; this.inserting[who];
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_insertion</NAME>
          <CODE>
            return this:ok(who = args[1]) &amp;&amp; ((((ins = toint(args[2])) &lt; 1) ? E_INVARG | ((ins &lt;= (max = length(this.texts[who]) + 1)) || (ins = max))) &amp;&amp; (this.inserting[who] = ins));
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>changed retain_session_on_exit</NAME>
          <CODE>
            return this:ok(who = args[1]) &amp;&amp; this.changes[who];
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_changed</NAME>
          <CODE>
            return this:ok(who = args[1]) &amp;&amp; (((unchanged = !args[2]) || (this.times[who] = time())) &amp;&amp; (this.changes[who] = !unchanged));
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>origin</NAME>
          <CODE>
            return this:ok(who = args[1]) &amp;&amp; this.original[who];
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_origin</NAME>
          <CODE>
            return this:ok(who = args[1]) &amp;&amp; (((valid(origin = args[2]) &amp;&amp; (origin != this)) || ((origin == $nothing) || E_INVARG)) &amp;&amp; (this.original[who] = origin));
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>readable</NAME>
          <CODE>
            return (((who = args[1]) &lt; 1) || (who &gt; length(this.active))) ? E_RANGE | this.readable[who];
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_readable</NAME>
          <CODE>
            return this:ok(who = args[1]) &amp;&amp; (this.readable[who] = !(!args[2]));
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>text</NAME>
          <CODE>
            {?who = player in this.active} = args;
            return (this:readable(who) || this:ok(who)) &amp;&amp; this.texts[who];
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>load</NAME>
          <CODE>
            texts = args[2];
            if (!(fuckup = this:ok(who = args[1])))
            return fuckup;
            elseif (typeof(texts) == STR)
            texts = {texts};
            elseif ((typeof(texts) != LIST) || (length(texts) &amp;&amp; (typeof(texts[1]) != STR)))
            return E_TYPE;
            endif
            this.texts[who] = texts;
            this.inserting[who] = length(texts) + 1;
            this.changes[who] = 0;
            this.readable[who] = 0;
            this.times[who] = time();
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>working_on</NAME>
          <CODE>
            "Dummy routine.  The child editor should provide something informative";
            return this:ok(who = args[1]) &amp;&amp; (("something [in " + this.name) + "]");
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>ok</NAME>
          <CODE>
            who = args[1];
            if ((who &lt; 1) || (who &gt; length(this.active)))
            return E_RANGE;
            elseif ((length(c = callers()) &lt; 2) ? player == this.active[who] | ((c[2][1] == this) || ($perm_utils:controls(c[2][3], this.active[who]) || (c[2][3] == $generic_editor.owner))))
            return 1;
            else
            return E_PERM;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>loaded</NAME>
          <CODE>
            return ((who = args[1] in this.active) &amp;&amp; (typeof(this.texts[who]) == LIST)) &amp;&amp; who;
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>list_line</NAME>
          <CODE>
            if (this:ok(who = args[1]))
            f = 1 + ((line = args[2]) in {(ins = this.inserting[who]) - 1, ins});
            player:tell($string_utils:right(line, 3, " _^"[f]), ":_^"[f], " ", this.texts[who][line]);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>insert_line</NAME>
          <CODE>
            ":insert_line([who,] line or list of lines [,quiet])";
            "  inserts the given text at the insertion point.";
            "  returns E_NONE if the session has no text loaded yet.";
            if (typeof(args[1]) != INT)
            args = {player in this.active, @args};
            endif
            {who, lines, ?quiet = this.active[who]:edit_option("quiet_insert")} = args;
            if (!(fuckup = this:ok(who)))
            return fuckup;
            elseif (typeof(text = this.texts[who]) != LIST)
            return E_NONE;
            else
            if (typeof(lines) != LIST)
            lines = {lines};
            endif
            p = this.active[who];
            insert = this.inserting[who];
            this.texts[who] = {@text[1..insert - 1], @lines, @text[insert..$]};
            this.inserting[who] = insert + length(lines);
            if (lines)
            if (!this.changes[who])
            this.changes[who] = 1;
            this.times[who] = time();
            endif
            if (!quiet)
            if (length(lines) != 1)
            p:tell("Lines ", insert, "-", (insert + length(lines)) - 1, " added.");
            else
            p:tell("Line ", insert, " added.");
            endif
            endif
            else
            p:tell("No lines added.");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>append_line</NAME>
          <CODE>
            ":append_line([who,] string)";
            "  appends the given string to the line before the insertion point.";
            "  returns E_NONE if the session has no text loaded yet.";
            if (typeof(args[1]) != INT)
            args = {player in this.active, @args};
            endif
            {who, string} = args;
            if (!(fuckup = this:ok(who)))
            return fuckup;
            elseif ((append = this.inserting[who] - 1) &lt; 1)
            return this:insert_line(who, {string});
            elseif (typeof(text = this.texts[who]) != LIST)
            return E_NONE;
            else
            this.texts[who][append] = text[append] + string;
            if (!this.changes[who])
            this.changes[who] = 1;
            this.times[who] = time();
            endif
            p = this.active[who];
            if (!p:edit_option("quiet_insert"))
            p:tell("Appended to line ", append, ".");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>join_lines</NAME>
          <CODE>
            {who, from, to, english} = args;
            if (!(fuckup = this:ok(who)))
            return fuckup;
            elseif (from &gt;= to)
            return 0;
            else
            nline = "";
            for line in ((text = this.texts[who])[from..to])
            if (!english)
            nline = nline + line;
            else
            len = length(line) + 1;
            while ((len = len - 1) &amp;&amp; (line[len] == " "))
            endwhile
            if (len &gt; 0)
            nline = (nline + line) + (index(".:", line[len]) ? "  " | " ");
            endif
            endif
            endfor
            this.texts[who] = {@text[1..from - 1], nline, @text[to + 1..$]};
            if ((insert = this.inserting[who]) &gt; from)
            this.inserting[who] = (insert &lt;= to) ? from + 1 | ((insert - to) + from);
            endif
            if (!this.changes[who])
            this.changes[who] = 1;
            this.times[who] = time();
            endif
            return to - from;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>parse_number</NAME>
          <CODE>
            "parse_number(who,string,before)   interprets string as a line number.  In the event that string is `.', `before' tells us which line to use.  Return 0 if string is bogus.";
            {who, string, before} = args;
            if (!(fuckup = this:ok(who)))
            return fuckup;
            endif
            last = length(this.texts[who]);
            ins = this.inserting[who] - 1;
            after = !before;
            if (!string)
            return 0;
            elseif ("." == string)
            return ins + after;
            elseif (!(i = index("_^$", string[slen = length(string)])))
            return toint(string);
            else
            start = {ins + 1, ins, last + 1}[i];
            n = 1;
            if ((slen &gt; 1) &amp;&amp; (!(n = toint(string[1..slen - 1]))))
            return 0;
            elseif (i % 2)
            return start - n;
            else
            return start + n;
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>parse_range</NAME>
          <CODE>
            "parse_range(who,default,@args) =&gt; {from to rest}";
            numargs = length(args);
            if (!(fuckup = this:ok(who = args[1])))
            return fuckup;
            elseif (!(last = length(this.texts[who])))
            return this:no_text_msg();
            endif
            default = args[2];
            r = 0;
            while (default &amp;&amp; (LIST != typeof(r = this:parse_range(who, {}, default[1]))))
            default = listdelete(default, 1);
            endwhile
            if (typeof(r) == LIST)
            from = r[1];
            to = r[2];
            else
            from = to = 0;
            endif
            saw_from_to = 0;
            not_done = 1;
            a = 2;
            while (((a = a + 1) &lt;= numargs) &amp;&amp; not_done)
            if (args[a] == "from")
            if ((a == numargs) || (!(from = this:parse_number(who, args[a = a + 1], 0))))
            return "from ?";
            endif
            saw_from_to = 1;
            elseif (args[a] == "to")
            if ((a == numargs) || (!(to = this:parse_number(who, args[a = a + 1], 1))))
            return "to ?";
            endif
            saw_from_to = 1;
            elseif (saw_from_to)
            a = a - 1;
            not_done = 0;
            elseif (i = index(args[a], "-"))
            from = this:parse_number(who, args[a][1..i - 1], 0);
            to = this:parse_number(who, args[a][i + 1..$], 1);
            not_done = 0;
            elseif (f = this:parse_number(who, args[a], 0))
            from = f;
            if ((a == numargs) || (!(to = this:parse_number(who, args[a + 1], 1))))
            to = from;
            else
            a = a + 1;
            endif
            not_done = 0;
            else
            a = a - 1;
            not_done = 0;
            endif
            endwhile
            if (from &lt; 1)
            return tostr("from ", from, "?  (out of range)");
            elseif (to &gt; last)
            return tostr("to ", to, "?  (out of range)");
            elseif (from &gt; to)
            return tostr("from ", from, " to ", to, "?  (backwards range)");
            else
            return {from, to, $string_utils:from_list(args[a..numargs], " ")};
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>parse_insert</NAME>
          <CODE>
            "parse_ins(who,string)  interprets string as an insertion point, i.e., a position between lines and returns the number of the following line or 0 if bogus.";
            if (!(fuckup = this:ok(who = args[1])))
            return fuckup;
            endif
            {who, string} = args;
            last = length(this.texts[who]) + 1;
            ins = this.inserting[who];
            if (i = index("-+", string[1]))
            rest = string[2..$];
            return ((n = toint(rest)) || (rest == "0")) ? {ins - n, ins + n}[i] | E_INVARG;
            else
            if (!(j = index(string, "^") || index(string, "_")))
            offset = 0;
            else
            offset = (j == 1) || toint(string[1..j - 1]);
            if (!offset)
            return E_INVARG;
            elseif (string[j] == "^")
            offset = -offset;
            endif
            endif
            rest = string[j + 1..$];
            if (i = rest in {".", "$"})
            return offset + {ins, last}[i];
            elseif (!(n = toint(rest)))
            return E_INVARG;
            else
            return (offset + (j &amp;&amp; (string[j] == "^"))) + n;
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>parse_subst</NAME>
          <CODE>
            {cmd, ?recognized_flags = "gcr", ?null_subst_msg = "Null substitution?"} = args;
            if (!cmd)
            return "/xxx/yyy[/[g][c]] [&lt;range&gt;] expected..";
            endif
            bchar = cmd[1];
            cmd = cmd[2..$];
            fromstr = cmd[1..(b2 = index(cmd + bchar, bchar, 1)) - 1];
            cmd = cmd[b2 + 1..$];
            tostr = cmd[1..(b2 = index(cmd + bchar, bchar, 1)) - 1];
            cmd = cmd[b2 + 1..$];
            cmdlen = length(cmd);
            b2 = 0;
            while (((b2 = b2 + 1) &lt;= cmdlen) &amp;&amp; index(recognized_flags, cmd[b2]))
            endwhile
            return ((fromstr == "") &amp;&amp; (tostr == "")) ? null_subst_msg | {fromstr, tostr, cmd[1..b2 - 1], cmd[b2..$]};
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>invoke</NAME>
          <CODE>
            ":invoke(...)";
            "to find out what arguments this verb expects,";
            "see this editor's parse_invoke verb.";
            new = args[1];
            if ((!(caller in {this, player})) &amp;&amp; (!$perm_utils:controls(caller_perms(), player)))
            "...non-editor/non-player verb trying to send someone to the editor...";
            return E_PERM;
            endif
            if ((who = this:loaded(player)) &amp;&amp; this:changed(who))
            if (!new)
            if (this:suck_in(player))
            player:tell("You are working on ", this:working_on(who));
            endif
            return;
            elseif (player.location == this)
            player:tell("You are still working on ", this:working_on(who));
            if (msg = this:previous_session_msg())
            player:tell(msg);
            endif
            return;
            endif
            "... we're not in the editor and we're about to start something new,";
            "... but there's still this pending session...";
            player:tell("You were working on ", this:working_on(who));
            if (!$command_utils:yes_or_no("Do you wish to delete that session?"))
            if (this:suck_in(player))
            player:tell("Continuing with ", this:working_on(player in this.active));
            if (msg = this:previous_session_msg())
            player:tell(msg);
            endif
            endif
            return;
            endif
            "... note session number may have changed =&gt; don't trust `who'";
            this:kill_session(player in this.active);
            endif
            spec = this:parse_invoke(@args);
            if (typeof(spec) == LIST)
            if ((player:edit_option("local") &amp;&amp; $object_utils:has_verb(this, "local_editing_info")) &amp;&amp; (info = this:local_editing_info(@spec)))
            this:invoke_local_editor(@info);
            elseif (this:suck_in(player))
            this:init_session(player in this.active, @spec);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>suck_in</NAME>
          <CODE>
            "The correct way to move someone into the editor.";
            if (((loc = (who_obj = args[1]).location) != this) &amp;&amp; (caller == this))
            this.invoke_task = task_id();
            who_obj:moveto(this);
            if (who_obj.location == this)
            try
            "...forked, just in case loc:announce is broken...";
            "changed to a try-endtry. Lets reduce tasks..Ho_Yan 12/20/96";
            if (valid(loc) &amp;&amp; (msg = this:depart_msg()))
            loc:announce($string_utils:pronoun_sub(msg));
            endif
            except (ANY)
            "Just drop it and move on";
            endtry
            else
            who_obj:tell("For some reason, I can't move you.   (?)");
            this:exitfunc(who_obj);
            endif
            this.invoke_task = 0;
            endif
            return who_obj.location == this;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>new_session</NAME>
          <CODE>
            "WIZARDLY";
            {who_obj, from} = args;
            if ($object_utils:isa(from, $generic_editor))
            "... never put an editor in .original, ...";
            if (w = who_obj in from.active)
            from = from.original[w];
            else
            from = #-1;
            endif
            endif
            if (caller != this)
            return E_PERM;
            elseif (who = who_obj in this.active)
            "... edit in progress here...";
            if (valid(from))
            this.original[who] = from;
            endif
            return -1;
            else
            for p in ({{"active", who_obj}, {"original", valid(from) ? from | $nothing}, {"times", time()}, @this.stateprops})
            this.(p[1]) = {@this.(p[1]), p[2]};
            endfor
            return length(this.active);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>kill_session</NAME>
          <CODE>
            "WIZARDLY";
            if (!(fuckup = this:ok(who = args[1])))
            return fuckup;
            else
            for p in ({@this.stateprops, {"original"}, {"active"}, {"times"}})
            this.(p[1]) = listdelete(this.(p[1]), who);
            endfor
            return who;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>reset_session</NAME>
          <CODE>
            "WIZARDLY";
            if (!(fuckup = this:ok(who = args[1])))
            return fuckup;
            else
            for p in (this.stateprops)
            this.(p[1])[who] = p[2];
            endfor
            this.times[who] = time();
            return who;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>kill_all_sessions</NAME>
          <CODE>
            "WIZARDLY";
            if ((caller != this) &amp;&amp; (!caller_perms().wizard))
            return E_PERM;
            else
            for victim in (this.contents)
            victim:tell("Sorry, ", this.name, " is going down.  Your editing session is hosed.");
            victim:moveto(((who = victim in this.active) &amp;&amp; valid(origin = this.original[who])) ? origin | (valid(victim.home) ? victim.home | $player_start));
            endfor
            for p in ({@this.stateprops, {"original"}, {"active"}, {"times"}})
            this.(p[1]) = {};
            endfor
            return 1;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>acceptable</NAME>
          <CODE>
            return is_player(who_obj = args[1]) &amp;&amp; (who_obj.wizard || pass(@args));
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>enterfunc</NAME>
          <CODE>
            who_obj = args[1];
            if (who_obj.wizard &amp;&amp; (!(who_obj in this.active)))
            this:accept(who_obj);
            endif
            pass(@args);
            if (this.invoke_task == task_id())
            "Means we're about to load something, so be quiet.";
            this.invoke_task = 0;
            elseif (who = this:loaded(who_obj))
            who_obj:tell("You are working on ", this:working_on(who), ".");
            elseif (msg = this:nothing_loaded_msg())
            who_obj:tell(msg);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>exitfunc</NAME>
          <CODE>
            if (!(who = (who_obj = args[1]) in this.active))
            elseif (this:retain_session_on_exit(who))
            if (msg = this:no_littering_msg())
            who_obj:tell_lines(msg);
            endif
            else
            this:kill_session(who);
            endif
            pass(@args);
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="any" IOBJ="any">
          <NAME>@flush</NAME>
          <CODE>
            "@flush &lt;editor&gt;";
            "@flush &lt;editor&gt; at &lt;month&gt; &lt;day&gt;";
            "@flush &lt;editor&gt; at &lt;weekday&gt;";
            "The first form removes all sessions from the editor; the other two forms remove everything older than the given date.";
            if ((caller_perms() != #-1) &amp;&amp; (caller_perms() != player))
            raise(E_PERM);
            elseif (!$perm_utils:controls(player, this))
            player:tell("Only the owner of the editor can do a ", verb, ".");
            return;
            endif
            if (!prepstr)
            player:tell("Trashing all sessions.");
            this:kill_all_sessions();
            elseif (prepstr != "at")
            player:tell("Usage:  ", verb, " ", dobjstr, " [at [mon day|weekday]]");
            else
            p = prepstr in args;
            if (t = $time_utils:from_day(iobjstr, -1))
            elseif (t = $time_utils:from_month(args[p + 1], -1))
            if (length(args) &gt; (p + 1))
            if (!(n = toint(args[p + 2])))
            player:tell(args[p + 1], " WHAT?");
            return;
            endif
            t = t + ((n - 1) * 86400);
            endif
            else
            player:tell("couldn't parse date");
            return;
            endif
            this:do_flush(t, "noisy");
            endif
            player:tell("Done.");
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="for/about" IOBJ="this">
          <NAME>@stateprop</NAME>
          <CODE>
            if (!$perm_utils:controls(player, this))
            player:tell(E_PERM);
            return;
            endif
            if (i = index(dobjstr, "="))
            default = dobjstr[i + 1..$];
            prop = dobjstr[1..i - 1];
            if (argstr[1 + index(argstr, "=")] == "\"")
            elseif (default[1] == "#")
            default = toobj(default);
            elseif (index("0123456789", default[1]))
            default = toint(default);
            elseif (default == "{}")
            default = {};
            endif
            else
            default = 0;
            prop = dobjstr;
            endif
            if (typeof(result = this:set_stateprops(prop, default)) == ERR)
            player:tell((result == E_RANGE) ? tostr(".", prop, " needs to hold a list of the same length as .active (", length(this.active), ").") | ((result != E_NACC) ? result | (prop + " is already a property on an ancestral editor.")));
            else
            player:tell("Property added.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="out of/from inside/from" IOBJ="this">
          <NAME>@rmstateprop</NAME>
          <CODE>
            if (!$perm_utils:controls(player, this))
            player:tell(E_PERM);
            elseif (typeof(result = this:set_stateprops(dobjstr)) == ERR)
            player:tell((result != E_NACC) ? result | (dobjstr + " is already a property on an ancestral editor."));
            else
            player:tell("Property removed.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>initialize</NAME>
          <CODE>
            if ($perm_utils:controls(caller_perms(), this))
            pass(@args);
            this:kill_all_sessions();
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>init_for_core</NAME>
          <CODE>
            if (caller_perms().wizard)
            pass();
            this:kill_all_sessions();
            if (this == $generic_editor)
            this.help = $editor_help;
            endif
            if ($object_utils:defines_verb(this, "is_not_banned"))
            delete_verb(this, "is_not_banned");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_stateprops</NAME>
          <CODE>
            remove = length(args) &lt; 2;
            if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
            return E_PERM;
            elseif (!(length(args) in {1, 2}))
            return E_ARGS;
            elseif (typeof(prop = args[1]) != STR)
            return E_TYPE;
            elseif (i = $list_utils:iassoc(prop, this.stateprops))
            if (!remove)
            this.stateprops[i] = {prop, args[2]};
            elseif ($object_utils:has_property(parent(this), prop))
            return E_NACC;
            else
            this.stateprops = listdelete(this.stateprops, i);
            endif
            elseif (remove)
            elseif (prop in `properties(this) ! ANY =&gt; {}')
            if (this:_stateprop_length(prop) != length(this.active))
            return E_RANGE;
            endif
            this.stateprops = {{prop, args[2]}, @this.stateprops};
            else
            return $object_utils:has_property(this, prop) ? E_NACC | E_PROPNF;
            endif
            return 0;
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>description</NAME>
          <CODE>
            is_look_self = 1;
            for c in (callers())
            if (is_look_self &amp;&amp; (c[2] in {"enterfunc", "confunc"}))
            return {"", "Do a 'look' to get the list of commands, or 'help' for assistance.", "", @this.description};
            elseif ((c[2] != "look_self") &amp;&amp; (c[2] != "pass"))
            is_look_self = 0;
            endif
            endfor
            d = {"Commands:", ""};
            col = {{}, {}};
            for c in [1..2]
            for cmd in (this.commands2[c])
            cmd = this:commands_info(cmd);
            col[c] = {cmdargs = $string_utils:left(cmd[1] + " ", 12) + cmd[2], @col[c]};
            endfor
            endfor
            i1 = length(col[1]);
            i2 = length(col[2]);
            right = 0;
            while (i1 || i2)
            if (!((i1 &amp;&amp; (length(col[1][i1]) &gt; 35)) || (i2 &amp;&amp; (length(col[2][i2]) &gt; 35))))
            d = {@d, $string_utils:left(i1 ? col[1][i1] | "", 40) + (i2 ? col[2][i2] | "")};
            i1 &amp;&amp; (i1 = i1 - 1);
            i2 &amp;&amp; (i2 = i2 - 1);
            right = 0;
            elseif (right &amp;&amp; i2)
            d = {@d, (length(col[2][i2]) &gt; 35) ? $string_utils:right(col[2][i2], 75) | ($string_utils:space(40) + col[2][i2])};
            i2 = i2 - 1;
            right = 0;
            elseif (i1)
            d = {@d, col[1][i1]};
            i1 = i1 - 1;
            right = 1;
            else
            right = 1;
            endif
            endwhile
            return {@d, "", "----  Do `help &lt;cmdname&gt;' for help with a given command.  ----", "", "  &lt;ins&gt; ::= $ (the end) | [^]n (above line n) | _n (below line n) | . (current)", "&lt;range&gt; ::= &lt;lin&gt; | &lt;lin&gt;-&lt;lin&gt; | from &lt;lin&gt; | to &lt;lin&gt; | from &lt;lin&gt; to &lt;lin&gt;", "  &lt;lin&gt; ::= n | [n]$ (n from the end) | [n]_ (n before .) | [n]^ (n after .)", "`help insert' and `help ranges' describe these in detail.", @this.description};
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>commands_info</NAME>
          <CODE>
            cmd = args[1];
            if (pc = $list_utils:assoc(cmd, this.commands))
            return pc;
            elseif (this == $generic_editor)
            return {cmd, "&lt;&lt;&lt;&lt;&lt;======= Need to add this to .commands"};
            else
            return parent(this):commands_info(cmd);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>match_object</NAME>
          <CODE>
            {objstr, ?who = player} = args;
            origin = this;
            while ((where = player in origin.active) &amp;&amp; ($recycler:valid(origin = origin.original[where]) &amp;&amp; (origin != this)))
            if (!$object_utils:isa(origin, $generic_editor))
            return origin:match_object(objstr, who);
            endif
            endwhile
            return who:my_match_object(objstr, #-1);
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>who_location_msg</NAME>
          <CODE>
            who = args[1];
            where = {#-1, @this.original}[1 + (who in this.active)];
            wherestr = `where:who_location_msg(who) ! ANY =&gt; "An Editor"';
            if (typeof(wherestr) != STR)
            wherestr = "broken who_location_msg";
            endif
            return strsub(this.who_location_msg, "%L", wherestr);
            return $string_utils:pronoun_sub(this.who_location_msg, who, this, where);
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>nothing_loaded_msg no_text_msg change_msg no_change_msg no_littering_msg depart_msg return_msg previous_session_msg</NAME>
          <CODE>
            return this.(verb);
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>announce announce_all announce_all_but tell_contents</NAME>
          <CODE>
            return;
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>fill_string</NAME>
          <CODE>
            "fill(string [, width [, prefix]])";
            "tries to cut &lt;string&gt; into substrings of length &lt; &lt;width&gt; along word boundaries.  Prefix, if supplied, will be prefixed to the 2nd..last substrings.";
            {string, ?width = 1 + player:linelen(), ?prefix = ""} = args;
            width = width + 1;
            if (width &lt; (3 + length(prefix)))
            return E_INVARG;
            endif
            string = ("$" + string) + " $";
            len = length(string);
            if (len &lt;= width)
            last = len - 1;
            next = len;
            else
            last = rindex(string[1..width], " ");
            if (last &lt; ((width + 1) / 2))
            last = width + index(string[width + 1..len], " ");
            endif
            next = last;
            while (string[next = next + 1] == " ")
            endwhile
            endif
            while (string[last = last - 1] == " ")
            endwhile
            ret = {string[2..last]};
            width = width - length(prefix);
            minlast = (width + 1) / 2;
            while (next &lt; len)
            string = "$" + string[next..len];
            len = (len - next) + 2;
            if (len &lt;= width)
            last = len - 1;
            next = len;
            else
            last = rindex(string[1..width], " ");
            if (last &lt; minlast)
            last = width + index(string[width + 1..len], " ");
            endif
            next = last;
            while (string[next = next + 1] == " ")
            endwhile
            endif
            while (string[last = last - 1] == " ")
            endwhile
            if (last &gt; 1)
            ret = {@ret, prefix + string[2..last]};
            endif
            endwhile
            return ret;
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>here_huh</NAME>
          <CODE>
            "This catches subst and find commands that don't fit into the usual model, e.g., s/.../.../ without the space after the s, and find commands without the verb `find'.  Still behaves in annoying ways (e.g., loses if the search string contains multiple whitespace), but better than before.";
            if ((caller != this) &amp;&amp; (caller_perms() != player))
            return E_PERM;
            endif
            {verb, args} = args;
            v = 1;
            vmax = min(length(verb), 5);
            while ((v &lt;= vmax) &amp;&amp; (verb[v] == "subst"[v]))
            v = v + 1;
            endwhile
            argstr = $code_utils:argstr(verb, args);
            if ((v &gt; 1) &amp;&amp; ((v &lt;= length(verb)) &amp;&amp; (((vl = verb[v]) &lt; "A") || (vl &gt; "Z"))))
            argstr = (verb[v..$] + (argstr &amp;&amp; " ")) + argstr;
            this:subst();
            return 1;
            elseif ("/" == verb[1])
            argstr = (verb + (argstr &amp;&amp; " ")) + argstr;
            this:find();
            return 1;
            else
            return 0;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>match</NAME>
          <CODE>
            return $failed_match;
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>get_room</NAME>
          <CODE>
            ":get_room([player])  =&gt; correct room to match in on invocation.";
            {?who = player} = args;
            if (who.location != this)
            return who.location;
            else
            origin = this;
            while ((where = player in origin.active) &amp;&amp; (valid(origin = origin.original[where]) &amp;&amp; (origin != this)))
            if (!$object_utils:isa(origin, $generic_editor))
            return origin;
            endif
            endwhile
            return this;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>invoke_local_editor</NAME>
          <CODE>
            ":invoke_local_editor(name, text, upload)";
            "Spits out the magic text that invokes the local editor in the player's client.";
            "NAME is a good human-readable name for the local editor to use for this particular piece of text.";
            "TEXT is a string or list of strings, the initial body of the text being edited.";
            "UPLOAD, a string, is a MOO command that the local editor can use to save the text when the user is done editing.  The local editor is going to send that command on a line by itself, followed by the new text lines, followed by a line containing only `.'.  The UPLOAD command should therefore call $command_utils:read_lines() to get the new text as a list of strings.";
            if (caller != this)
            return;
            endif
            {name, text, upload} = args;
            if (typeof(text) == STR)
            text = {text};
            endif
            notify(player, tostr("#$# edit name: ", name, " upload: ", upload));
            ":dump_lines() takes care of the final `.' ...";
            for line in ($command_utils:dump_lines(text))
            notify(player, line);
            endfor
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>_stateprop_length</NAME>
          <CODE>
            "+c properties on children cannot necessarily be read, so we need this silliness...";
            if (caller != this)
            return E_PERM;
            else
            return length(this.(args[1]));
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
          <NAME>print</NAME>
          <CODE>
            txt = this:text(player in this.active);
            if (typeof(txt) == LIST)
            player:tell_lines(txt);
            else
            player:tell("Text unreadable:  ", txt);
            endif
            player:tell("--------------------------");
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>accept</NAME>
          <CODE>
            return this:acceptable(who_obj = args[1]) &amp;&amp; this:new_session(who_obj, who_obj.location);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>y*ank</NAME>
          <CODE>
            "Usage: yank from &lt;note&gt;";
            "       yank &lt;message-sequence&gt; from &lt;mail-recipient&gt;";
            "       yank from &lt;object&gt;:&lt;verb&gt;";
            "       yank from &lt;object&gt;.&lt;property&gt;";
            "Grabs the specified text and inserts it at the cursor.";
            set_task_perms(player);
            if (dobjstr)
            "yank &lt;message-sequence&gt; from &lt;mail-recipient&gt;";
            if (!(p = player:parse_mailread_cmd(verb, args, "", "from")))
            return;
            elseif ($seq_utils:size(sequence = p[2]) != 1)
            player:notify(tostr("You can only ", verb, " one message at a time"));
            return;
            else
            m = (folder = p[1]):messages_in_seq(sequence);
            msg = m[1];
            header = tostr("Message ", msg[1]);
            if (folder != player)
            header = tostr(header, " on ", $mail_agent:name(folder));
            endif
            header = tostr(header, ":");
            lines = {header, @player:msg_full_text(@msg[2])};
            this:insert_line(this:loaded(player), lines, 0);
            endif
            elseif (pr = $code_utils:parse_propref(iobjstr))
            o = player:my_match_object(pr[1]);
            if ($command_utils:object_match_failed(o, pr[1]))
            return;
            elseif ((lines = `o.(pr[2]) ! ANY') == E_PROPNF)
            player:notify(tostr("There is no `", pr[2], "' property on ", $string_utils:nn(o), "."));
            return;
            elseif (lines == E_PERM)
            player:notify(tostr("Error: Permission denied reading ", iobjstr));
            return;
            elseif (typeof(lines) == ERR)
            player:notify(tostr("Error: ", lines, " reading ", iobjstr));
            return;
            elseif (typeof(lines) == STR)
            this:insert_line(this:loaded(player), lines, 0);
            return;
            elseif (typeof(lines) == LIST)
            for x in (lines)
            if (typeof(x) != STR)
            player:notify(tostr("Error: ", iobjstr, " does not contain a ", verb, "-able value."));
            return;
            endif
            endfor
            this:insert_line(this:loaded(player), lines, 0);
            return;
            else
            player:notify(tostr("Error: ", iobjstr, " does not contain a ", verb, "-able value."));
            return;
            endif
            elseif (pr = $code_utils:parse_verbref(iobjstr))
            o = player:my_match_object(pr[1]);
            if ($command_utils:object_match_failed(o, pr[1]))
            return;
            elseif (lines = `verb_code(o, pr[2], !player:edit_option("no_parens")) ! ANY')
            this:insert_line(this:loaded(player), lines, 0);
            return;
            elseif (lines == E_PERM)
            player:notify(tostr("Error: Permission denied reading ", iobjstr));
            return;
            elseif (lines == E_VERBNF)
            player:notify(tostr("There is no `", pr[2], "' verb on ", $string_utils:nn(o), "."));
            else
            player:notify(tostr("Error: ", lines, " reading ", iobjstr));
            return;
            endif
            elseif ($command_utils:object_match_failed(iobj = player:my_match_object(iobjstr), iobjstr))
            return;
            elseif ((lines = `iobj:text() ! ANY') == E_PERM)
            player:notify(tostr("Error: Permission denied reading ", iobjstr));
            return;
            elseif (lines == E_VERBNF)
            player:notify($string_utils:nn(iobj), " doesn't seem to be a note.");
            elseif (typeof(lines) == ERR)
            player:notify(tostr("Error: ", lines, " reading ", iobjstr));
            return;
            else
            this:insert_line(this:loaded(player), lines, 0);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>do_flush</NAME>
          <CODE>
            "Flushes editor sessions older than args[1].  If args[2] is true, prints status as it runs.  If args[2] is false, runs silently.";
            if (!$perm_utils:controls(caller_perms(), this))
            return E_PERM;
            else
            {t, noisy} = args;
            for i in [-length(this.active)..-1]
            if (this.times[-i] &lt; t)
            if (noisy)
            player:tell($string_utils:nn(this.active[-i]), ctime(this.times[-i]));
            endif
            this:kill_session(-i);
            endif
            endfor
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>s*ubst</NAME>
          <CODE>
            if (callers() &amp;&amp; (caller != this))
            return E_PERM;
            elseif (!(who = this:loaded(player)))
            player:tell(this:nothing_loaded_msg());
            elseif (typeof(subst = this:parse_subst(argstr)) != LIST)
            player:tell(tostr(subst));
            elseif (typeof(range = this:parse_range(who, {"_", "1"}, @$string_utils:explode(subst[4]))) != LIST)
            player:tell(range);
            elseif (range[3])
            player:tell("Junk at end of cmd:  ", range[3]);
            else
            {fromstr, tostr, specs, dummy} = subst;
            global = index(specs, "g", 1);
            regexp = index(specs, "r", 1);
            case = !index(specs, "c", 1);
            munged = {};
            text = this.texts[who];
            changed = {};
            {from, to} = range[1..2];
            for line in [from..to]
            t = t0 = text[line];
            if (!fromstr)
            t = tostr + t;
            elseif (global)
            if (regexp)
            while (new = this:subst_regexp(t, fromstr, tostr, case))
            t = new;
            endwhile
            else
            t = strsub(t, fromstr, tostr, case);
            endif
            else
            if (regexp)
            (new = this:subst_regexp(t, fromstr, tostr, case)) &amp;&amp; (t = new);
            else
            (i = index(t, fromstr, case)) &amp;&amp; (t = (t[1..i - 1] + tostr) + t[i + length(fromstr)..length(t)]);
            endif
            endif
            if (strcmp(t0, t))
            changed = {@changed, line};
            endif
            munged = {@munged, t};
            endfor
            if (!changed)
            player:tell("No changes in line", (from == to) ? tostr(" ", from) | tostr("s ", from, "-", to), ".");
            else
            this.texts[who] = {@text[1..from - 1], @munged, @text[to + 1..$]};
            if (!this.changes[who])
            this.changes[who] = 1;
            this.times[who] = time();
            endif
            for line in (changed)
            this:list_line(who, line);
            endfor
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>subst_regexp</NAME>
          <CODE>
            "Copied from Domain (#8111):subst_regexp by Mooshie (#106469) Mon Jan  5 19:27:26 1998 PST";
            "Usage: subst_regexp(STR text, STR from string, STR to string, INT case)";
            {text, from, to, case} = args;
            if (m = match(text, from, case))
            {start, end} = m[1..2];
            text[start..end] = substitute(to, m);
            return text;
            else
            return m;
            endif
          </CODE>
        </VERB>
        <OBJECT ID="obj47" FLAGS="r" OWNER="obj36" LOCATION="obj-1">
          <NAME>Mail Room</NAME>
          <PROPERTY OWNER="obj36" >
            <NAME>replytos</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>recipients</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>subjects</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>sending</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>readable</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>times</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>commands2</NAME>
            <VALUE>{{"say", "emote", "lis*t", "ins*ert", "n*ext,p*rev", "enter", "del*ete", "f*ind", "s*ubst", "m*ove,c*opy", "join*l", "fill"}, {"y*ank", "w*hat", "subj*ect", "to", "also-to", "reply-to", "showlists,unsubscribe", "who", "pri*nt", "send", "abort", "q*uit,done,pause"}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>help</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_text_msg</NAME>
            <VALUE>"Message body is empty."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>commands</NAME>
            <VALUE>{{"subj*ect", "[&lt;text&gt;]"}, {"to", "[&lt;rcpt&gt;..]"}, {"also-to", "[&lt;rcpt&gt;..]"}, {"reply-to", "[&lt;rcpt&gt;..]"}, {"who", "[&lt;rcpt&gt;..]"}, {"pri*nt", ""}, {"send", ""}, {"showlists,unsubscribe", ""}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>invoke_task</NAME>
            <VALUE>0</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>exit_on_abort</NAME>
            <VALUE>1</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>previous_session_msg</NAME>
            <VALUE>"You need to either SEND it or ABORT it before you can start another message."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>stateprops</NAME>
            <VALUE>{{"sending", 0}, {"replytos", {}}, {"recipients", {}}, {"subjects", ""}, {"texts", {}}, {"changes", 0}, {"inserting", 1}, {"readable", 0}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>depart_msg</NAME>
            <VALUE>"%N flattens out into a largish postage stamp and floats away."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>return_msg</NAME>
            <VALUE>"A largish postage stamp floats into the room and fattens up into %n."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_littering_msg</NAME>
            <VALUE>{"Saving your message so that you can finish it later.", "To come back, give the `@send' command with no arguments.", "Please come back and SEND or ABORT if you don't intend to be working on this", "message in the immediate future.  Keep Our MOO Clean!  No Littering!"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_change_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>change_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>nothing_loaded_msg</NAME>
            <VALUE>"You're not editing anything!"</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>texts</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>active</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>changes</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>inserting</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>original</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>who_location_msg</NAME>
            <VALUE>"%L [mailing]"</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>free_home</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>victim_ejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>ejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>residents</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>free_entry</NAME>
            <VALUE>1</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>entrances</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>blessed_object</NAME>
            <VALUE>#-1</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>blessed_task</NAME>
            <VALUE>1442346925</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>exits</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>dark</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>ctype</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>key</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>aliases</NAME>
            <VALUE>{"Mail Room"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>description</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>object_size</NAME>
            <VALUE>{23556, 919123694}</VALUE>
          </PROPERTY>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>working_on</NAME>
            <CODE>
              return this:ok(who = args[1]) &amp;&amp; tostr("a letter ", this:sending(who) ? "(in transit) " | "", "to ", this:recipient_names(who), (subject = `this.subjects[who] ! ANY') &amp;&amp; tostr(" entitled \"", subject, "\""));
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>parse_invoke</NAME>
            <CODE>
              "invoke(rcptstrings,verb[,subject]) for a @send";
              "invoke(1,verb,rcpts,subject,replyto,body) if no parsing is needed";
              "invoke(2,verb,msg,flags,replytos) for an @answer";
              if (!(which = args[1]))
              player:tell_lines({tostr("Usage:  ", args[2], " &lt;list-of-recipients&gt;"), tostr("        ", args[2], "                      to continue with a previous draft")});
              elseif (typeof(which) == LIST)
              "...@send...";
              if (rcpts = this:parse_recipients({}, which))
              if (replyto = player:mail_option("replyto"))
              replyto = this:parse_recipients({}, replyto, ".mail_options: ");
              endif
              if (0 == (subject = {@args, 0}[3]))
              if (player:mail_option("nosubject"))
              subject = "";
              else
              player:tell("Subject:");
              subject = $command_utils:read();
              endif
              endif
              return {rcpts, subject, replyto, {}};
              endif
              elseif (which == 1)
              return args[3..6];
              elseif (!(to_subj = this:parse_msg_headers(msg = args[3], flags = args[4])))
              else
              include = {};
              if ("include" in flags)
              prefix = "&gt;            ";
              for line in ($mail_agent:to_text(@msg))
              if (!line)
              prefix = "&gt;  ";
              include = {@include, prefix};
              else
              include = {@include, @this:fill_string("&gt;  " + line, 70, prefix)};
              endif
              endfor
              endif
              return {@to_subj, args[5], include};
              endif
              return 0;
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>init_session</NAME>
            <CODE>
              {who, recip, subj, replyto, msg} = args;
              if (this:ok(who))
              this.sending[who] = 0;
              this.recipients[who] = recip;
              this.subjects[who] = subj;
              this.replytos[who] = replyto || {};
              this:load(who, msg);
              this.active[who]:tell("Composing ", this:working_on(who));
              p = this.active[who];
              "if (p:mail_option(\"enter\") &amp;&amp; !args[5])";
              "Changed from above so that @reply can take advantage of @mailoption +enter. Ho_Yan 11/9/94";
              if (p:mail_option("enter"))
              if (typeof(lines = $command_utils:read_lines()) == ERR)
              p:tell(lines);
              else
              this:insert_line(p in this.active, lines, 0);
              endif
              endif
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
            <NAME>pri*nt</NAME>
            <CODE>
              if (!dobjstr)
              plyr = player;
              elseif ($command_utils:player_match_result(plyr = $string_utils:match_player(dobjstr), dobjstr)[1])
              return;
              endif
              if ((plyr != player) &amp;&amp; (!this:readable(plyr in this.active)))
              player:tell(plyr.name, "(", plyr, ") has not published anything here.");
              elseif (typeof(msg = this:message_with_headers(plyr in this.active)) != LIST)
              player:tell(msg);
              else
              player:display_message({((plyr == player) ? "Your" | tostr(plyr.name, "(", plyr, ")'s")) + " message so far:", ""}, player:msg_text(@msg));
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>message_with_headers</NAME>
            <CODE>
              return (this:readable(who = args[1]) || this:ok(who)) &amp;&amp; $mail_agent:make_message(this.active[who], this.recipients[who], {this.subjects[who], this.replytos[who]}, this:text(who));
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>subj*ect:</NAME>
            <CODE>
              if (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              elseif (!argstr)
              player:tell(this.subjects[who]);
              elseif (ERR == typeof(subj = this:set_subject(who, argstr)))
              player:tell(subj);
              else
              player:tell(subj ? ("Setting the subject line for your message to \"" + subj) + "\"." | "Deleting the subject line for your message.");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>set_subject</NAME>
            <CODE>
              if (!(fuckup = this:ok(who = args[1])))
              return fuckup;
              else
              this.subjects[who] = subj = args[2];
              this:set_changed(who, 1);
              return subj;
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>sending</NAME>
            <CODE>
              if (!(fuckup = this:ok(who = args[1])))
              return fuckup;
              elseif ((!(task = this.sending[who])) || $code_utils:task_valid(task))
              return task;
              else
              "... uh oh... sending task crashed...";
              this:set_changed(who, 1);
              return this.sending[who] = 0;
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>to*:</NAME>
            <CODE>
              if (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              elseif (!args)
              player:tell("Your message is currently to ", this:recipient_names(who), ".");
              else
              this.recipients[who] = this:parse_recipients({}, args);
              this:set_changed(who, 1);
              player:tell("Your message is now to ", this:recipient_names(who), ".");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>also*-to: cc*:</NAME>
            <CODE>
              if (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              else
              this.recipients[who] = this:parse_recipients(this.recipients[who], args);
              this:set_changed(who, 1);
              player:tell("Your message is now to ", this:recipient_names(who), ".");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>not-to*: uncc*:</NAME>
            <CODE>
              if (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              else
              recips = this.recipients[who];
              nonmrs = {};
              mrs = {};
              for o in (recips)
              if ($object_utils:isa(o, $mail_recipient))
              mrs = {@mrs, o};
              else
              nonmrs = {@nonmrs, o};
              endif
              endfor
              for a in (args)
              if (!a)
              player:tell("\"\"?");
              return;
              elseif (valid(aobj = $mail_agent:match_recipient(a)) &amp;&amp; (aobj in recips))
              elseif ($failed_match != (aobj = $string_utils:literal_object(a)))
              if (!(aobj in recips))
              player:tell(aobj, " was not a recipient.");
              return;
              endif
              elseif ((a[1] == "*") &amp;&amp; valid(aobj = $string_utils:match(a[2..$], mrs, "aliases")))
              elseif ((a[1] != "*") &amp;&amp; valid(aobj = $string_utils:match(a, nonmrs, "aliases")))
              elseif (valid(aobj = $string_utils:match(a, recips, "aliases")))
              else
              player:tell("couldn't find \"", a, "\" in To: list.");
              return;
              endif
              recips = setremove(recips, aobj);
              endfor
              this.recipients[who] = recips;
              this:set_changed(who, 1);
              player:tell("Your message is now to ", this:recipient_names(who), ".");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>parse_recipients</NAME>
            <CODE>
              "parse_recipients(prev_list,list_of_strings) -- parses list of strings and adds any resulting player objects to prev_list.  Optional 3rd arg is prefixed to any mismatch error messages";
              {recips, l, ?cmd_id = ""} = args;
              cmd_id = cmd_id || "";
              for s in ((typeof(l) == LIST) ? l | {l})
              if (typeof(s) != STR)
              if ($mail_agent:is_recipient(s))
              recips = setadd(recips, s);
              else
              player:tell(cmd_id, s, " is not a valid mail recipient.");
              endif
              elseif (!$mail_agent:match_failed(md = $mail_agent:match_recipient(s), s, cmd_id))
              recips = setadd(recips, md);
              endif
              endfor
              return recips;
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>recipient_names</NAME>
            <CODE>
              return this:ok(who = args[1]) &amp;&amp; $mail_agent:name_list(@this.recipients[who]);
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>make_message</NAME>
            <CODE>
              return $mail_agent:make_message(@args);
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>name_list</NAME>
            <CODE>
              "(obsolete verb... see $mail_agent:name_list)";
              return $mail_agent:(verb)(@args[1]);
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>parse_msg_headers</NAME>
            <CODE>
              "parse_msg_headers(msg,flags)";
              "  parses msg to extract reply recipients and construct a subject line";
              "  if the \"all\" flag is present, reply goes to all of the original recipients";
              "  returns a list {recipients, subjectline} or 0 in case of error.";
              {msg, flags} = args;
              replyall = "all" in flags;
              objects = {};
              if ("followup" in flags)
              "...look for first non-player recipient in To: line...";
              for o in ($mail_agent:parse_address_field(msg[3]))
              if (objects)
              break o;
              elseif ($object_utils:isa(o, $mail_recipient))
              objects = {o};
              endif
              endfor
              endif
              objects = objects || $mail_agent:parse_address_field(msg[2] + (replyall ? msg[3] | ""));
              for line in (msg[5..("" in {@msg, ""}) - 1])
              if (rt = index(line, "Reply-to:") == 1)
              objects = $mail_agent:parse_address_field(line);
              endif
              endfor
              recips = {};
              for o in (objects)
              if (o == #0)
              player:tell("Sorry, but I can't parse the header of that message.");
              return 0;
              elseif ((!valid(o)) || (!(is_player(o) || ($mail_recipient in $object_utils:ancestors(o)))))
              player:tell(o, " is no longer a valid player or maildrop; ignoring that recipient.");
              elseif (o != player)
              recips = setadd(recips, o);
              endif
              endfor
              subject = msg[4];
              if (subject == " ")
              subject = "";
              elseif (subject &amp;&amp; (index(subject, "Re: ") != 1))
              subject = "Re: " + subject;
              endif
              return {recips, subject};
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>check_answer_flags</NAME>
            <CODE>
              flags = {};
              for o in ({"all", "include", "followup"})
              if (player:mail_option(o))
              flags = {@flags, o};
              endif
              endfor
              reply_to = player:mail_option("replyto") || {};
              flaglist = "+1#include -1#noinclude +2#all -2#sender 0#replyto +3#followup ";
              for a in (args)
              if (i = index(a, "="))
              value = a[i + 1..$];
              a = a[1..i - 1];
              else
              value = "";
              endif
              if ((typeof(a) != STR) || ((i = index(flaglist, "#" + a)) &lt; 3))
              player:tell("Unrecognized answer/reply option:  ", a);
              return 0;
              elseif (i != rindex(flaglist, "#" + a))
              player:tell("Ambiguous answer/reply option:  ", a);
              return 0;
              elseif (j = index("0123456789", flaglist[i - 1]) - 1)
              if (value)
              player:tell("Flag does not take a value:  ", a);
              return 0;
              endif
              f = {"include", "all", "followup"}[j];
              flags = (flaglist[i - 2] == "+") ? setadd(flags, f) | setremove(flags, f);
              if (f == "all")
              flags = setremove(flags, "followup");
              endif
              elseif ((!value) || (value = this:parse_recipients({}, $string_utils:explode(value), "replyto flag:  ")))
              reply_to = value || {};
              endif
              endfor
              return {flags, reply_to};
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>reply-to*: replyto*:</NAME>
            <CODE>
              if (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              else
              if (args)
              this.replytos[who] = rt = this:parse_recipients({}, args);
              this:set_changed(who, 1);
              else
              rt = this.replytos[who];
              endif
              player:tell(rt ? ("Replies will go to " + $mail_agent:name_list(@this.replytos[who])) + "." | "Reply-to field is empty.");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
            <NAME>send</NAME>
            <CODE>
              "WIZARDLY";
              if (!(who = this:loaded(player)))
              player:notify(this:nothing_loaded_msg());
              elseif (!(recips = this.recipients[who]))
              player:notify("Umm... your message isn't addressed to anyone.");
              elseif (this:sending(who))
              player:notify("Again? ... relax... it'll get there eventually.");
              else
              msg = this:message_with_headers(who);
              this.sending[who] = old_sending = task_id();
              this:set_changed(who, 0);
              player:notify("Sending...");
              "... this sucker can suspend BIG TIME...";
              result = $mail_agent:raw_send(msg, recips, player);
              "... the world changes...";
              who = player in this.active;
              if (who &amp;&amp; (this.sending[who] == old_sending))
              "... same editing session; no problemo...";
              previous = "";
              this.sending[who] = 0;
              else
              "... uh oh, different session... tiptoe quietly out...";
              "... Don't mess with the session.";
              previous = "(prior send) ";
              endif
              if (!(e = result[1]))
              player:notify(tostr(previous, (typeof(e) == ERR) ? e | ("Bogus recipients:  " + $string_utils:from_list(result[2]))));
              player:notify(tostr(previous, "Mail not sent."));
              previous || this:set_changed(who, 1);
              elseif (length(result) == 1)
              player:notify(tostr(previous, "Mail not actually sent to anyone."));
              previous || this:set_changed(who, 1);
              else
              player:notify(tostr(previous, "Mail actually sent to ", $mail_agent:name_list(@listdelete(result, 1))));
              if (previous)
              "...don't even think about it...";
              elseif (player.location == this)
              if (ticks_left() &lt; 10000)
              suspend(0);
              endif
              this:done();
              elseif (!this:changed(who))
              "... player is gone, no further edits...";
              this:kill_session(who);
              endif
              endif
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
            <NAME>who</NAME>
            <CODE>
              if (dobjstr)
              if (!(recips = this:parse_recipients({}, args)))
              "parse_recipients has already complained about anything it doesn't like";
              return;
              endif
              elseif (caller != player)
              return E_PERM;
              elseif (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              return;
              else
              recips = this.recipients[who];
              endif
              resolve = $mail_agent:resolve_addr(recips, player);
              if (resolve[1])
              player:tell("Bogus addresses:  ", $string_utils:english_list(resolve[1]));
              else
              player:tell(dobjstr ? ("Mail to " + $mail_agent:name_list(@recips)) + " actually goes to " | "Your mail will actually go to ", $mail_agent:name_list(@resolve[2]));
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
            <NAME>showlists</NAME>
            <CODE>
              player:tell_lines({"Available aliases:", ""});
              for c in ((dobjstr == "all") ? $object_utils:descendants($mail_recipient) | $mail_agent.contents)
              if (c:is_usable_by(player) || c:is_readable_by(player))
              c:look_self();
              endif
              endfor
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="at/to" IOBJ="any">
            <NAME>subsc*ribe</NAME>
            <CODE>
              player:tell("This command is obsolete.  Use @subscribe instead.  See `help @subscribe'");
              return;
              if (!iobjstr)
              player:tell("Usage:  ", verb, " [&lt;list-of-people/lists&gt;] to &lt;list&gt;");
              return;
              elseif ($mail_agent:match_failed(iobj = $mail_agent:match(iobjstr), iobjstr))
              return;
              endif
              rstrs = dobjstr ? $string_utils:explode(dobjstr) | {"me"};
              recips = this:parse_recipients({}, rstrs);
              outcomes = iobj:add_forward(@recips);
              if (typeof(outcomes) != LIST)
              player:tell(outcomes);
              return;
              endif
              added = {};
              for r in [1..length(recips)]
              if ((t = typeof(e = outcomes[r])) == OBJ)
              added = setadd(added, recips[r]);
              else
              player:tell(verb, " ", recips[r].name, " to ", iobj.name, ":  ", e);
              endif
              endfor
              if (added)
              player:tell($string_utils:english_list($list_utils:map_arg(2, $string_utils, "pronoun_sub", "%(name) (%#)", added)), " added to ", iobj.name, " (", iobj, ")");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="out of/from inside/from" IOBJ="any">
            <NAME>unsubsc*ribe</NAME>
            <CODE>
              if (!iobjstr)
              player:tell("Usage:  ", verb, " [&lt;list-of-people/lists&gt;] from &lt;list&gt;");
              return;
              elseif ($mail_agent:match_failed(iobj = $mail_agent:match(iobjstr), iobjstr))
              return;
              endif
              rstrs = dobjstr ? $string_utils:explode(dobjstr) | {"me"};
              recips = this:parse_recipients({}, rstrs);
              outcomes = iobj:delete_forward(@recips);
              if (typeof(outcomes) != LIST)
              player:tell(outcomes);
              return;
              endif
              removed = {};
              for r in [1..length(recips)]
              if (typeof(e = outcomes[r]) == ERR)
              player:tell(verb, " ", recips[r].name, " from ", iobj.name, ":  ", (e == E_INVARG) ? "Not on list." | e);
              else
              removed = setadd(removed, recips[r]);
              endif
              endfor
              if (removed)
              player:tell($string_utils:english_list($list_utils:map_arg(2, $string_utils, "pronoun_sub", "%(name) (%#)", removed)), " removed from ", iobj.name, " (", iobj, ")");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>retain_session_on_exit</NAME>
            <CODE>
              return this:ok(who = args[1]) &amp;&amp; (this:sending(who) || pass(@args));
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>no_littering_msg</NAME>
            <CODE>
              "recall that this only gets called if :retain_session_on_exit returns true";
              return (this:ok(who = player in this.active) &amp;&amp; (!this:changed(who))) ? {"Your message is in transit."} | this.(verb);
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>parse_msg_headers(slow)</NAME>
            <CODE>
              "parse_msg_headers(msg,flags)";
              "  parses msg to extract reply recipients and construct a subject line";
              "  if the \"all\" flag is present, reply goes to all of the original recipients";
              "  returns a list {recipients, subjectline} or 0 in case of error.";
              msg = args[1];
              replyall = "all" in args[2];
              recipients = $mail_agent:parse_address_field(msg[2] + (replyall ? msg[3] | ""));
              subject = msg[4];
              if (subject == " ")
              subject = "";
              endif
              noreplyto = 1;
              for line in (msg[1..("" in msg) || length(msg)])
              if (typeof(line) != STR)
              "Skip it";
              elseif (index(line, "Subject:") == 1)
              subject = $string_utils:triml(line[9..length(line)]);
              elseif ((rt = index(line, "Reply-to:") == 1) || (noreplyto &amp;&amp; ((index(line, "From:") == 1) || (replyall &amp;&amp; (index(line, "To:") == 1)))))
              if (rt)
              noreplyto = 0;
              recipients = {};
              endif
              recipients = {@recipients, @$mail_agent:parse_address_field(line)};
              endif
              endfor
              if (subject &amp;&amp; (index(subject, "Re: ") != 1))
              subject = "Re: " + subject;
              endif
              recips = {};
              for o in (recipients)
              if (o == #0)
              player:tell("Sorry, but I can't parse the header of that message.");
              return 0;
              elseif ((!valid(o)) || (!(is_player(o) || ($mail_recipient in $object_utils:ancestors(o)))))
              player:tell(o, " is no longer a valid player or maildrop; ignoring that recipient.");
              elseif (o != player)
              recips = setadd(recips, o);
              endif
              endfor
              return {recips, subject};
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>local_editing_info</NAME>
            <CODE>
              lines = {"To:       " + (toline = $mail_agent:name_list(@args[1])), "Subject:  " + $string_utils:trim(subject = args[2])};
              if (args[3])
              lines = {@lines, "Reply-to: " + $mail_agent:name_list(@args[3])};
              endif
              lines = {@lines, "", @args[4]};
              return {tostr("MOOMail", subject ? ("(" + subject) + ")" | (("-to(" + toline) + ")")), lines, "@@sendmail"};
            </CODE>
          </VERB>
        </OBJECT>
        <OBJECT ID="obj48" FLAGS="r" OWNER="obj36" LOCATION="obj-1">
          <NAME>Note Editor</NAME>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>strmode</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>objects</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>readable</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>times</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>commands2</NAME>
            <VALUE>{{"say", "emote", "lis*t", "ins*ert", "n*ext,p*rev", "enter", "del*ete", "f*ind", "s*ubst", "m*ove,c*opy", "join*l", "fill"}, {"y*ank", "w*hat", "mode", "e*dit", "save", "abort", "q*uit,done,pause"}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>help</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_text_msg</NAME>
            <VALUE>"Note is devoid of text."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>commands</NAME>
            <VALUE>{{"e*dit", "&lt;note&gt;"}, {"save", "[&lt;note&gt;]"}, {"mode", "[string|list]"}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>invoke_task</NAME>
            <VALUE>0</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>exit_on_abort</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>previous_session_msg</NAME>
            <VALUE>"You need to ABORT or SAVE this note before editing any other."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>stateprops</NAME>
            <VALUE>{{"strmode", 0}, {"objects", 0}, {"texts", 0}, {"changes", 0}, {"inserting", 1}, {"readable", 0}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>depart_msg</NAME>
            <VALUE>"A small swarm of 3x5 index cards arrives, engulfs %n, and carries %o away."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>return_msg</NAME>
            <VALUE>"A small swarm of 3x5 index cards blows in and disperses, revealing %n."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_littering_msg</NAME>
            <VALUE>{"Partially edited text will be here when you get back.", "To return, give the `@notedit' command with no arguments.", "Please come back and SAVE or ABORT if you don't intend to be working on this text in the immediate future.  Keep Our MOO Clean!  No Littering!"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_change_msg</NAME>
            <VALUE>"Note has not been modified since the last save."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>change_msg</NAME>
            <VALUE>"There are changes."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>nothing_loaded_msg</NAME>
            <VALUE>"Use the EDIT command to select a note."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>texts</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>active</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>changes</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>inserting</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>original</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>who_location_msg</NAME>
            <VALUE>"%L [editing notes]"</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>free_home</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>victim_ejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>ejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>residents</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>free_entry</NAME>
            <VALUE>1</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>entrances</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>blessed_object</NAME>
            <VALUE>#-1</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>blessed_task</NAME>
            <VALUE>499657208</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>exits</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>dark</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>ctype</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>key</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>aliases</NAME>
            <VALUE>{"Note Editor", "nedit"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>description</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>object_size</NAME>
            <VALUE>{9824, 919123694}</VALUE>
          </PROPERTY>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
            <NAME>e*dit</NAME>
            <CODE>
              if (this:changed(who = player in this.active))
              player:tell("You are still editing ", this:working_on(who), ".  Please type ABORT or SAVE first.");
              elseif (spec = this:parse_invoke(dobjstr, verb))
              this:init_session(who, @spec);
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
            <NAME>save</NAME>
            <CODE>
              if (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              return;
              endif
              if (!dobjstr)
              note = this.objects[who];
              elseif (1 == (note = this:note_match_failed(dobjstr)))
              return;
              else
              this.objects[who] = note;
              endif
              text = this:text(who);
              strmode = (length(text) &lt;= 1) &amp;&amp; this.strmode[who];
              if (strmode)
              text = text ? text[1] | "";
              endif
              if (ERR == typeof(result = this:set_note_text(note, text)))
              player:tell("Text not saved to ", this:working_on(who), ":  ", result);
              if ((result == E_TYPE) &amp;&amp; (typeof(note) == OBJ))
              player:tell("Do `mode list' and try saving again.");
              elseif (!dobjstr)
              player:tell("Use `save' with an argument to save the text elsewhere.");
              endif
              else
              player:tell("Text written to ", this:working_on(who), strmode ? " as a single string." | ".");
              this:set_changed(who, 0);
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>init_session</NAME>
            <CODE>
              if (this:ok(who = args[1]))
              this.strmode[who] = strmode = typeof(text = args[3]) == STR;
              this:load(who, strmode ? text ? {text} | {} | text);
              this.objects[who] = args[2];
              player:tell("Now editing ", this:working_on(who), ".", strmode ? "  [string mode]" | "");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>working_on</NAME>
            <CODE>
              if (!(who = args[1]))
              return "????";
              endif
              spec = this.objects[who];
              if (typeof(spec) == LIST)
              object = spec[1];
              prop = spec[2];
              else
              object = spec;
              prop = 0;
              endif
              return valid(object) ? tostr("\"", object.name, "\"(", object, ")", prop ? "." + prop | "") | tostr(prop ? ("." + prop) + " on " | "", "invalid object (", object, ")");
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>parse_invoke</NAME>
            <CODE>
              ":parse_invoke(string,verb)";
              " string is the actual commandline string indicating what we are to edit";
              " verb is the command verb that is attempting to invoke the editor";
              if (!(string = args[1]))
              player:tell_lines({("Usage:  " + args[2]) + " &lt;note&gt;   (where &lt;note&gt; is some note object)", ("        " + args[2]) + "          (continues editing an unsaved note)"});
              elseif (1 == (note = this:note_match_failed(string)))
              elseif (ERR == typeof(text = this:note_text(note)))
              player:tell("Couldn't retrieve text:  ", text);
              else
              return {note, text};
              endif
              return 0;
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>note_text</NAME>
            <CODE>
              "WIZARDLY";
              if ((caller != $note_editor) || (caller_perms() != $note_editor.owner))
              return E_PERM;
              endif
              set_task_perms(player);
              if (typeof(spec = args[1]) == OBJ)
              text = spec:text();
              else
              text = `spec[1].(spec[2]) ! ANY';
              endif
              if (((tt = typeof(text)) in {ERR, STR}) || ((tt == LIST) &amp;&amp; ((!text) || (typeof(text[1]) == STR))))
              return text;
              else
              return E_TYPE;
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>set_note_text</NAME>
            <CODE>
              "WIZARDLY";
              if ((caller != $note_editor) || (caller_perms() != $note_editor.owner))
              return E_PERM;
              endif
              set_task_perms(player);
              attempt = E_NONE;
              if (typeof(spec = args[1]) == OBJ)
              return spec:set_text(args[2]);
              elseif ($object_utils:has_callable_verb(spec[1], "set_" + spec[2]))
              attempt = spec[1]:("set_" + spec[2])(args[2]);
              endif
              if (typeof(attempt) == ERR)
              return `spec[1].(spec[2]) = args[2] ! ANY';
              else
              return attempt;
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>note_match_failed</NAME>
            <CODE>
              if (pp = $code_utils:parse_propref(string = args[1]))
              object = pp[1];
              prop = pp[2];
              else
              object = string;
              prop = 0;
              endif
              if ($command_utils:object_match_failed(note = player:my_match_object(object, this:get_room(player)), object))
              elseif (prop)
              if (!$object_utils:has_property(note, prop))
              player:tell(object, " has no \".", prop, "\" property.");
              else
              return {note, prop};
              endif
              elseif ((!$object_utils:has_callable_verb(note, "text")) || (!$object_utils:has_callable_verb(note, "set_text")))
              return {note, "description"};
              "... what we used to do.  but why barf?   that's no fun...";
              player:tell(object, "(", note, ") doesn't look like a note.");
              else
              return note;
              endif
              return 1;
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
            <NAME>w*hat</NAME>
            <CODE>
              pass(@args);
              if ((who = this:loaded(player)) &amp;&amp; this.strmode[who])
              player:tell("Text will be stored as a single string instead of a list when possible.");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
            <NAME>mode</NAME>
            <CODE>
              "mode [string|list]";
              if (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              return;
              endif
              if (dobjstr &amp;&amp; (index("string", dobjstr) == 1))
              this.strmode[who] = mode = 1;
              player:tell("Now in string mode:");
              elseif (dobjstr &amp;&amp; (index("list", dobjstr) == 1))
              this.strmode[who] = mode = 0;
              player:tell("Now in list mode:");
              elseif (dobjstr)
              player:tell("Unrecognized mode:  ", dobjstr);
              player:tell("Should be one of `string' or `list'");
              return;
              else
              player:tell("Currently in ", mode = this.strmode[who] ? "string " | "list ", "mode:");
              endif
              if (mode)
              player:tell("  store text as a single string instead of a list when possible.");
              else
              player:tell("  always store text as a list of strings.");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>local_editing_info</NAME>
            <CODE>
              {what, text} = args;
              cmd = (typeof(text) == STR) ? "@set-note-string" | "@set-note-text";
              name = (typeof(what) == OBJ) ? what.name | tostr(what[1].name, ".", what[2]);
              note = (typeof(what) == OBJ) ? what | tostr(what[1], ".", what[2]);
              return {name, text, tostr(cmd, " ", note)};
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>set_*</NAME>
            <CODE>
              if ($perm_utils:controls(caller_perms(), this))
              return pass(@args);
              else
              return E_PERM;
              endif
            </CODE>
          </VERB>
        </OBJECT>
        <OBJECT ID="obj49" FLAGS="r" OWNER="obj36" LOCATION="obj-1">
          <NAME>Verb Editor</NAME>
          <PROPERTY OWNER="obj36" >
            <NAME>objects</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>verbnames</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>readable</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>times</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>commands2</NAME>
            <VALUE>{{"say", "emote", "lis*t", "ins*ert", "n*ext,p*rev", "enter", "del*ete", "f*ind", "s*ubst", "m*ove,c*opy", "join*l", "fill"}, {"y*ank", "w*hat", "e*dit", "com*pile", "abort", "q*uit,done,pause"}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>help</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_text_msg</NAME>
            <VALUE>"Verb body is empty."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>commands</NAME>
            <VALUE>{{"e*dit", "&lt;obj&gt;:&lt;verb&gt;"}, {"com*pile", "[as &lt;obj&gt;:&lt;verb&gt;]"}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>invoke_task</NAME>
            <VALUE>0</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>exit_on_abort</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>previous_session_msg</NAME>
            <VALUE>"You need to either COMPILE or ABORT this verb before you can start on another."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>stateprops</NAME>
            <VALUE>{{"objects", 0}, {"verbnames", 0}, {"texts", 0}, {"changes", 0}, {"inserting", 1}, {"readable", 0}}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>depart_msg</NAME>
            <VALUE>"You hear the bips of keyclick, the sliding of mice and the hum of computers in the distance as %n fades slowly out of view, heading towards them."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>return_msg</NAME>
            <VALUE>"There are the light bips of keyclick and the sliding of mice as %n fades into view, shoving %r away from the console, which promptly fades away."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_littering_msg</NAME>
            <VALUE>{"Keeping your verb for later work.  ", "To return, give the `@edit' command with no arguments.", "Please come back and COMPILE or ABORT if you don't intend to be working on this verb in the immediate future.  Keep Our MOO Clean!  No Littering!"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>no_change_msg</NAME>
            <VALUE>"The verb has no pending changes."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>change_msg</NAME>
            <VALUE>"You have changed the verb since last successful compile."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>nothing_loaded_msg</NAME>
            <VALUE>"First, you have to select a verb to edit with the EDIT command."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>texts</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>active</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>changes</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>inserting</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>original</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>who_location_msg</NAME>
            <VALUE>"%L [editing verbs]"</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>free_home</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>victim_ejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>ejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oejection_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>residents</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>free_entry</NAME>
            <VALUE>1</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>entrances</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>blessed_object</NAME>
            <VALUE>#-1</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>blessed_task</NAME>
            <VALUE>1614342745</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>exits</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>dark</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>ctype</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>key</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>aliases</NAME>
            <VALUE>{"Verb Editor", "vedit", "verbedit", "verb edit"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>description</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>object_size</NAME>
            <VALUE>{13425, 919123694}</VALUE>
          </PROPERTY>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
            <NAME>e*dit</NAME>
            <CODE>
              if (!args)
              player:tell("edit what?");
              else
              this:invoke(argstr, verb);
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="none" PREP="any" IOBJ="any">
            <NAME>com*pile save</NAME>
            <CODE>
              pas = {{}, {}};
              if (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              return;
              elseif (!args)
              object = this.objects[who];
              vname = this.verbnames[who];
              if (typeof(vname) == LIST)
              vargs = listdelete(vname, 1);
              vname = vname[1];
              else
              vargs = {};
              endif
              changeverb = 0;
              elseif ((args[1] != "as") || ((length(args) &lt; 2) || ((!(spec = $code_utils:parse_verbref(args[2]))) || ((typeof(pas = $code_utils:parse_argspec(@args[3..$])) != LIST) || pas[2]))))
              if (typeof(pas) != LIST)
              player:tell(pas);
              elseif (pas[2])
              player:tell("I don't understand \"", $string_utils:from_list(pas[2], " "), "\"");
              endif
              player:tell("Usage: ", verb, " [as &lt;object&gt;:&lt;verb&gt;]");
              return;
              elseif ($command_utils:object_match_failed(object = player:my_match_object(spec[1], this:get_room(player)), spec[1]))
              return;
              else
              vname = spec[2];
              vargs = pas[1] &amp;&amp; {@pas[1], "none", "none"}[1..3];
              if (vargs)
              vargs[2] = $code_utils:full_prep(vargs[2]) || vargs[2];
              endif
              changeverb = 1;
              endif
              if (vargs)
              vnum = $code_utils:find_verb_named(object, vname);
              while (vnum &amp;&amp; (verb_args(object, vnum) != vargs))
              vnum = $code_utils:find_verb_named(object, vname, vnum + 1);
              endwhile
              if (!vnum)
              player:tell("There is no ", object, ":", vname, " verb with args (", $string_utils:from_list(vargs, " "), ").");
              if (!changeverb)
              player:tell("Use 'compile as ...' to write your code to another verb.");
              endif
              return;
              endif
              objverbname = tostr(object, ":", vname, " (", $string_utils:from_list(vargs, " "), ")");
              else
              vnum = 0;
              objverbname = tostr(object, ":", ($code_utils:toint(vname) == E_TYPE) ? vname | this:verb_name(object, vname));
              endif
              "...";
              "...perform eval_subs on verb code if necessary...";
              "...";
              if (player.eval_subs &amp;&amp; player:edit_option("eval_subs"))
              verbcode = {};
              for x in (this:text(who))
              verbcode = {@verbcode, $code_utils:substitute(x, player.eval_subs)};
              endfor
              else
              verbcode = this:text(who);
              endif
              "...";
              "...write it out...";
              "...";
              if (result = this:set_verb_code(object, vnum ? vnum | vname, verbcode))
              player:tell(objverbname, " not compiled because:");
              for x in (result)
              player:tell("  ", x);
              endfor
              elseif (typeof(result) == ERR)
              player:tell({result, ("You do not have write permission on " + objverbname) + ".", ("The verb " + objverbname) + " does not exist (!?!)", ("The object " + tostr(object)) + " does not exist (!?!)"}[1 + (result in {E_PERM, E_VERBNF, E_INVARG})]);
              if (!changeverb)
              player:tell("Do 'compile as &lt;object&gt;:&lt;verb&gt;' to write your code to another verb.");
              endif
              changeverb = 0;
              else
              player:tell(objverbname, verbcode ? " successfully compiled." | " verbcode removed.");
              this:set_changed(who, 0);
              endif
              if (changeverb)
              this.objects[who] = object;
              this.verbnames[who] = vargs ? {vname, @vargs} | vname;
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>working_on</NAME>
            <CODE>
              if (!(fuckup = this:ok(who = args[1])))
              return fuckup;
              else
              object = this.objects[who];
              verbname = this.verbnames[who];
              if (typeof(verbname) == LIST)
              return tostr(object, ":", verbname[1], " (", $string_utils:from_list(listdelete(verbname, 1), " "), ")");
              else
              return tostr(object, ":", this:verb_name(object, verbname), " (", this:verb_args(object, verbname), ")");
              endif
              endif
              "return this:ok(who = args[1]) &amp;&amp; tostr(this.objects[who]) + \":\" + this.verbnames[who];";
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>init_session</NAME>
            <CODE>
              {who, object, vname, vcode} = args;
              if (this:ok(who))
              this:load(who, vcode);
              this.verbnames[who] = vname;
              this.objects[who] = object;
              this.active[who]:tell("Now editing ", this:working_on(who), ".");
              "this.active[who]:tell(\"Now editing \", object, \":\", vname, \".\");";
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>parse_invoke</NAME>
            <CODE>
              ":parse_invoke(string,v,?code)";
              "  string is the commandline string to parse to obtain the obj:verb to edit";
              "  v is the actual command verb used to invoke the editor";
              " =&gt; {object, verbname, verb_code} or error";
              vref = $string_utils:words(args[1]);
              if ((!vref) || (!(spec = $code_utils:parse_verbref(vref[1]))))
              player:tell("Usage: ", args[2], " object:verb");
              return;
              endif
              if (argspec = listdelete(vref, 1))
              if (typeof(pas = $code_utils:parse_argspec(@argspec)) == LIST)
              if (pas[2])
              player:tell("I don't understand \"", $string_utils:from_list(pas[2], " "), "\"");
              return;
              endif
              argspec = {@pas[1], "none", "none"}[1..3];
              argspec[2] = $code_utils:full_prep(argspec[2]) || argspec[2];
              else
              player:tell(pas);
              return;
              endif
              endif
              if (!$command_utils:object_match_failed(object = player:my_match_object(spec[1], this:get_room(player)), spec[1]))
              vnum = $code_utils:find_verb_named(object, vname = spec[2]);
              if (argspec)
              while (vnum &amp;&amp; (verb_args(object, vnum) != argspec))
              vnum = $code_utils:find_verb_named(object, vname, vnum + 1);
              endwhile
              endif
              if (length(args) &gt; 2)
              code = args[3];
              elseif (vnum)
              code = this:fetch_verb_code(object, vnum);
              else
              code = E_VERBNF;
              endif
              if (typeof(code) == ERR)
              player:tell((code != E_VERBNF) ? code | "That object does not define that verb", argspec ? " with those args." | ".");
              return code;
              else
              return {object, argspec ? {vname, @argspec} | vname, code};
              endif
              endif
              return 0;
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>fetch_verb_code</NAME>
            <CODE>
              "WIZARDLY";
              if ((caller != $verb_editor) || (caller_perms() != $verb_editor.owner))
              return E_PERM;
              else
              set_task_perms(player);
              return `verb_code(args[1], args[2], !player:edit_option("no_parens")) ! ANY';
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>set_verb_code</NAME>
            <CODE>
              "WIZARDLY";
              if ((caller != $verb_editor) || (caller_perms() != $verb_editor.owner))
              return E_PERM;
              else
              set_task_perms(player);
              return `set_verb_code(args[1], args[2], args[3]) ! ANY';
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>local_editing_info</NAME>
            <CODE>
              if (caller == $verb_editor)
              set_task_perms(player);
              endif
              {object, vname, code} = args;
              if (typeof(vname) == LIST)
              vargs = tostr(" ", vname[2], " ", $code_utils:short_prep(vname[3]), " ", vname[4]);
              vname = vname[1];
              else
              vargs = "";
              endif
              name = tostr(object.name, ":", vname);
              "... so the next 2 lines are actually wrong, since verb_info won't";
              "... necessarily retrieve the correct verb if we have more than one";
              "... matching the given same name; anyway, if parse_invoke understood vname,";
              "... so will @program.  I suspect these were put here because in the";
              "... old scheme of things, vname was always a number.";
              "vname = strsub($string_utils:explode(verb_info(object, vname)[3])[1], \"*\", \"\")";
              "vargs = verb_args(object, vname)";
              "";
              return {name, code, tostr("@program ", object, ":", vname, vargs)};
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>verb_name</NAME>
            <CODE>
              "verb_name(object, vname)";
              "Find vname on object and return its full name (quoted).";
              "This is useful for when we're working with verb numbers.";
              if ((caller != $verb_editor) || (caller_perms() != $verb_editor.owner))
              return E_PERM;
              else
              set_task_perms(player);
              given = args[2];
              if (typeof(info = `verb_info(args[1], given) ! ANY') == ERR)
              return tostr(given, "[", info, "]");
              elseif (info[3] == given)
              return given;
              else
              return tostr(given, "/\"", info[3], "\"");
              endif
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>verb_args</NAME>
            <CODE>
              "verb_name(object, vname)";
              "Find vname on object and return its full name (quoted).";
              "This is useful for when we're working with verb numbers.";
              if ((caller != $verb_editor) || (caller_perms() != $verb_editor.owner))
              return E_PERM;
              else
              set_task_perms(player);
              return $string_utils:from_list(`verb_args(args[1], args[2]) ! ANY', " ");
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>comment</NAME>
            <CODE>
              "Syntax: comment [&lt;range&gt;]";
              "";
              "Turns the specified range of lines, into comments.";
              if ((caller != player) &amp;&amp; (caller_perms() != player))
              return E_PERM;
              elseif (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              elseif (typeof(range = this:parse_range(who, {"."}, @args)) != LIST)
              player:tell(tostr(range));
              elseif (range[3])
              player:tell_lines($code_utils:verb_documentation());
              else
              text = this.texts[who];
              {from, to, crap} = range;
              cut = $maxint;
              for line in [from..to]
              cut = min(cut, `match(text[line], "[^ ]")[1] ! E_RANGE =&gt; 1');
              endfor
              for line in [from..to]
              text[line] = toliteral(text[line][cut..$]) + ";";
              endfor
              this.texts[who] = text;
              player:tell((to == from) ? "Line" | "Lines", " changed.");
              this.changes[who] = 1;
              this.times[who] = time();
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>uncomment</NAME>
            <CODE>
              "Syntax: uncomment [&lt;range&gt;]";
              "";
              "Turns the specified range of lines from comments to, uh, not comments.";
              if ((caller != player) &amp;&amp; (caller_perms() != player))
              return E_PERM;
              elseif (!(who = this:loaded(player)))
              player:tell(this:nothing_loaded_msg());
              elseif (typeof(range = this:parse_range(who, {"."}, @args)) != LIST)
              player:tell(tostr(range));
              elseif (range[3])
              player:tell_lines($code_utils:verb_documentation());
              else
              text = this.texts[who];
              {from, to, crap} = range;
              bogus = {};
              for line in [from..to]
              if (match(text[line], "^ *\"%([^\\\"]%|\\.%)*\";$"))
              "check from $code_utils:verb_documentation";
              if (!bogus)
              text[line] = $no_one:eval(text[line])[2];
              endif
              else
              bogus = setadd(bogus, line);
              endif
              endfor
              if (bogus)
              player:tell((length(bogus) == 1) ? "Line" | "Lines", " ", $string_utils:english_list(bogus), " ", (length(bogus) == 1) ? "is" | "are", " not comments.");
              player:tell("No changes.");
              return;
              endif
              this.texts[who] = text;
              player:tell((to == from) ? "Line" | "Lines", " changed.");
              this.changes[who] = 1;
              this.times[who] = time();
              endif
            </CODE>
          </VERB>
        </OBJECT>
      </OBJECT>
      <OBJECT ID="obj62" FLAGS="r" OWNER="obj36" LOCATION="obj-1">
        <NAME>The First Room</NAME>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>who_location_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>free_home</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>victim_ejection_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>ejection_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>oejection_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>residents</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>free_entry</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c">
          <NAME>entrances</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>blessed_object</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>blessed_task</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c">
          <NAME>exits</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>dark</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>ctype</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c">
          <NAME>key</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>aliases</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>description</NAME>
          <VALUE>"This is all there is right now."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>object_size</NAME>
          <VALUE>{4339, 919123699}</VALUE>
        </PROPERTY>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>disfunc</NAME>
          <CODE>
            "Copied from The Coat Closet (#11):disfunc by Haakon (#2) Mon May  8 10:41:04 1995 PDT";
            if ((((cp = caller_perms()) == (who = args[1])) || $perm_utils:controls(cp, who)) || (caller == this))
            "need the first check since guests don't control themselves";
            if (who.home == this)
            move(who, $limbo);
            this:announce("You hear a quiet popping sound; ", who.name, " has disconnected.");
            else
            pass(who);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>enterfunc</NAME>
          <CODE>
            "Copied from The Coat Closet (#11):enterfunc by Haakon (#2) Mon May  8 10:41:38 1995 PDT";
            who = args[1];
            if ($limbo:acceptable(who))
            move(who, $limbo);
            else
            pass(who);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>match</NAME>
          <CODE>
            "Copied from The Coat Closet (#11):match by Lambda (#50) Mon May  8 10:42:01 1995 PDT";
            m = pass(@args);
            if (m == $failed_match)
            "... it might be a player off in the body bag...";
            m = $string_utils:match_player(args[1]);
            if (valid(m) &amp;&amp; (!(m.location in {this, $limbo})))
            return $failed_match;
            endif
            endif
            return m;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>init_for_core</NAME>
          <CODE>
            "Copied from The Coat Closet (#11):init_for_core by Nosredna (#2487) Mon May  8 10:42:52 1995 PDT";
            if (!caller_perms().wizard)
            return E_PERM;
            endif
            for v in ({"announce*", "emote", "button", "knob"})
            if (`verb_info($player_start, v) ! E_VERBNF =&gt; 0')
            delete_verb($player_start, v);
            endif
            endfor
            for p in ({"out", "quiet", "button"})
            if (p in properties($player_start))
            delete_property($player_start, p);
            endif
            endfor
            for p in ($object_utils:all_properties($room))
            clear_property($player_start, p);
            endfor
            $player_start.name = "The First Room";
            $player_start.aliases = {};
            $player_start.description = "This is all there is right now.";
            $player_start.exits = $player_start.entrances = {};
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>keep_clean</NAME>
          <CODE>
            "Copied from The Coat Closet (#11):keep_clean by Haakon (#2) Mon May  8 10:47:08 1995 PDT";
            if ($perm_utils:controls(caller_perms(), this))
            junk = {};
            while (1)
            for x in (junk)
            $command_utils:suspend_if_needed(0);
            if (x in this.contents)
            "This is old junk that's still around five minutes later.  Clean it up.";
            if (!valid(x.owner))
            move(x, $nothing);
            #2:tell("&gt;**&gt; Cleaned up orphan object `", x.name, "' (", x, "), owned by ", x.owner, ", to #-1.");
            elseif (!$object_utils:contains(x, x.owner))
            move(x, x.owner);
            x.owner:tell("You shouldn't leave junk in ", this.name, "; ", x.name, " (", x, ") has been moved to your inventory.");
            #2:tell("&gt;**&gt; Cleaned up `", x.name, "' (", x, "), owned by `", x.owner.name, "' (", x.owner, "), to ", x.owner, ".");
            endif
            endif
            endfor
            junk = {};
            for x in (this.contents)
            if ((seconds_left() &lt; 2) || (ticks_left() &lt; 1000))
            suspend(0);
            endif
            if (!is_player(x))
            junk = {@junk, x};
            endif
            endfor
            suspend(5 * 60);
            endwhile
            endif
          </CODE>
        </VERB>
      </OBJECT>
    </OBJECT>
    <OBJECT ID="obj5" FLAGS="f r" OWNER="obj2" LOCATION="obj-1">
      <NAME>generic thing</NAME>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>drop_failed_msg</NAME>
        <VALUE>"You can't seem to drop %t here."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>drop_succeeded_msg</NAME>
        <VALUE>"You drop %t."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>odrop_failed_msg</NAME>
        <VALUE>"tries to drop %t but fails!"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>odrop_succeeded_msg</NAME>
        <VALUE>"drops %t."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>otake_succeeded_msg</NAME>
        <VALUE>"picks up %t."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>otake_failed_msg</NAME>
        <VALUE>""</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>take_succeeded_msg</NAME>
        <VALUE>"You take %t."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>take_failed_msg</NAME>
        <VALUE>"You can't pick that up."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c">
        <NAME>key</NAME>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>aliases</NAME>
        <VALUE>{"generic thing"}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>description</NAME>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>object_size</NAME>
        <VALUE>{4763, 919123665}</VALUE>
      </PROPERTY>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="none">
        <NAME>g*et t*ake</NAME>
        <CODE>
          set_task_perms(callers() ? caller_perms() | player);
          if (this.location == player)
          player:tell("You already have that!");
          elseif (this.location != player.location)
          player:tell("I don't see that here.");
          else
          this:moveto(player);
          if (this.location == player)
          player:tell(this:take_succeeded_msg() || "Taken.");
          if (msg = this:otake_succeeded_msg())
          player.location:announce(player.name, " ", msg);
          endif
          else
          player:tell(this:take_failed_msg() || "You can't pick that up.");
          if (msg = this:otake_failed_msg())
          player.location:announce(player.name, " ", msg);
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="none">
        <NAME>d*rop th*row</NAME>
        <CODE>
          set_task_perms(callers() ? caller_perms() | player);
          if (this.location != player)
          player:tell("You don't have that.");
          elseif (!player.location:acceptable(this))
          player:tell("You can't drop that here.");
          else
          this:moveto(player.location);
          if (this.location == player.location)
          player:tell_lines(this:drop_succeeded_msg() || "Dropped.");
          if (msg = this:odrop_succeeded_msg())
          player.location:announce(player.name, " ", msg);
          endif
          else
          player:tell_lines(this:drop_failed_msg() || "You can't seem to drop that here.");
          if (msg = this:odrop_failed_msg())
          player.location:announce(player.name, " ", msg);
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>moveto</NAME>
        <CODE>
          where = args[1];
          "if (!valid(where) || this:is_unlocked_for(where))";
          if (this:is_unlocked_for(where))
          pass(where);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>take_failed_msg take_succeeded_msg otake_failed_msg otake_succeeded_msg drop_failed_msg drop_succeeded_msg odrop_failed_msg odrop_succeeded_msg</NAME>
        <CODE>
          set_task_perms(caller_perms());
          return $string_utils:pronoun_sub(this.(verb));
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="at/to" IOBJ="any">
        <NAME>gi*ve ha*nd</NAME>
        <CODE>
          set_task_perms(callers() ? caller_perms() | player);
          if (this.location != player)
          player:tell("You don't have that!");
          elseif (!valid(player.location))
          player:tell("I see no \"", iobjstr, "\" here.");
          elseif ($command_utils:object_match_failed(who = player.location:match_object(iobjstr), iobjstr))
          elseif (who.location != player.location)
          player:tell("I see no \"", iobjstr, "\" here.");
          elseif (who == player)
          player:tell("Give it to yourself?");
          else
          this:moveto(who);
          if (this.location == who)
          player:tell("You hand ", this:title(), " to ", who:title(), ".");
          who:tell(player:titlec(), " ", $gender_utils:get_conj("hands/hand", player), " you ", this:title(), ".");
          else
          player:tell(who:titlec(), " ", $gender_utils:get_conj("does/do", who), " not want that item.");
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>examine_key</NAME>
        <CODE>
          "examine_key(examiner)";
          "return a list of strings to be told to the player, indicating what the key on this type of object means, and what this object's key is set to.";
          "the default will only tell the key to a wizard or this object's owner.";
          who = args[1];
          if (((caller == this) &amp;&amp; $perm_utils:controls(who, this)) &amp;&amp; (this.key != 0))
          return {tostr(this:title(), " can only be moved to locations matching this key:"), tostr("  ", $lock_utils:unparse_key(this.key))};
          endif
        </CODE>
      </VERB>
      <OBJECT ID="obj8" FLAGS="f r" OWNER="obj2" LOCATION="obj-1">
        <NAME>generic container</NAME>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>oclose_msg</NAME>
          <VALUE>"closes %d."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>close_msg</NAME>
          <VALUE>"You close %d."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>oopen_msg</NAME>
          <VALUE>"opens %d."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>open_msg</NAME>
          <VALUE>"You open %d."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>oput_fail_msg</NAME>
          <VALUE>""</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>put_fail_msg</NAME>
          <VALUE>"You can't put %d in that."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>opaque</NAME>
          <VALUE>1</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>dark</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>oremove_fail_msg</NAME>
          <VALUE>""</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>oremove_msg</NAME>
          <VALUE>"removes %d from %i."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>remove_fail_msg</NAME>
          <VALUE>"You can't remove that."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>remove_msg</NAME>
          <VALUE>"You remove %d from %i."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>oput_msg</NAME>
          <VALUE>"puts %d in %i."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>put_msg</NAME>
          <VALUE>"You put %d in %i."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>oopen_fail_msg</NAME>
          <VALUE>""</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>open_fail_msg</NAME>
          <VALUE>"You can't open that."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>empty_msg</NAME>
          <VALUE>"It is empty."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>opened</NAME>
          <VALUE>1</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>open_key</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>drop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>drop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>odrop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>odrop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>otake_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>otake_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>take_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>take_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>key</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>aliases</NAME>
          <VALUE>{"generic container"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>description</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>object_size</NAME>
          <VALUE>{9323, 919123665}</VALUE>
        </PROPERTY>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="in/inside/into" IOBJ="this">
          <NAME>p*ut in*sert d*rop</NAME>
          <CODE>
            if ((this.location != player) &amp;&amp; (this.location != player.location))
            player:tell("You can't get at ", this.name, ".");
            elseif (dobj == $nothing)
            player:tell("What do you want to put ", prepstr, " ", this.name, "?");
            elseif ($command_utils:object_match_failed(dobj, dobjstr))
            elseif ((dobj.location != player) &amp;&amp; (dobj.location != player.location))
            player:tell("You don't have ", dobj.name, ".");
            elseif (!this.opened)
            player:tell(this.name, " is closed.");
            else
            set_task_perms(callers() ? caller_perms() | player);
            dobj:moveto(this);
            if (dobj.location == this)
            player:tell(this:put_msg());
            if (msg = this:oput_msg())
            player.location:announce(player.name, " ", msg);
            endif
            else
            player:tell(this:put_fail_msg());
            if (msg = this:oput_fail_msg())
            player.location:announce(player.name, " ", msg);
            endif
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="out of/from inside/from" IOBJ="this">
          <NAME>re*move ta*ke g*et</NAME>
          <CODE>
            if (!(this.location in {player, player.location}))
            player:tell("Sorry, you're too far away.");
            elseif (!this.opened)
            player:tell(this.name, " is not open.");
            elseif (this.dark)
            player:tell("You can't see into ", this.name, " to remove anything.");
            elseif ((dobj = this:match_object(dobjstr)) == $nothing)
            player:tell("What do you want to take from ", this.name, "?");
            elseif ($command_utils:object_match_failed(dobj, dobjstr))
            elseif (!(dobj in this:contents()))
            player:tell(dobj.name, " isn't in ", this.name, ".");
            else
            set_task_perms(callers() ? caller_perms() | player);
            dobj:moveto(player);
            if (dobj.location == player)
            player:tell(this:remove_msg());
            if (msg = this:oremove_msg())
            player.location:announce(player.name, " ", msg);
            endif
            else
            dobj:moveto(this.location);
            if (dobj.location == this.location)
            player:tell(this:remove_msg());
            if (msg = this:oremove_msg())
            player.location:announce(player.name, " ", msg);
            endif
            player:tell("You can't pick up ", dobj.name, ", so it tumbles onto the floor.");
            else
            player:tell(this:remove_fail_msg());
            if (msg = this:oremove_fail_msg())
            player.location:announce(player.name, " ", msg);
            endif
            endif
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>look_self</NAME>
          <CODE>
            pass();
            if (!this.dark)
            this:tell_contents();
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>acceptable</NAME>
          <CODE>
            return !is_player(args[1]);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="none">
          <NAME>open</NAME>
          <CODE>
            perms = (callers() &amp;&amp; (caller != this)) ? caller_perms() | player;
            if (this.opened)
            player:tell("It's already open.");
            "elseif (this:is_openable_by(player))";
            elseif (this:is_openable_by(perms))
            this:set_opened(1);
            player:tell(this:open_msg());
            if (msg = this:oopen_msg())
            player.location:announce(player.name, " ", msg);
            endif
            else
            player:tell(this:open_fail_msg());
            if (msg = this:oopen_fail_msg())
            player.location:announce(player.name, " ", msg);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="this" PREP="with/using" IOBJ="any">
          <NAME>@lock_for_open</NAME>
          <CODE>
            set_task_perms(player);
            key = $lock_utils:parse_keyexp(iobjstr, player);
            if (typeof(key) == STR)
            player:tell("That key expression is malformed:");
            player:tell("  ", key);
            else
            try
            this.open_key = key;
            player:tell("Locked opening of ", this.name, " with this key:");
            player:tell("  ", $lock_utils:unparse_key(key));
            except error (ANY)
            player:tell(error[2], ".");
            endtry
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>is_openable_by</NAME>
          <CODE>
            return (this.open_key == 0) || $lock_utils:eval_key(this.open_key, args[1]);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="none">
          <NAME>close</NAME>
          <CODE>
            if (!this.opened)
            player:tell("It's already closed.");
            else
            this:set_opened(0);
            player:tell(this:close_msg());
            if (msg = this:oclose_msg())
            player.location:announce(player.name, " ", msg);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="this" PREP="none" IOBJ="none">
          <NAME>@unlock_for_open</NAME>
          <CODE>
            set_task_perms(player);
            try
            dobj.open_key = 0;
            player:tell("Unlocked ", dobj.name, " for opening.");
            except error (ANY)
            player:tell(error[2], ".");
            endtry
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>tell_contents</NAME>
          <CODE>
            if (this.contents)
            player:tell("Contents:");
            for thing in (this:contents())
            player:tell("  ", thing:title());
            endfor
            elseif (msg = this:empty_msg())
            player:tell(msg);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_opened</NAME>
          <CODE>
            if (!$perm_utils:controls(caller.owner, this))
            return E_PERM;
            else
            this.opened = opened = !(!args[1]);
            this.dark = this.opaque &gt; opened;
            return opened;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="this" PREP="is" IOBJ="any">
          <NAME>@opacity</NAME>
          <CODE>
            if (!$perm_utils:controls(player, this))
            player:tell("Can't set opacity of something you don't own.");
            elseif ((iobjstr != "0") &amp;&amp; (!toint(iobjstr)))
            player:tell("Opacity must be an integer (0, 1, 2).");
            else
            player:tell("Opacity changed:  Now " + {"transparent.", "opaque.", "a black hole."}[1 + this:set_opaque(toint(iobjstr))]);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_opaque</NAME>
          <CODE>
            if (!$perm_utils:controls(caller.owner, this))
            return E_PERM;
            elseif (typeof(number = args[1]) != INT)
            return E_INVARG;
            else
            number = (number &lt; 0) ? 0 | ((number &gt; 2) ? 2 | number);
            this.dark = number &gt; this.opened;
            return this.opaque = number;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>oclose_msg close_msg oopen_msg open_msg oput_fail_msg put_fail_msg oremove_fail_msg oremove_msg remove_fail_msg remove_msg oput_msg put_msg oopen_fail_msg open_fail_msg empty_msg</NAME>
          <CODE>
            return (msg = `this.(verb) ! ANY') ? $string_utils:pronoun_sub(msg) | "";
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>dark</NAME>
          <CODE>
            return this.(verb);
          </CODE>
        </VERB>
        <OBJECT ID="obj83" FLAGS="r" OWNER="obj36" LOCATION="obj-1">
          <NAME>Feature Warehouse</NAME>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oclose_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>close_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oopen_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>open_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oput_fail_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>put_fail_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="r">
            <NAME>opaque</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="r">
            <NAME>dark</NAME>
            <VALUE>0</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oremove_fail_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oremove_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>remove_fail_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>remove_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oput_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>put_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>oopen_fail_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>open_fail_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>empty_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="r">
            <NAME>opened</NAME>
            <VALUE>1</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>open_key</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>drop_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>drop_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>odrop_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>odrop_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>otake_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>otake_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>take_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>take_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>key</NAME>
            <VALUE>0</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>aliases</NAME>
            <VALUE>{"Feature Warehouse", "warehouse"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>description</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>object_size</NAME>
            <VALUE>{1590, 919123703}</VALUE>
          </PROPERTY>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="in/inside/into" IOBJ="this">
            <NAME>list</NAME>
            <CODE>
              "Copied from Features Feature Object (#24300):list by Joe (#2612) Mon Oct 10 21:07:35 1994 PDT";
              if (this.contents)
              player:tell(".features objects:");
              player:tell("----------------------");
              first = 1;
              for thing in (this.contents)
              $command_utils:kill_if_laggy(10, "Sorry, the MOO is very laggy, and there are too many feature objects in here to list!");
              $command_utils:suspend_if_needed(0);
              if (!first)
              player:tell();
              endif
              player:tell($string_utils:nn(thing), ":");
              `thing:look_self() ! ANY =&gt; player:tell("&lt;&lt;Error printing description&gt;&gt;")';
              first = 0;
              endfor
              player:tell("----------------------");
              else
              player:tell("No objects in ", this.name, ".");
              endif
            </CODE>
          </VERB>
        </OBJECT>
      </OBJECT>
      <OBJECT ID="obj9" FLAGS="f r" OWNER="obj2" LOCATION="obj-1">
        <NAME>generic note</NAME>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>writers</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>encryption_key</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>text</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>drop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>drop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>odrop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>odrop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>otake_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>otake_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>take_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>take_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>key</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>aliases</NAME>
          <VALUE>{"generic note"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>description</NAME>
          <VALUE>"There appears to be some writing on the note ..."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>object_size</NAME>
          <VALUE>{6228, 919123665}</VALUE>
        </PROPERTY>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="none">
          <NAME>r*ead</NAME>
          <CODE>
            if (!this:is_readable_by(valid(caller_perms()) ? caller_perms() | player))
            player:tell("Sorry, but it seems to be written in some code that you can't read.");
            else
            this:look_self();
            player:tell();
            player:tell_lines_suspended(this:text());
            player:tell();
            player:tell("(You finish reading.)");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="none">
          <NAME>er*ase</NAME>
          <CODE>
            if (this:is_writable_by(valid(caller_perms()) ? caller_perms() | player))
            this:set_text({});
            player:tell("Note erased.");
            else
            player:tell("You can't erase this note.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="on top of/on/onto/upon" IOBJ="this">
          <NAME>wr*ite</NAME>
          <CODE>
            if (this:is_writable_by(valid(caller_perms()) ? caller_perms() | player))
            this:set_text({@this.text, dobjstr});
            player:tell("Line added to note.");
            else
            player:tell("You can't write on this note.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="out of/from inside/from" IOBJ="this">
          <NAME>del*ete rem*ove</NAME>
          <CODE>
            if (!this:is_writable_by(player))
            player:tell("You can't modify this note.");
            elseif (!dobjstr)
            player:tell("You must tell me which line to delete.");
            else
            line = toint(dobjstr);
            if (line &lt; 0)
            line = (line + length(this.text)) + 1;
            endif
            if ((line &lt;= 0) || (line &gt; length(this.text)))
            player:tell("Line out of range.");
            else
            this:set_text(listdelete(this.text, line));
            player:tell("Line deleted.");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="this" PREP="with/using" IOBJ="any">
          <NAME>encrypt</NAME>
          <CODE>
            set_task_perms(player);
            key = $lock_utils:parse_keyexp(iobjstr, player);
            if (typeof(key) == STR)
            player:tell("That key expression is malformed:");
            player:tell("  ", key);
            else
            try
            this.encryption_key = key;
            player:tell("Encrypted ", this.name, " with this key:");
            player:tell("  ", $lock_utils:unparse_key(key));
            except error (ANY)
            player:tell(error[2], ".");
            endtry
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="this" PREP="none" IOBJ="none">
          <NAME>decrypt</NAME>
          <CODE>
            set_task_perms(player);
            try
            dobj.encryption_key = 0;
            player:tell("Decrypted ", dobj.name, ".");
            except error (ANY)
            player:tell(error[2], ".");
            endtry
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>text</NAME>
          <CODE>
            cp = caller_perms();
            if ($perm_utils:controls(cp, this) || this:is_readable_by(cp))
            return this.text;
            else
            return E_PERM;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>is_readable_by</NAME>
          <CODE>
            key = this.encryption_key;
            return (key == 0) || $lock_utils:eval_key(key, args[1]);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_text</NAME>
          <CODE>
            cp = caller_perms();
            newtext = args[1];
            if ($perm_utils:controls(cp, this) || this:is_writable_by(cp))
            if (typeof(newtext) == LIST)
            this.text = newtext;
            else
            return E_TYPE;
            endif
            else
            return E_PERM;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>is_writable_by</NAME>
          <CODE>
            who = args[1];
            wr = this.writers;
            if ($perm_utils:controls(who, this))
            return 1;
            elseif (typeof(wr) == LIST)
            return who in wr;
            else
            return wr;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="this" PREP="none" IOBJ="none">
          <NAME>mailme @mailme</NAME>
          <CODE>
            "Usage:  mailme &lt;note&gt;";
            "  uses $network to sends the text of this note to your REAL internet email address.";
            if (!this:is_readable_by(player))
            return player:tell("Sorry, but it seems to be written in some code that you can't read.");
            elseif (!$wiz_utils:get_email_address(player))
            return player:tell("Sorry, you don't have a registered email address.");
            elseif (!$network.active)
            return player:tell("Sorry, internet mail is disabled.");
            elseif (!(text = this:text()))
            return player:tell($string_utils:pronoun_sub("%T is empty--there wouldn't be any point to mailing it."));
            endif
            player:tell("Mailing ", this:title(), " to ", $wiz_utils:get_email_address(player), ".");
            player:tell("... ", length(text), " lines ...");
            suspend(0);
            $network:sendmail($wiz_utils:get_email_address(player), this:titlec(), "", @text);
          </CODE>
        </VERB>
        <OBJECT ID="obj54" FLAGS="f r" OWNER="obj2" LOCATION="obj-1">
          <NAME>generic letter</NAME>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>oburn_succeeded_msg</NAME>
            <VALUE>"stares at %t; %[tps] bursts into flame and disappears, leaving no ash."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>oburn_failed_msg</NAME>
            <VALUE>0</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>burn_failed_msg</NAME>
            <VALUE>"%T might be damp.  In any case, %[tps] won't burn."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>burn_succeeded_msg</NAME>
            <VALUE>"%T burns with a smokeless flame and leaves no ash."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>writers</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>encryption_key</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c">
            <NAME>text</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>drop_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>drop_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>odrop_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="c r">
            <NAME>odrop_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>otake_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>otake_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>take_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>take_failed_msg</NAME>
            <VALUE>"This is a private letter."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>key</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>aliases</NAME>
            <VALUE>{"generic letter"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>description</NAME>
            <VALUE>"Some writing on the letter explains that you should 'read letter', and when you've finished, 'burn letter'."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>object_size</NAME>
            <VALUE>{2361, 919123696}</VALUE>
          </PROPERTY>
          <VERB OWNER="obj2" PERMS="d r" DOBJ="this" PREP="none" IOBJ="none">
            <NAME>burn</NAME>
            <CODE>
              who = valid(caller_perms()) ? caller_perms() | player;
              if ($perm_utils:controls(who, this) || this:is_readable_by(who))
              result = this:do_burn();
              else
              result = 0;
              endif
              player:tell(result ? this:burn_succeeded_msg() | this:burn_failed_msg());
              if (msg = result ? this:oburn_succeeded_msg() | this:oburn_failed_msg())
              player.location:announce(player.name, " ", msg);
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>burn_succeeded_msg oburn_succeeded_msg burn_failed_msg oburn_failed_msg</NAME>
            <CODE>
              return (msg = this.(verb)) ? $string_utils:pronoun_sub(msg) | "";
            </CODE>
          </VERB>
          <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
            <NAME>do_burn</NAME>
            <CODE>
              if ((this != $letter) &amp;&amp; ((caller == this) || $perm_utils:controls(caller_perms(), this)))
              fork (0)
              $recycler:_recycle(this);
              endfork
              return 1;
              else
              return E_PERM;
              endif
            </CODE>
          </VERB>
        </OBJECT>
      </OBJECT>
      <OBJECT ID="obj63" FLAGS="r" OWNER="obj36" LOCATION="obj-1">
        <NAME>Recycling Center</NAME>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>orphans</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>announce_removal_msg</NAME>
          <VALUE>""</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" >
          <NAME>nhist</NAME>
          <VALUE>50</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" >
          <NAME>history</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>lost_souls</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>drop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>drop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>odrop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>odrop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>otake_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>otake_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>take_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>take_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c">
          <NAME>key</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>aliases</NAME>
          <VALUE>{"Recycling Center", "Center"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>description</NAME>
          <VALUE>"Object reuse. Call $recycler:_create() to create an object (semantics the same as create()), $recycler:_recycle() to recycle an object. Will create a new object if nothing available in its contents. Note underscores, to avoid builtin :recycle() verb called when objects are recycled. Uses $building_utils:recreate() to prepare objects."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>object_size</NAME>
          <VALUE>{11726, 919123700}</VALUE>
        </PROPERTY>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>_recreate</NAME>
          <CODE>
            "Return a toad (child of #1, owned by $hacker) from this.contents.  Move it to #-1.  Recreate as a child of args[1], or of #1 if no args are given.  Chown to caller_perms() or args[2] if present.";
            {?what = #1, ?who = caller_perms()} = args;
            if (!(caller_perms().wizard || (who == caller_perms())))
            return E_PERM;
            elseif (!(valid(what) &amp;&amp; is_player(who)))
            return E_INVARG;
            elseif ((((who != what.owner) &amp;&amp; (!what.f)) &amp;&amp; (!who.wizard)) &amp;&amp; (!caller_perms().wizard))
            return E_PERM;
            endif
            for potential in (this.contents)
            if (((potential.owner == $hacker) &amp;&amp; (parent(potential) == $garbage)) &amp;&amp; (!children(potential)))
            return this:setup_toad(potential, who, what);
            endif
            endfor
            return E_NONE;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>_recycle</NAME>
          <CODE>
            "Take the object in args[1], and turn it into a child of #1 owned by $hacker.";
            "If the object is a player, decline.";
            item = args[1];
            if (!$perm_utils:controls(caller_perms(), item))
            raise(E_PERM);
            elseif (is_player(item))
            raise(E_INVARG);
            endif
            this:addhist(caller_perms(), item);
            "...recreate can fail (:recycle can crash)...";
            this:add_orphan(item);
            this:kill_all_tasks(item);
            $quota_utils:preliminary_reimburse_quota(item.owner, item);
            $building_utils:recreate(item, $garbage);
            this:remove_orphan(item);
            "...";
            $wiz_utils:set_owner(item, $hacker);
            item.name = tostr("Recyclable ", item);
            `move(item, this) ! ANY =&gt; 0';
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>_create</NAME>
          <CODE>
            e = `set_task_perms(caller_perms()) ! ANY';
            if (typeof(e) == ERR)
            return e;
            else
            val = this:_recreate(@args);
            return (val == E_NONE) ? $quota_utils:bi_create(@args) | val;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>addhist</NAME>
          <CODE>
            if (caller == this)
            h = this.history;
            if ((len = length(h)) &gt; this.nhist)
            h = h[len - this.nhist..len];
            endif
            this.history = {@h, args};
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="none">
          <NAME>show*-history</NAME>
          <CODE>
            if ($perm_utils:controls(valid(caller_perms()) ? caller_perms() | player, this))
            for x in (this.history)
            pname = valid(x[1]) ? x[1].name | "A recycled player";
            oname = valid(x[2]) ? x[2].name | "recycled";
            player:notify(tostr(pname, " (", x[1], ") recycled ", x[2], " (now ", oname, ")"));
            endfor
            else
            player:tell("Sorry.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="out of/from inside/from" IOBJ="this">
          <NAME>request</NAME>
          <CODE>
            "added check that obj is already $garbage - Bits 12/16/5";
            if (!(caller_perms() in {player, #-1}))
            raise(E_PERM);
            endif
            dobj = valid(dobj) ? dobj | $string_utils:match_object(dobjstr, player.location);
            if (!valid(dobj))
            dobj = (n = toint(dobjstr)) ? toobj(n) | #-1;
            endif
            if (!valid(dobj))
            player:tell("Couldn't parse ", dobjstr, " as a valid object number.");
            elseif (!(dobj in this.contents))
            player:tell("Couldn't find ", dobj, " in ", this.name, ".");
            elseif (!$object_utils:isa(dobj, $garbage))
            player:tell("Sorry, that isn't recyclable.");
            elseif ($object_utils:has_callable_verb(this, "request_refused") &amp;&amp; (msg = this:request_refused(player, dobj)))
            player:tell("Sorry, can't do that:  ", msg);
            else
            if (typeof(emsg = this:setup_toad(dobj, player, $root_class)) != ERR)
            dobj:moveto(player);
            dobj.aliases = {dobj.name = "Object " + tostr(dobj)};
            player:tell("You now have ", dobj, " ready for @recreation.");
            if (this.announce_removal_msg)
            player.location:announce($string_utils:pronoun_sub(this.announce_removal_msg));
            endif
            else
            player:tell(emsg);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>setup_toad</NAME>
          <CODE>
            "this:setup_toad(objnum,new_owner,parent)";
            "Called by :_create and :request.";
            if (caller != this)
            return E_PERM;
            endif
            {potential, who, what} = args;
            if (!$quota_utils:creation_permitted(who))
            return E_QUOTA;
            else
            $wiz_utils:set_owner(potential, who);
            move(potential, #-1);
            set_task_perms({@callers(), {#-1, "", player}}[2][3]);
            "... if :initialize crashes...";
            this:add_orphan(potential);
            $building_utils:recreate(potential, what);
            this:remove_orphan(potential);
            "... if we don't get this far, the object stays on the orphan list...";
            "... orphan list should be checked periodically...";
            return potential;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>add_orphan</NAME>
          <CODE>
            if (caller == this)
            this.orphans = setadd(this.orphans, args[1]);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>remove_orphan</NAME>
          <CODE>
            if (caller == this)
            this.orphans = setremove(this.orphans, args[1]);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>valid</NAME>
          <CODE>
            "Usage:  valid(object)";
            "True if object is valid and not $garbage.";
            return valid(args[1]) &amp;&amp; (parent(args[1]) != $garbage);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>init_for_core</NAME>
          <CODE>
            if (caller_perms().wizard)
            this.orphans = {};
            this.history = {};
            this.lost_souls = {};
            pass();
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>resurrect</NAME>
          <CODE>
            who = caller_perms();
            if (!valid(parent = {@args, $garbage}[1]))
            return E_INVARG;
            elseif (!who.wizard)
            return E_PERM;
            elseif (typeof(o = renumber($quota_utils:bi_create(parent, $hacker))) == ERR)
            "..death...";
            elseif (parent == $garbage)
            $recycler:_recycle(o);
            else
            o.aliases = {o.name = tostr("Resurrectee ", o)};
            $wiz_utils:set_owner(o, who);
            move(o, who);
            endif
            reset_max_object();
            return o;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>reclaim_lost_souls</NAME>
          <CODE>
            if (!caller_perms().wizard)
            raise(E_PERM);
            endif
            fork (1800)
            this:(verb)();
            endfork
            for x in (this.lost_souls)
            this.lost_souls = setremove(this.lost_souls, x);
            if ((valid(x) &amp;&amp; (typeof(x.owner.owned_objects) == LIST)) &amp;&amp; (!(x in x.owner.owned_objects)))
            x.owner.owned_objects = setadd(x.owner.owned_objects, x);
            $quota_utils:summarize_one_user(x.owner);
            endif
            $command_utils:suspend_if_needed(0);
            endfor
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>look_self</NAME>
          <CODE>
            if (prepstr in {"in", "inside", "into"})
            recycler = this;
            linelen = ((linelen = abs(player.linelen)) &lt; 20) ? 78 | linelen;
            intercolumn_gap = 2;
            c_width = length(tostr(max_object())) + intercolumn_gap;
            n_columns = (linelen + (c_width - 1)) / c_width;
            things = $list_utils:sort_suspended(0, this.contents);
            header = tostr(this.name, " (", this, ") contains:");
            player:tell_lines({header, @$string_utils:columnize_suspended(0, things, n_columns)});
            else
            return pass(@args);
            endif
            "This code contributed by Mickey.";
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_quota_scam</NAME>
          <CODE>
            who = args[1];
            if ($quota_utils.byte_based &amp;&amp; (is_clear_property(who, "size_quota") || is_clear_property(who, "owned_objects")))
            raise(E_QUOTA);
            endif
            cheater = 0;
            other_cheaters = {};
            for x in (this.lost_souls)
            if (((valid(x) &amp;&amp; ((owner = x.owner) != $hacker)) &amp;&amp; (typeof(owner.owned_objects) == LIST)) &amp;&amp; (!(x in owner.owned_objects)))
            if (owner == who)
            who.owned_objects = setadd(who.owned_objects, x);
            cheater = 1;
            else
            "it's someone else's quota scam we're detecting...";
            other_cheaters = setadd(other_cheaters, owner);
            owner.owned_objects = setadd(owner.owned_objects, x);
            this.lost_souls = setremove(this.lost_souls, x);
            endif
            endif
            this.lost_souls = setremove(this.lost_souls, x);
            endfor
            if ($quota_utils.byte_based)
            if (cheater)
            $quota_utils:summarize_one_user(who);
            endif
            if (other_cheaters)
            fork (0)
            for x in (other_cheaters)
            $quota_utils:summarize_one_user(x);
            endfor
            endfork
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>gc</NAME>
          <CODE>
            for x in (this.orphans)
            if ((!valid(x)) || ((x.owner != $hacker) &amp;&amp; (x in x.owner.owned_objects)))
            this.orphans = setremove(this.orphans, x);
            endif
            endfor
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>moveto</NAME>
          <CODE>
            pass(#-1);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>kill_all_tasks</NAME>
          <CODE>
            "kill_all_tasks ( object being recycled )";
            " -- kill all tasks involving this now-recycled object";
            ((caller == this) || (caller == #0)) || raise(E_PERM);
            {object} = args;
            (typeof(object) == OBJ) || raise(E_INVARG);
            fork (0)
            for t in (queued_tasks())
            for c in (`task_stack(t[1]) ! E_INVARG =&gt; {}')
            if (object in c)
            kill_task(t[1]);
            continue t;
            endif
            endfor
            endfor
            endfork
          </CODE>
        </VERB>
      </OBJECT>
      <OBJECT ID="obj74" FLAGS="f r" OWNER="obj36" LOCATION="obj-1">
        <NAME>Generic Feature Object</NAME>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>warehouse</NAME>
          <VALUE>#83</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>help_msg</NAME>
          <VALUE>"The Generic Feature Object--not to be used as a feature object."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>feature_verbs</NAME>
          <VALUE>{"Using"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>feature_ok</NAME>
          <VALUE>1</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>drop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>drop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>odrop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>odrop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>otake_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>otake_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>take_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>take_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c">
          <NAME>key</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>aliases</NAME>
          <VALUE>{"Generic Feature Object", "Generic .Features_Huh Object", "Feature Object", ".Features_Huh Object"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="c r">
          <NAME>description</NAME>
          <VALUE>"This is the Generic Feature Object.  It is not meant to be used as a feature object itself, but is handy for making new feature objects."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>object_size</NAME>
          <VALUE>{6717, 919123701}</VALUE>
        </PROPERTY>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>help_msg</NAME>
          <CODE>
            all_help = this.help_msg;
            if (typeof(all_help) == STR)
            all_help = {all_help};
            endif
            helpless = {};
            for vrb in (this.feature_verbs)
            if (loc = $object_utils:has_verb(this, vrb))
            loc = loc[1];
            help = $code_utils:verb_documentation(loc, vrb);
            if (help)
            all_help = {@all_help, "", tostr(loc, ":", verb_info(loc, vrb)[3]), @help};
            else
            helpless = {@helpless, vrb};
            endif
            endif
            endfor
            if (helpless)
            all_help = {@all_help, "", ("No help found on " + $string_utils:english_list(helpless, "nothing", " or ")) + "."};
            endif
            return {@all_help, "----"};
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>look_self</NAME>
          <CODE>
            "Definition from #1";
            desc = this:description();
            if (desc)
            player:tell_lines(desc);
            else
            player:tell("You see nothing special.");
            endif
            player:tell("Please type \"help ", this, "\" for more information.");
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>using this</NAME>
          <CODE>
            "Proper usage for the Generic Feature Object:";
            "";
            "First of all, the Generic Feature Object is constructed with the idea";
            "that its children will be @moved to #24300, which is kind of a warehouse";
            "for feature objects.  If there's enough interest, I'll try to make the";
            "stuff that works with that in mind optional.";
            "";
            "Make a short description.  This is so I can continue to have looking at";
            "#24300 give the descriptions of each of the objects in its .contents.";
            "The :look_msg automatically includes a pointer to `help &lt;this object&gt;',";
            "so you don't have to.";
            "";
            "Put a list of the commands you want people to use in";
            "&lt;this object&gt;.feature_verbs.  (You need to use the :set_feature_verbs";
            "verb to do this.)";
            "";
            "When someone types `help &lt;this object&gt;', they will be told the comment";
            "strings from each of the verbs named in .feature_verbs.";
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>examine_commands_ok</NAME>
          <CODE>
            return this in args[1].features;
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_feature_ok</NAME>
          <CODE>
            if ($perm_utils:controls(caller_perms(), this) || (caller == this))
            return this.feature_ok = args[1];
            else
            return E_PERM;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>hidden_verbs</NAME>
          <CODE>
            "Can't see `get' unless it's in the room; can't see `drop' unless it's in the player.  Should possibly go on $thing.";
            "Should use :contents, but I'm in a hurry.";
            hidden = pass(@args);
            if (this.location != args[1])
            hidden = setadd(hidden, {$thing, verb_info($thing, "drop")[3], {"this", "none", "none"}});
            hidden = setadd(hidden, {$thing, verb_info($thing, "give")[3], {"this", "at/to", "any"}});
            endif
            if (this.location != args[1].location)
            hidden = setadd(hidden, {$thing, verb_info($thing, "get")[3], {"this", "none", "none"}});
            endif
            return hidden;
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_feature_verbs</NAME>
          <CODE>
            if ($perm_utils:controls(caller_perms(), this) || (caller == this))
            return this.feature_verbs = args[1];
            else
            return E_PERM;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>initialize</NAME>
          <CODE>
            if ((caller == this) || $perm_utils:controls(caller_perms(), this))
            pass(@args);
            this.feature_verbs = {};
            else
            return E_PERM;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>init_for_core</NAME>
          <CODE>
            if (($code_utils:verb_location() == this) &amp;&amp; caller_perms().wizard)
            this.warehouse = $feature_warehouse;
            `delete_property(this, "guest_ok") ! ANY';
            `delete_verb(this, "set_ok_for_guest_use") ! ANY';
            `set_verb_code(this, "player_connected", {"return;"}) ! ANY';
            pass();
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>feature_remove</NAME>
          <CODE>
            "This is just a blank verb definition to encourage others to use this verb name if they care when a user is no longer using that feature.";
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>player_connected</NAME>
          <CODE>
            return;
          </CODE>
        </VERB>
        <OBJECT ID="obj90" FLAGS="f r" OWNER="obj36" LOCATION="obj-1">
          <NAME>Stage-Talk Feature</NAME>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>warehouse</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>help_msg</NAME>
            <VALUE>{"This feature contains various verbs used in stage talk, which allows players to describe their actions in terms of stage directions instead of prose."}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>feature_verbs</NAME>
            <VALUE>{"`", "[", "]", "-", "&lt;"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>feature_ok</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>drop_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>drop_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>odrop_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>odrop_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>otake_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>otake_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>take_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>take_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>key</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>aliases</NAME>
            <VALUE>{"Stage-Talk Feature"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>description</NAME>
            <VALUE>{"This feature contains various verbs used in stage talk, which allows players to describe their actions in terms of stage directions instead of prose."}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>object_size</NAME>
            <VALUE>{4209, 919123705}</VALUE>
          </PROPERTY>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>stage `*</NAME>
            <CODE>
              "Say something out loud, directed at someone or something.";
              "Usage:";
              "  `target message";
              "Example:";
              "  Munchkin is talking to Kenneth, who's in the same room with him.  He types:";
              "      `kenneth What is the frequency?";
              "  The room sees:";
              "       Munchkin [to Kenneth]: What is the frequency?";
              name = verb[2..$];
              who = player.location:match_object(name);
              if ($command_utils:object_match_failed(who, name))
              return;
              endif
              player.location:announce_all(player.name, " [to ", who.name, "]: ", argstr);
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>stage [*</NAME>
            <CODE>
              "Say something out loud, in some specific way.";
              "Usage:";
              "  [how]: message";
              "Example:";
              "  Munchkin decideds to sing some lyrics.  He types:";
              "      [sings]: I am the eggman";
              "  The room sees:";
              "      Munchkin [sings]: I am the eggman";
              player.location:announce_all((((player.name + " ") + verb) + " ") + argstr);
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>stage ]*</NAME>
            <CODE>
              "Perform some physical, non-verbal, action.";
              "Usage:";
              "  ]third person action";
              "Example:";
              "  Munchkin has annoyed some would-be tough guy.  He types:";
              "      ]hides behind the reactor.";
              "  The room sees:";
              "      [Munchkin hides behind the reactor.]";
              player.location:announce_all("[", (((player.name + " ") + verb[2..$]) + (argstr ? " " + argstr | "")) + "]");
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>-*</NAME>
            <CODE>
              "This is the same as `*";
              name = verb[2..$];
              who = player.location:match_object(name);
              argstr = $code_utils:argstr(verb, args, argstr);
              if (!valid(who))
              player.location:announce_all(player.name, " [", name, "]: ", argstr);
              else
              player.location:announce_all(player.name, " [to ", who.name, "]: ", argstr);
              endif
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>stage &lt;*</NAME>
            <CODE>
              "Point to yourself.";
              "Usage:";
              "  &lt;message";
              "Example:";
              "  Muchkin decides he's being strange. He types:";
              "    &lt;being strange.";
              "  The room sees:";
              "    Munchkin &lt;- being strange.";
              player.location:announce_all((((player.name + " &lt;- ") + verb[2..$]) + " ") + argstr);
            </CODE>
          </VERB>
        </OBJECT>
        <OBJECT ID="obj91" FLAGS="f r" OWNER="obj36" LOCATION="obj-1">
          <NAME>Pasting Feature</NAME>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>warehouse</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>help_msg</NAME>
            <VALUE>"The Pasting Feature is mostly useful to people with fancy clients (such as Emacs) or who connect using a windowing system that allows them to copy text they've already seen.  It's intended to give people a way to quote verbatim text at other people in the room."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>feature_verbs</NAME>
            <VALUE>{"@paste", "|", "@paste-to"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>feature_ok</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>drop_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>drop_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>odrop_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>odrop_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>otake_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>otake_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>take_succeeded_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>take_failed_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>key</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>aliases</NAME>
            <VALUE>{"Pasting Feature"}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>description</NAME>
            <VALUE>"Verbs useful to people using a windowing system to paste text at people."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>object_size</NAME>
            <VALUE>{4198, 919123706}</VALUE>
          </PROPERTY>
          <VERB OWNER="obj36" PERMS="x r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>@paste</NAME>
            <CODE>
              "Usage: @paste &lt;prefix&gt; &lt;suffix&gt;";
              "Announce a series of entered lines to the room the player is in.";
              "Before the lines are quoted, player.paste_header is run through";
              "$string_utils:pronoun_sub(), and if the result contains the player's";
              "name, it is used as a header.  Otherwise player.name centered in a";
              "line of dashes is used.";
              "A footer comes afterwards, likewise derived from player.paste_footer.";
              "&lt;prefix&gt; and &lt;suffix&gt; are placed before and after each line.";
              "";
              "This verb is, as one might guess, designed for pasting text to MOO using";
              "GnuEmacs or a windowing system.  You should remember that after you";
              "have pasted the lines in, you must type . on a line by itself, or you'll";
              "sit around waiting for $command_utils:read_lines() to finish _forever_.";
              {?prefix = "", ?suffix = ""} = args;
              lines = $command_utils:read_lines();
              header = $string_utils:pronoun_sub_secure($code_utils:verb_or_property(player, "paste_header"), "") || $string_utils:center(player.name, 75, "-");
              to_tell = {header};
              for line in (lines)
              to_tell = listappend(to_tell, (prefix + line) + suffix);
              endfor
              to_tell = listappend(to_tell, $string_utils:pronoun_sub_secure($code_utils:verb_or_property(player, "paste_footer"), "") || $string_utils:center("finished", 75, "-"));
              for thing in (player.location.contents)
              $command_utils:suspend_if_needed(0);
              thing:tell_lines(to_tell);
              endfor
              player:tell("Done @pasting.");
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
            <NAME>|*</NAME>
            <CODE>
              "Echo a line prefaced by a vertical bar.";
              "Usage:";
              "  |message";
              "Example:";
              "  Hacker wants to echo to the room what he just saw. He enters (either by hand, or with Emacs or a windowing system):";
              "      |Haakon has disconnected.";
              "  The room sees:";
              "      Hacker | Haakon has disconnected.";
              player.location:announce_all((((player.name + " | ") + verb[2..$]) + " ") + argstr);
            </CODE>
          </VERB>
          <VERB OWNER="obj36" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
            <NAME>@pasteto @paste-to</NAME>
            <CODE>
              "Syntax: @paste-to &lt;player&gt;";
              "";
              "Which will then prompt you for the lines to privately send to &lt;player&gt;. The lines will be surrounded by a default footer and header.";
              target = $string_utils:match_player(dobjstr);
              $command_utils:player_match_result(target, dobjstr);
              if (!valid(target))
              return;
              endif
              prefix = "";
              suffix = "";
              lines = $command_utils:read_lines();
              to_tell = {$string_utils:center("Private message from " + player.name, 75, "-")};
              for line in (lines)
              to_tell = listappend(to_tell, (prefix + line) + suffix);
              endfor
              to_tell = listappend(to_tell, $string_utils:center("end message", 75, "-"));
              target:tell_lines(to_tell);
              player:tell("Done @pasting.");
            </CODE>
          </VERB>
        </OBJECT>
      </OBJECT>
      <OBJECT ID="obj87" FLAGS="r" OWNER="obj2" LOCATION="obj-1">
        <NAME>password verifier</NAME>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>minimum_password_length</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>check_against_name</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>check_against_email</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>check_against_hosts</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>check_against_dictionary</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>require_funky_characters</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>help_msg</NAME>
          <VALUE>{"Password Verifier", "==================", "", "To check for the validity of a password, use", "  :reject_password( password [, for-whom? ] )", "... If it returns a true value, that value will contain the string representing the reason why the password was rejected.  If it returns a false value, the password is OK.", "", "The toggle switches for this checking are:"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>check_against_moo</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>check_obscure_stuff</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>drop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>drop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>odrop_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>odrop_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>otake_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>otake_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>take_succeeded_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>take_failed_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>key</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>aliases</NAME>
          <VALUE>{"password verifier", "password", "verifier", "pwd"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>description</NAME>
          <VALUE>"The password verifier verifies passwords."</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>object_size</NAME>
          <VALUE>{10869, 919123705}</VALUE>
        </PROPERTY>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>help_msg</NAME>
          <CODE>
            if (typeof(base = this.(verb)) == STR)
            base = {base};
            endif
            base = {@base, "", tostr(".minimum_password_length = ", toliteral(x = this.minimum_password_length)), x ? tostr("Passwords are required to be a minimum of ", $string_utils:english_number(x), " characters in length.") | "There is no minimum length requirement for passwords."};
            base = {@base, "", tostr(".check_against_moo = ", toliteral(x = this.check_against_moo)), tostr("Passwords ", x ? "may not" | "may", " be variants on the MOO's name (", $network.MOO_name, ").")};
            base = {@base, "", tostr(".check_against_name = ", toliteral(x = this.check_against_name)), tostr("Passwords ", x ? "may not" | "may", " be variants on the player's MOO name and/or aliases.")};
            base = {@base, "", tostr(".check_against_email = ", toliteral(x = this.check_against_email)), x ? "Passwords may not be variants on the player's email address." | "Passwords are not checked against the player's email address."};
            base = {@base, "", tostr(".check_against_hosts = ", toliteral(x = this.check_against_hosts)), x ? "Passwords may not be variants on the player's hostname(s)." | "Passwords are not checked against the player's hostname(s)."};
            base = {@base, "", tostr(".check_against_dictionary = ", toliteral(x = this.check_against_dictionary)), tostr("Passwords ", (typeof(x) in {LIST, OBJ}) ? "may not" | "may", " be dictionary words.", (x &amp;&amp; (!$network.active)) ? "  (This option is set but unavailable.)" | "")};
            base = {@base, "", tostr(".require_funky_characters = ", toliteral(x = this.require_funky_characters)), tostr("Non-alphabetic characters are ", x ? "" | "not ", "required in passwords.")};
            base = {@base, "", tostr(".check_obscure_stuff = ", toliteral(x = this.check_obscure_stuff)), x ? "Misc. obscure checks enabled" | "No obscure checks in use."};
            return base;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>reject_password</NAME>
          <CODE>
            ":reject_password ( STR password [ , OBJ for-whom ] );";
            "=&gt; string value [if the password is rejected, why?]";
            "=&gt; false value [if the password isn't rejected]";
            if (length(args) == 1)
            trust = 0;
            else
            if ($perm_utils:controls(caller_perms(), args[2]))
            trust = 1;
            else
            return "Permissions don't permit setting of that password.";
            endif
            endif
            "this is gonna be huge";
            return (((((((this:trivial_check(@args) || (this.minimum_password_length &amp;&amp; this:check_length(@args))) || ((this.check_against_name &amp;&amp; trust) &amp;&amp; this:check_name(@args))) || ((this.check_against_email &amp;&amp; trust) &amp;&amp; this:check_email(@args))) || ((this.check_against_hosts &amp;&amp; trust) &amp;&amp; this:check_hosts(@args))) || ((typeof(this.check_against_dictionary) in {LIST, OBJ}) &amp;&amp; this:check_dictionary(@args))) || (this.require_funky_characters &amp;&amp; this:check_for_funky_characters(@args))) || (this.check_against_moo &amp;&amp; this:check_against_moo(@args))) || (this.check_obscure_stuff &amp;&amp; this:check_obscure_combinations(@args));
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>trivial_check</NAME>
          <CODE>
            if (typeof(pwd = args[1]) != STR)
            return "Passwords must be strings.";
            elseif (index(pwd, " "))
            return "Passwords may not contain spaces.";
            elseif (length(args) == 2)
            if (((typeof(who = args[2]) != OBJ) || (!valid(who))) || (!is_player(who)))
            return "That's not a player.";
            elseif (!$perm_utils:controls(caller_perms(), who))
            return "You can't set the password for that player.";
            elseif ($object_utils:isa(who, $guest))
            return "Sorry, but guest characters are not allowed to change their passwords.";
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_length</NAME>
          <CODE>
            if ((l = this.minimum_password_length) &amp;&amp; (length(args[1]) &lt; l))
            return tostr("Passwords must be a minimum of ", $string_utils:english_number(l), (l == 1) ? " character " | " characters ", "long.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_name</NAME>
          <CODE>
            pwd = args[1];
            if (valid($player_db:find_exact(pwd)))
            return "Passwords may not be close to a player's name/alias pair.";
            elseif (valid($player_db:find($string_utils:reverse(pwd))))
            return "Passwords ought not be the reverse of a player's name/alias.";
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_email</NAME>
          <CODE>
            {pwd, who} = args;
            if (!$perm_utils:controls(caller_perms(), who))
            return "Permission denied.";
            endif
            email = $wiz_utils:get_email_address(who);
            if (!email)
            "can't check";
            return;
            endif
            if (index(email, pwd))
            return "Passwords can't match your registered email address.";
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_hosts</NAME>
          <CODE>
            {pwd, who} = args;
            if (!$perm_utils:controls(caller_perms(), who))
            return "Permission denied.";
            endif
            hosts = who.all_connect_places;
            for x in (hosts)
            if (index(x, pwd))
            return "Passwords may not match hostnames.";
            endif
            endfor
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_dictionary</NAME>
          <CODE>
            pwd = args[1];
            if ((typeof(dict = this.check_against_dictionary) == LIST) &amp;&amp; $network.active)
            "assume we're checking an on-line dictionary";
            dict[3] = dict[3] + pwd;
            result = $gopher:get(@dict);
            if (typeof(result) == ERR)
            "we probably can't check the dictionary anyway";
            return;
            elseif ((result[1] &amp;&amp; (result[1][1] != "0")) &amp;&amp; (!this:_is_funky_case(pwd)))
            return "Dictionary words are not permitted for passwords.";
            endif
            elseif (typeof(dict) == OBJ)
            "assume we're checking mr spell";
            try
            if (dict:find_exact(pwd) &amp;&amp; (!this:_is_funky_case(pwd)))
            return "Dictionary words are not permitted for passwords.";
            endif
            except (ANY)
            "in case this is messed up. Just let it go and return 0;";
            endtry
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_for_funky_characters</NAME>
          <CODE>
            if (this:_is_funky_case(pwd = args[1]))
            return;
            endif
            alphabet = $string_utils.alphabet;
            for i in [1..length(pwd)]
            if (!index(alphabet, pwd[i]))
            return;
            endif
            endfor
            return "At least one unusual capitalization and/or numeric or punctuation character is required.";
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_against_moo</NAME>
          <CODE>
            pwd = args[1];
            moo = $network.MOO_Name;
            if (this:_is_funky_case(pwd))
            return;
            endif
            if (pwd == moo)
            return "The MOO's name is not secure as a password.";
            endif
            if (moo[$ - 2..$] == "MOO")
            if (pwd == moo[1..$ - 3])
            return "The MOO's name is not secure as a password.";
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>_is_funky_case</NAME>
          <CODE>
            pwd = args[1];
            if (!strcmp(pwd, u = $string_utils:uppercase(pwd)))
            return 0;
            elseif (!strcmp(pwd, l = $string_utils:lowercase(pwd)))
            return 0;
            elseif (!strcmp(pwd, tostr(u[1], l[2..$])))
            return 0;
            else
            return 1;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>check_obscure_combinations</NAME>
          <CODE>
            pwd = args[1];
            if (match(pwd, "^[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]$"))
            return "Social security numbers are potentially insecure passwords.";
            elseif (match(pwd, "^[0-9]+/[0-9]+/[0-9]+$"))
            return "Passwords which look like dates are potentially insecure passwords.";
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>init_for_core</NAME>
          <CODE>
            if (caller_perms().wizard)
            pass(@args);
            this.minimum_password_length = this.check_against_name = this.check_against_email = this.check_against_hosts = this.check_against_dictionary = this.require_funky_characters = this.check_against_moo = this.check_obscure_stuff = 0;
            endif
          </CODE>
        </VERB>
      </OBJECT>
    </OBJECT>
    <OBJECT ID="obj6" FLAGS="f r" OWNER="obj2" LOCATION="obj-1">
      <NAME>generic player</NAME>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>features</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" >
        <NAME>previous_connection</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" >
        <NAME>email_address</NAME>
        <VALUE>""</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>last_disconnect_time</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>help</NAME>
        <VALUE>#60</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>more_msg</NAME>
        <VALUE>"*** More ***  %n lines left.  Do @more [rest|flush] for more."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>linetask</NAME>
        <VALUE>{0, 0}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>linesleft</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" >
        <NAME>linebuffer</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>pagelen</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>owned_objects</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>linelen</NAME>
        <VALUE>-79</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c">
        <NAME>current_folder</NAME>
        <VALUE>1</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" >
        <NAME>all_connect_places</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" >
        <NAME>last_connect_place</NAME>
        <VALUE>"?"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>dict</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>brief</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c">
        <NAME>lines</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>page_absent_msg</NAME>
        <VALUE>"%N is not currently logged in."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>pq</NAME>
        <VALUE>"its"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>pqc</NAME>
        <VALUE>"Its"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>page_origin_msg</NAME>
        <VALUE>"You sense that %n is looking for you in %l."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>page_echo_msg</NAME>
        <VALUE>"Your message has been sent."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>edit_options</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>last_connect_time</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" >
        <NAME>ownership_quota</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>gender</NAME>
        <VALUE>"neuter"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>prc</NAME>
        <VALUE>"Itself"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>ppc</NAME>
        <VALUE>"Its"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>poc</NAME>
        <VALUE>"It"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>psc</NAME>
        <VALUE>"It"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>pr</NAME>
        <VALUE>"itself"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>pp</NAME>
        <VALUE>"its"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>po</NAME>
        <VALUE>"it"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>ps</NAME>
        <VALUE>"it"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>home</NAME>
        <VALUE>#62</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" >
        <NAME>password</NAME>
        <VALUE>"impossible password to type"</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>gaglist</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>paranoid</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>display_options</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>verb_subs</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>first_connect_time</NAME>
        <VALUE>2147483647</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" >
        <NAME>size_quota</NAME>
        <VALUE>{}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" >
        <NAME>last_password_time</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" >
        <NAME>last_connect_attempt</NAME>
        <VALUE>0</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c">
        <NAME>key</NAME>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="r">
        <NAME>aliases</NAME>
        <VALUE>{"generic player"}</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj2" PERMS="c r">
        <NAME>description</NAME>
        <VALUE>"You see a player who should type '@describe me as ...'."</VALUE>
      </PROPERTY>
      <PROPERTY OWNER="obj36" PERMS="r">
        <NAME>object_size</NAME>
        <VALUE>{95739, 919123665}</VALUE>
      </PROPERTY>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>init_for_core</NAME>
        <CODE>
          if (caller_perms().wizard)
          pass();
          this.home = (this in {$no_one, $hacker}) ? $nothing | $player_start;
          if (a = $list_utils:assoc(this, {{$prog, {$prog_help, $builtin_function_help, $verb_help, $core_help}}, {$wiz, $wiz_help}, {$builder, $builder_help}, {$mail_recipient_class, $mail_help}, {$frand_class, $frand_help}}))
          this.help = a[2];
          else
          this.help = 0;
          endif
          if (this != $player)
          for p in ({"last_connect_place", "all_connect_places", "features", "previous_connection", "last_connect_time"})
          clear_property(this, p);
          endfor
          if (is_player(this))
          this.first_connect_time = $maxint;
          this.last_disconnect_time = $maxint;
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>confunc</NAME>
        <CODE>
          if (((valid(cp = caller_perms()) &amp;&amp; (caller != this)) &amp;&amp; (!$perm_utils:controls(cp, this))) &amp;&amp; (caller != #0))
          return E_PERM;
          endif
          this:("@last-connection")();
          $news:check();
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>disfunc</NAME>
        <CODE>
          if (((valid(cp = caller_perms()) &amp;&amp; (caller != this)) &amp;&amp; (!$perm_utils:controls(cp, this))) &amp;&amp; (caller != #0))
          return E_PERM;
          endif
          this:expunge_rmm();
          this:erase_paranoid_data();
          this:gc_gaglist();
          return;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>initialize</NAME>
        <CODE>
          if ((caller == this) || $perm_utils:controls(caller_perms(), this))
          this.help = 0;
          return pass(@args);
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>acceptable</NAME>
        <CODE>
          return !is_player(args[1]);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>my_huh</NAME>
        <CODE>
          "Extra parsing of player commands.  Called by $command_utils:do_huh.";
          "This version of my_huh just handles features.";
          permissions = (((caller == this) || $perm_utils:controls(caller_perms(), this)) &amp;&amp; $command_utils:validate_feature(@args)) ? this | $no_one;
          "verb - obvious                 pass - would be args";
          "plist - list of prepspecs that this command matches";
          "dlist and ilist - likewise for dobjspecs, iobjspecs";
          verb = args[1];
          if ($code_utils:toint(verb))
          return;
          endif
          pass = args[2];
          plist = {"any", prepstr ? $code_utils:full_prep(prepstr) | "none"};
          dlist = dobjstr ? {"any"} | {"none", "any"};
          ilist = iobjstr ? {"any"} | {"none", "any"};
          for fobj in (this.features)
          if (!$recycler:valid(fobj))
          this:remove_feature(fobj);
          elseif (`valid(loc = $object_utils:has_callable_verb(fobj, verb)[1]) ! ANY =&gt; 0')
          vargs = verb_args(loc, verb);
          if ((vargs[2] in plist) &amp;&amp; ((vargs[1] in dlist) &amp;&amp; (vargs[3] in ilist)))
          "(got rid of notify_huh - should write a @which command)";
          "if (this.notify_huh)";
          "player:notify(tostr(\"Using \", what.name, \" (\", what, \")\"));";
          "endif";
          set_task_perms(permissions);
          fobj:(verb)(@pass);
          "Problem with verbs of the same name. If we use which=vrb in the loop instead, we have a problem with verbs that use the variable verb.";
          return 1;
          endif
          endif
          if ($command_utils:running_out_of_time())
          player:tell("You have too many features.  Parsing your command runs out of ticks while checking ", fobj.name, " (", fobj, ").");
          return 1;
          endif
          endfor
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>last_huh</NAME>
        <CODE>
          ":last_huh(verb,args)  final attempt to parse a command...";
          set_task_perms(caller_perms());
          {verb, args} = args;
          if ((verb[1] == "@") &amp;&amp; (prepstr == "is"))
          "... set or show _msg property ...";
          set_task_perms(player);
          $last_huh:(verb)(@args);
          return 1;
          elseif (verb in {"give", "hand", "get", "take", "drop", "throw"})
          $last_huh:(verb)(@args);
          return 1;
          else
          return 0;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>my_match_object</NAME>
        <CODE>
          ":my_match_object(string [,location])";
          return $string_utils:match_object(@{@args, this.location}[1..2], this);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>tell_contents</NAME>
        <CODE>
          c = args[1];
          if (c)
          longear = {};
          gear = {};
          width = player:linelen();
          half = width / 2;
          player:tell("Carrying:");
          for thing in (c)
          cx = tostr(" ", thing:title());
          if (length(cx) &gt; half)
          longear = {@longear, cx};
          else
          gear = {@gear, cx};
          endif
          endfor
          player:tell_lines($string_utils:columnize(gear, 2, width));
          player:tell_lines(longear);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>titlec</NAME>
        <CODE>
          return `this.namec ! E_PROPNF =&gt; this:title()';
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>notify</NAME>
        <CODE>
          line = args[1];
          if (this.pagelen)
          if (!(this in connected_players()))
          "...drop it on the floor...";
          return 0;
          elseif ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
          return E_PERM;
          endif
          "...need wizard perms if this and this.owner are different, since...";
          "...only this can notify() and only this.owner can read .linebuffer...";
          if ((player == this) &amp;&amp; (this.linetask[2] != task_id()))
          "...player has started a new task...";
          "....linetask[2] is the taskid of the most recent player task...";
          if (this.linetask[2] != this.linetask[1])
          this.linesleft = this.pagelen - 2;
          endif
          this.linetask[2] = task_id();
          endif
          "... digest the current line...";
          if (this.linelen &gt; 0)
          lbuf = {@this.linebuffer, @this:linesplit(line, this.linelen)};
          else
          lbuf = {@this.linebuffer, line};
          endif
          "... print out what we can...";
          if (this.linesleft)
          howmany = min(this.linesleft, length(lbuf));
          for l in (lbuf[1..howmany])
          pass(l);
          endfor
          this.linesleft = this.linesleft - howmany;
          lbuf[1..howmany] = {};
          endif
          if (lbuf)
          "...see if we need to say ***More***";
          if (this.linetask[1] != this.linetask[2])
          "....linetask[1] is the taskid of the most recent player task";
          "...   for which ***More*** was printed...";
          this.linetask[1] = this.linetask[2];
          fork (0)
          if (lb = this.linebuffer)
          pass(strsub(this.more_msg, "%n", tostr(length(lb))));
          endif
          endfork
          endif
          llen = length(lbuf);
          if (llen &gt; 500)
          "...way too much saved text, flush some of it...";
          lbuf[1..llen - 100] = {"*** buffer overflow, lines flushed ***"};
          endif
          endif
          this.linebuffer = lbuf;
          else
          if (caller != this)
          set_task_perms(caller_perms());
          endif
          if (this.linelen &gt; 0)
          for l in (this:linesplit(line, this.linelen))
          pass(l);
          endfor
          else
          pass(line);
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>notify_lines</NAME>
        <CODE>
          if (($perm_utils:controls(caller_perms(), this) || (caller == this)) || (caller_perms() == this))
          set_task_perms(caller_perms());
          for line in ((typeof(lines = args[1]) != LIST) ? {lines} | lines)
          this:notify(tostr(line));
          endfor
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>linesplit</NAME>
        <CODE>
          ":linesplit(line,len) =&gt; list of substrings of line";
          "used by :notify to split up long lines if .linelen&gt;0";
          {line, len} = args;
          cline = {};
          while (length(line) &gt; len)
          cutoff = rindex(line[1..len], " ");
          if (nospace = cutoff &lt; ((4 * len) / 5))
          cutoff = len + 1;
          nospace = line[cutoff] != " ";
          endif
          cline = {@cline, line[1..cutoff - 1]};
          line = (nospace ? " " | "") + line[cutoff..$];
          endwhile
          return {@cline, line};
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>linelen</NAME>
        <CODE>
          return abs(this.linelen);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@more</NAME>
        <CODE>
          if (player != this)
          "... somebody's being sneaky...";
          "... Can't do set_task_perms(player) since we need to be `this'...";
          "... to notify and `this.owner' to change +c properties...";
          return;
          elseif (!(lbuf = this.linebuffer))
          this.linesleft = this.pagelen - 2;
          notify(this, "*** No more ***");
          elseif (index("flush", dobjstr || "x") == 1)
          this.linesleft = this.pagelen - 2;
          notify(this, tostr("*** Flushed ***  ", length(lbuf), " lines"));
          this.linebuffer = {};
          elseif ((index("rest", dobjstr || "x") == 1) || (!this.pagelen))
          this.linesleft = this.pagelen - 2;
          for l in (lbuf)
          notify(this, l);
          endfor
          this.linebuffer = {};
          else
          howmany = min(this.pagelen - 2, llen = length(lbuf = this.linebuffer));
          for l in (lbuf[1..howmany])
          notify(this, l);
          endfor
          this.linesleft = (this.pagelen - 2) - howmany;
          this.linebuffer = lbuf[howmany + 1..llen];
          if (howmany &lt; llen)
          notify(this, strsub(this.more_msg, "%n", tostr(llen - howmany)));
          this.linetask[1] = task_id();
          endif
          endif
          this.linetask[2] = task_id();
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d r" DOBJ="none" PREP="any" IOBJ="none">
        <NAME>@wrap</NAME>
        <CODE>
          if (player != this)
          "... someone is being sneaky...";
          "... Can't do set_task_perms(player) since we need to be `this'...";
          "... to notify and `this.owner' to change +c properties...";
          return;
          endif
          linelen = player.linelen;
          if (!(prepstr in {"on", "off"}))
          player:notify("Usage:  @wrap on|off");
          player:notify(tostr("Word wrap is currently ", (linelen &gt; 0) ? "on" | "off", "."));
          return;
          endif
          player.linelen = abs(linelen) * ((prepstr == "on") ? 1 | -1);
          player:notify(tostr("Word wrap is now ", prepstr, "."));
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@linelen*gth</NAME>
        <CODE>
          if (callers() ? (caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)) | (player != this))
          "... somebody is being sneaky ...";
          return;
          endif
          curlen = player.linelen;
          wrap = curlen &gt; 0;
          wrapstr = wrap ? "on" | "off";
          if (!dobjstr)
          player:notify(tostr("Usage:  ", verb, " &lt;number&gt;"));
          player:notify(tostr("Current line length is ", abs(curlen), ".  Word wrapping is ", wrapstr, "."));
          return;
          endif
          newlen = toint(dobjstr);
          if (newlen &lt; 0)
          player:notify("Line length can't be a negative number.");
          return;
          elseif (newlen &lt; 10)
          player:notify("You don't want your linelength that small.  Setting it to 10.");
          newlen = 10;
          endif
          this:set_linelength(newlen);
          player:notify(tostr("Line length is now ", abs(player.linelen), ".  Word wrapping is ", wrapstr, "."));
          if (!wrap)
          player:notify("To enable word wrapping, type `@wrap on'.");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@pagelen*gth</NAME>
        <CODE>
          "@pagelength number  -- sets page buffering to that many lines (or 0 to turn off page buffering)";
          if (player != this)
          "... somebody is being sneaky ...";
          "... Can't do set_task_perms(player) since we need to be `this'...";
          "... to notify and `this.owner' to change +c properties...";
          return;
          elseif (!dobjstr)
          notify(player, tostr("Usage:  ", verb, " &lt;number&gt;"));
          notify(player, tostr("Current page length is ", player.pagelen, "."));
          return;
          elseif (0 &gt; (newlen = toint(dobjstr)))
          notify(player, "Page length can't be a negative number.");
          return;
          elseif (newlen == 0)
          player.pagelen = 0;
          notify(player, "Page buffering off.");
          if (lb = this.linebuffer)
          "queued text remains";
          this:notify_lines(lb);
          clear_property(this, "linebuffer");
          endif
          elseif (newlen &lt; 5)
          player.pagelen = 5;
          notify(player, "Too small.  Setting it to 5.");
          else
          notify(player, tostr("Page length is now ", player.pagelen = newlen, "."));
          endif
          if (this.linebuffer)
          notify(this, strsub(this.more_msg, "%n", tostr(length(this.linebuffer))));
          player.linetask = {task_id(), task_id()};
          player.linesleft = 0;
          else
          player.linetask = {0, task_id()};
          player.linesleft = player.pagelen - 2;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>tell</NAME>
        <CODE>
          if (this.gaglist || this.paranoid)
          "Check the above first, default case, to save ticks.  Paranoid gaggers are cost an extra three or so ticks by this, probably a net savings.";
          if (this:gag_p())
          return;
          endif
          if (this.paranoid == 1)
          $paranoid_db:add_data(this, {{@callers(1), {player, "&lt;cmd-line&gt;", player}}, args});
          elseif (this.paranoid == 2)
          z = this:whodunnit({@callers(), {player, "", player}}, {this, $no_one}, {})[3];
          args = {"(", z.name, " ", z, ") ", @args};
          endif
          endif
          pass(@args);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>gag_p</NAME>
        <CODE>
          if (player in this.gaglist)
          return 1;
          elseif (gag = this.gaglist)
          for x in (callers())
          if (((x[1] == #-1) &amp;&amp; (x[3] == #-1)) &amp;&amp; (x[2] != ""))
          elseif ((x[1] in gag) || (x[4] in gag))
          return 1;
          endif
          endfor
          endif
          return 0;
          "--- old definition --";
          if (player in this.gaglist)
          return 1;
          elseif (this.gaglist)
          for x in (callers())
          if (valid(x[1]))
          if (x[1] in this.gaglist)
          return 1;
          endif
          endif
          endfor
          endif
          return 0;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_gaglist</NAME>
        <CODE>
          ":set_gaglist(@newlist) =&gt; this.gaglist = newlist";
          if (!((caller == this) || $perm_utils:controls(caller_perms(), this)))
          return E_PERM;
          else
          return this.gaglist = args;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@gag*!</NAME>
        <CODE>
          set_task_perms(player);
          if (player != this)
          player:notify("Permission denied.");
          return;
          endif
          if (!args)
          player:notify(tostr("Usage:  ", verb, " &lt;player or object&gt; [&lt;player or object&gt;...]"));
          return;
          endif
          victims = $string_utils:match_player_or_object(@args);
          changed = 0;
          for p in (victims)
          if (p in player.gaglist)
          player:notify(tostr("You are already gagging ", p.name, "."));
          elseif (p == player)
          player:notify("Gagging yourself is a bad idea.");
          elseif (children(p) &amp;&amp; (verb != "@gag!"))
          player:tell("If you really want to gag all descendents of ", $string_utils:nn(p), ", use `@gag! ", p, "' instead.");
          else
          changed = 1;
          player:set_gaglist(@setadd(this.gaglist, p));
          endif
          endfor
          if (changed)
          this:("@listgag")();
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@listgag @gaglist @gagged</NAME>
        <CODE>
          set_task_perms(valid(caller_perms()) ? caller_perms() | player);
          if (!this.gaglist)
          player:notify(tostr("You are ", callers() ? "no longer gagging anything." | "not gagging anything right now."));
          else
          player:notify(tostr("You are ", callers() ? "now" | "currently", " gagging ", $string_utils:english_list($list_utils:map_arg(2, $string_utils, "pronoun_sub", "%n (%#)", this.gaglist)), "."));
          endif
          gl = {};
          if (args)
          player:notify("Searching for players who may be gagging you...");
          for p in (players())
          if ((typeof(`p.gaglist ! E_PERM') == LIST) &amp;&amp; (this in p.gaglist))
          gl = {@gl, p};
          endif
          $command_utils:suspend_if_needed(10, "...searching gaglist...");
          endfor
          if (gl || (!callers()))
          player:notify(tostr($string_utils:english_list($list_utils:map_arg(2, $string_utils, "pronoun_sub", "%n (%#)", gl), "No one"), " appear", (length(gl) &lt;= 1) ? "s" | "", " to be gagging you."));
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@ungag</NAME>
        <CODE>
          if ((player != this) || ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this))))
          player:notify("Permission denied.");
          elseif (dobjstr == "")
          player:notify(tostr("Usage:  ", verb, " &lt;player&gt;  or  ", verb, " everyone"));
          elseif (dobjstr == "everyone")
          this.gaglist = {};
          player:notify("You are no longer gagging anyone or anything.");
          else
          if (valid(dobj))
          match = dobj;
          elseif ((match = toobj(dobjstr)) &gt; #0)
          else
          match = $string_utils:match(dobjstr, this.gaglist, "name", this.gaglist, "aliases");
          endif
          if (match == $failed_match)
          player:notify(tostr("You don't seem to be gagging anything named ", dobjstr, "."));
          elseif (match == $ambiguous_match)
          player:notify(tostr("I don't know which \"", dobjstr, "\" you mean."));
          else
          this.gaglist = setremove(this.gaglist, match);
          player:notify(tostr(valid(match) ? match.name | match, " removed from gag list."));
          endif
          this:("@listgag")();
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>whodunnit</NAME>
        <CODE>
          {record, trust, mistrust} = args;
          s = {this, "???", this};
          for w in (record)
          if (((((!valid(s[3])) || s[3].wizard) || (s[3] in trust)) &amp;&amp; (!(s[3] in mistrust))) || (s[1] == this))
          s = w;
          else
          return s;
          endif
          endfor
          return s;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@ch*eck-full</NAME>
        <CODE>
          responsible = $paranoid_db:get_data(this);
          if (length(verb) &lt;= 6)
          "@check, not @check-full";
          n = 5;
          trust = {this, $no_one};
          "... trust no one, my friend.... no one....  --Herod";
          mistrust = {};
          for k in (args)
          if (z = $code_utils:toint(k))
          n = z;
          elseif (k[1] == "!")
          mistrust = listappend(mistrust, $string_utils:match_player(k[2..$]));
          else
          trust = listappend(trust, $string_utils:match_player(k));
          endif
          endfor
          msg_width = player:linelen() - 60;
          for q in ((n &gt; (y = length(responsible))) ? responsible | responsible[(y - n) + 1..y])
          msg = tostr(@q[2]);
          if (length(msg) &gt; msg_width)
          msg = msg[1..msg_width];
          endif
          s = this:whodunnit(q[1], trust, mistrust);
          text = valid(s[1]) ? s[1].name | "** NONE **";
          this:notify(tostr($string_utils:left(tostr((length(text) &gt; 13) ? text[1..13] | text, " (", s[1], ")"), 20), $string_utils:left(s[2], 15), $string_utils:left(tostr((length(s[3].name) &gt; 13) ? s[3].name[1..13] | s[3].name, " (", s[3], ")"), 20), msg));
          endfor
          this:notify("*** finished ***");
          else
          "@check-full, from @traceback by APHiD";
          "s_i_n's by Ho_Yan 10/18/94";
          matches = {};
          if (length(match = argstr) == 0)
          player:notify(tostr("Usage: ", verb, " &lt;string&gt; --or-- ", verb, " &lt;number&gt;"));
          return;
          endif
          if (!responsible)
          player:notify("No text has been saved by the monitor.  (See `help @paranoid').");
          else
          if (typeof(x = $code_utils:toint(argstr)) == ERR)
          for line in (responsible)
          if (index(tostr(@line[$]), argstr))
          matches = {@matches, line};
          endif
          endfor
          else
          matches = responsible[($ - x) + 1..$];
          endif
          if (matches)
          for match in (matches)
          $command_utils:suspend_if_needed(3);
          text = tostr(@match[$]);
          player:notify("Traceback for:");
          player:notify(text);
          "Moved cool display code to $code_utils, 3/29/95, Ho_Yan";
          $code_utils:display_callers(listdelete(mm = match[1], length(mm)));
          endfor
          player:notify("**** finished ****");
          else
          player:notify(tostr("No matches for \"", argstr, "\" found."));
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@paranoid</NAME>
        <CODE>
          if ((args == {}) || ((typ = args[1]) == ""))
          $paranoid_db:set_kept_lines(this, 10);
          this.paranoid = 1;
          this:notify("Anti-spoofer on and keeping 10 lines.");
          elseif (index("immediate", typ))
          $paranoid_db:set_kept_lines(this, 0);
          this.paranoid = 2;
          this:notify("Anti-spoofer now in immediate mode.");
          elseif (index("off", typ) || (typ == "0"))
          this.paranoid = 0;
          $paranoid_db:set_kept_lines(this, 0);
          this:notify("Anti-spoofer off.");
          elseif ((tostr(y = toint(typ)) != typ) || (y &lt; 0))
          this:notify(tostr("Usage: ", verb, " &lt;lines to be kept&gt;     to turn on your anti-spoofer."));
          this:notify(tostr("       ", verb, " off                    to turn it off."));
          this:notify(tostr("       ", verb, " immediate              to use immediate mode."));
          else
          this.paranoid = 1;
          $paranoid_db:set_kept_lines(this, y = min(y, 30));
          this:notify(tostr("Anti-spoofer on and keeping ", y, " lines."));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@sw*eep</NAME>
        <CODE>
          buggers = 1;
          found_listener = 0;
          here = this.location;
          for thing in (setremove(here.contents, this))
          tellwhere = $object_utils:has_verb(thing, "tell");
          notifywhere = $object_utils:has_verb(thing, "notify");
          if (thing in connected_players())
          this:notify(tostr(thing.name, " (", thing, ") is listening."));
          found_listener = 1;
          elseif ($object_utils:has_callable_verb(thing, "sweep_msg") &amp;&amp; (typeof(msg = thing:sweep_msg()) == STR))
          this:notify(tostr(thing.name, " (", thing, ") ", msg, "."));
          found_listener = 1;
          elseif (tellwhere &amp;&amp; (((owner = verb_info(tellwhere[1], "tell")[1]) != this) &amp;&amp; (!owner.wizard)))
          this:notify(tostr(thing.name, " (", thing, ") has been taught to listen by ", owner.name, " (", owner, ")"));
          found_listener = 1;
          elseif (notifywhere &amp;&amp; (((owner = verb_info(notifywhere[1], "notify")[1]) != this) &amp;&amp; (!owner.wizard)))
          this:notify(tostr(thing.name, " (", thing, ") has been taught to listen by ", owner.name, " (", owner, ")"));
          found_listener = 1;
          endif
          endfor
          buggers = {};
          for v in ({"announce", "announce_all", "announce_all_but", "say", "emote", "huh", "here_huh", "huh2", "whisper", "here_explain_syntax"})
          vwhere = $object_utils:has_verb(here, v);
          if (vwhere &amp;&amp; (((owner = verb_info(vwhere[1], v)[1]) != this) &amp;&amp; (!owner.wizard)))
          buggers = setadd(buggers, owner);
          endif
          endfor
          if (buggers != {})
          if ($object_utils:has_verb(here, "sweep_msg") &amp;&amp; (typeof(msg = here:sweep_msg()) == STR))
          this:notify(tostr(here.name, " (", here, ") ", msg, "."));
          else
          this:notify(tostr(here.name, " (", here, ") may have been bugged by ", $string_utils:english_list($list_utils:map_prop(buggers, "name")), "."));
          endif
          elseif (!found_listener)
          this:notify("Communications look secure.");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="at/to" IOBJ="this">
        <NAME>wh*isper</NAME>
        <CODE>
          this:tell(player.name, " whispers, \"", dobjstr, "\"");
          player:tell("You whisper, \"", dobjstr, "\" to ", this.name, ".");
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>page</NAME>
        <CODE>
          nargs = length(args);
          if (nargs &lt; 1)
          player:notify(tostr("Usage: ", verb, " &lt;player&gt; [with &lt;message&gt;]"));
          return;
          endif
          who = $string_utils:match_player(args[1]);
          if ($command_utils:player_match_result(who, args[1])[1])
          return;
          elseif (who in this.gaglist)
          player:tell("You have ", who:title(), " @gagged.  If you paged ", $gender_utils:get_pronoun("o", who), ", ", $gender_utils:get_pronoun("s", who), " wouldn't be able to answer you.");
          return;
          endif
          "for pronoun_sub's benefit...";
          dobj = who;
          iobj = player;
          header = player:page_origin_msg();
          text = "";
          if (nargs &gt; 1)
          if ((args[2] == "with") &amp;&amp; (nargs &gt; 2))
          msg_start = 3;
          else
          msg_start = 2;
          endif
          msg = $string_utils:from_list(args[msg_start..nargs], " ");
          text = tostr($string_utils:pronoun_sub(($string_utils:index_delimited(header, player.name) ? "%S" | "%N") + " %&lt;pages&gt;, \""), msg, "\"");
          endif
          result = text ? who:receive_page(header, text) | who:receive_page(header);
          if (result == 2)
          "not connected";
          player:tell((typeof(msg = who:page_absent_msg()) == STR) ? msg | $string_utils:pronoun_sub("%n is not currently logged in.", who));
          else
          player:tell(who:page_echo_msg());
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>receive_page</NAME>
        <CODE>
          "called by $player:page.  Two args, the page header and the text, all pre-processed by the page command.  Could be extended to provide haven abilities, multiline pages, etc.  Indeed, at the moment it just does :tell_lines, so we already do have multiline pages, if someone wants to take advantage of it.";
          "Return codes:";
          "  1:  page was received";
          "  2:  player is not connected";
          "  0:  page refused";
          "If a specialization wants to refuse a page, it should return 0 to say it was refused.  If it uses pass(@args) it should propagate back up the return value.  It is possible that this code should interact with gagging and return 0 if the page was gagged.";
          if (this:is_listening())
          this:tell_lines_suspended(args);
          return 1;
          else
          return 2;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>page_origin_msg page_echo_msg page_absent_msg</NAME>
        <CODE>
          "set_task_perms(this.owner)";
          return (msg = `this.(verb) ! ANY') ? $string_utils:pronoun_sub(this.(verb), this) | "";
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>i inv*entory</NAME>
        <CODE>
          if (c = player:contents())
          this:tell_contents(c);
          else
          player:tell("You are empty-handed.");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>look_self</NAME>
        <CODE>
          player:tell(this:titlec());
          pass();
          if (!(this in connected_players()))
          player:tell($gender_utils:pronoun_sub("%{:He} %{!is} sleeping.", this));
          elseif ((idle = idle_seconds(this)) &lt; 60)
          player:tell($gender_utils:pronoun_sub("%{:He} %{!is} awake and %{!looks} alert.", this));
          else
          time = $string_utils:from_seconds(idle);
          player:tell($gender_utils:pronoun_sub("%{:He} %{!is} awake, but %{!has} been staring off into space for ", this), time, ".");
          endif
          if (c = this:contents())
          this:tell_contents(c);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>home</NAME>
        <CODE>
          start = this.location;
          if (start == this.home)
          player:tell("You're already home!");
          return;
          elseif (typeof(this.home) != OBJ)
          player:tell("You've got a weird home, pal.  I've reset it to the default one.");
          this.home = $player_start;
          elseif (!valid(this.home))
          player:tell("Oh no!  Your home's been recycled.  Time to look around for a new one.");
          this.home = $player_start;
          else
          player:tell("You click your heels three times.");
          endif
          this:moveto(this.home);
          if (!valid(start))
          elseif (start == this.location)
          start:announce(player.name, " ", $gender_utils:get_conj("learns", player), " that you can never go home...");
          else
          try
          start:announce(player.name, " ", $gender_utils:get_conj("goes", player), " home.");
          except e (E_VERBNF)
          "start did not support announce";
          endtry
          endif
          if (this.location == this.home)
          this.location:announce(player.name, " ", $gender_utils:get_conj("comes", player), " home.");
          elseif (this.location == start)
          player:tell("Either home doesn't want you, or you don't really want to go.");
          else
          player:tell("Wait a minute!  This isn't your home...");
          if (valid(this.location))
          this.location:announce(player.name, " ", $gender_utils:get_conj("arrives", player), ", looking quite bewildered.");
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@sethome</NAME>
        <CODE>
          set_task_perms(this);
          here = this.location;
          if (!$object_utils:has_callable_verb(here, "accept_for_abode"))
          player:notify("This is a pretty odd place.  You should make your home in an actual room.");
          elseif (here:accept_for_abode(this))
          this.home = here;
          player:notify(tostr(here.name, " is your new home."));
          else
          player:notify(tostr("This place doesn't want to be your home.  Contact ", here.owner.name, " to be added to the residents list of this place, or choose another place as your home."));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="none">
        <NAME>g*et take</NAME>
        <CODE>
          player:tell("This is not a pick-up joint!");
          this:tell(player.name, " tried to pick you up.");
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="at/to" IOBJ="any">
        <NAME>@move @teleport</NAME>
        <CODE>
          "'@move &lt;object&gt; to &lt;place&gt;' - Teleport an object. Example: '@move trash to #11' to move trash to the closet.";
          set_task_perms((caller == this) ? this | $no_one);
          dobj = this:my_match_object(dobjstr);
          iobj = this:my_match_object(iobjstr);
          if ($command_utils:object_match_failed(dobj, dobjstr) || ((iobj != $nothing) &amp;&amp; $command_utils:object_match_failed(iobj, iobjstr)))
          return;
          endif
          if ((!$perm_utils:controls(this, dobj)) &amp;&amp; (this != dobj))
          player:tell("You may only @move your own things.");
          return;
          endif
          old_loc = dobj.location;
          if (old_loc == iobj)
          player:tell(dobj.name, " is already ", valid(iobj) ? "in " + iobj.name | "nowhere", ".");
          return;
          endif
          dobj:moveto(iobj);
          if (dobj.location == iobj)
          player:tell("Moved.");
          if (is_player(dobj))
          if (valid(old_loc))
          old_loc:announce_all(dobj.name, " disappears suddenly for parts unknown.");
          if (dobj != player)
          dobj:tell("You have been moved by ", player.name, ".");
          endif
          endif
          if (valid(dobj.location))
          dobj.location:announce(dobj.name, " materializes out of thin air.");
          endif
          endif
          elseif (dobj.location == old_loc)
          if ($object_utils:contains(dobj, iobj))
          player:tell(iobj.name, " is inside of ", dobj.name, "!");
          else
          player:tell($string_utils:pronoun_sub("Either %d doesn't want to go, or %i doesn't want to accept %[dpo]."));
          endif
          elseif (dobj == player)
          player:tell("You have been deflected from your original destination.");
          else
          player:tell($string_utils:pronoun_sub("%D has been deflected from %[dpp] original destination."));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="out of/from inside/from" IOBJ="any">
        <NAME>@eject @eject! @eject!!</NAME>
        <CODE>
          set_task_perms(player);
          if (iobjstr == "here")
          iobj = player.location;
          elseif (iobjstr == "me")
          iobj = player;
          elseif ($command_utils:object_match_failed(iobj, iobjstr))
          return;
          endif
          if (!$perm_utils:controls(player, iobj))
          player:notify(tostr("You are not the owner of ", iobj.name, "."));
          return;
          endif
          if (dobjstr == "me")
          dobj = player;
          elseif (($failed_match == (dobj = $string_utils:literal_object(dobjstr))) &amp;&amp; $command_utils:object_match_failed(dobj = iobj:match(dobjstr), dobjstr))
          return;
          endif
          if (dobj.location != iobj)
          player:notify(tostr(dobj.name, "(", dobj, ") is not in ", iobj.name, "(", iobj, ")."));
          return;
          endif
          if (dobj.wizard)
          player:notify(tostr("Sorry, you can't ", verb, " a wizard."));
          dobj:tell(player.name, " tried to ", verb, " you.");
          return;
          endif
          iobj:((verb == "@eject") ? "eject" | "eject_basic")(dobj);
          player:notify($object_utils:has_callable_verb(iobj, "ejection_msg") ? iobj:ejection_msg() | $room:ejection_msg());
          if (verb != "@eject!!")
          dobj:tell($object_utils:has_callable_verb(iobj, "victim_ejection_msg") ? iobj:victim_ejection_msg() | $room:victim_ejection_msg());
          endif
          iobj:announce_all_but({player, dobj}, $object_utils:has_callable_verb(iobj, "oejection_msg") ? iobj:oejection_msg() | $room:oejection_msg());
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>where*is @where*is</NAME>
        <CODE>
          if (!args)
          them = connected_players();
          else
          who = $command_utils:player_match_result($string_utils:match_player(args), args);
          if (length(who) &lt;= 1)
          if (!who[1])
          player:notify("Where is who?");
          endif
          return;
          elseif (who[1])
          player:notify("");
          endif
          them = listdelete(who, 1);
          endif
          lmax = rmax = 0;
          for p in (them)
          player:notify(tostr($string_utils:left($string_utils:nn(p), 25), " ", $string_utils:nn(p.location)));
          endfor
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@who</NAME>
        <CODE>
          if (caller != player)
          return E_PERM;
          endif
          plyrs = args ? listdelete($command_utils:player_match_result($string_utils:match_player(args), args), 1) | connected_players();
          if (!plyrs)
          return;
          elseif (length(plyrs) &gt; 100)
          player:tell("You have requested a listing of ", length(plyrs), " players.  Please either specify individual players you are interested in, to reduce the number of players in any single request, or else use the `@users' command instead.  The lag thanks you.");
          return;
          endif
          $code_utils:show_who_listing(plyrs);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@wizards</NAME>
        <CODE>
          "@wizards [all]";
          if (caller != player)
          return E_PERM;
          endif
          if (args)
          $code_utils:show_who_listing($wiz_utils:all_wizards());
          else
          $code_utils:show_who_listing($wiz_utils:connected_wizards()) || player:notify("No wizards currently logged in.");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>?* help info*rmation @help</NAME>
        <CODE>
          set_task_perms(callers() ? caller_perms() | player);
          "...this code explicitly relies on being !d in several places...";
          if ((index(verb, "?") != 1) || (length(verb) &lt;= 1))
          what = $string_utils:trimr(argstr);
          elseif (argstr)
          what = tostr(verb[2..$], " ", $string_utils:trimr(argstr));
          else
          what = verb[2..$];
          endif
          "...find a db that claims to know about `what'...";
          dblist = $code_utils:help_db_list();
          result = $code_utils:help_db_search(what, dblist);
          if (!result)
          "... note: all of the last-resort stuff...";
          "... is now located on $help:find_topics/get_topic...";
          $wiz_utils:missed_help(what, result);
          player:notify(tostr("Sorry, but no help is available on `", what, "'."));
          elseif (result[1] == $ambiguous_match)
          $wiz_utils:missed_help(what, result);
          player:notify_lines(tostr("Sorry, but the topic-name `", what, "' is ambiguous.  I don't know which of the following topics you mean:"));
          for x in ($help:columnize(@$help:sort_topics(result[2])))
          player:notify(tostr("   ", x));
          endfor
          else
          {help, topic} = result;
          if (topic != what)
          player:notify(tostr("Showing help on `", topic, "':"));
          player:notify("----");
          endif
          dblist = dblist[1 + (help in dblist)..$];
          if (1 == (text = help:get_topic(topic, dblist)))
          "...get_topic took matters into its own hands...";
          elseif (text)
          "...these can get long...";
          for line in ((typeof(text) == LIST) ? text | {text})
          if (typeof(line) != STR)
          player:notify("Odd results from help -- complain to a wizard.");
          else
          player:notify(line);
          endif
          $command_utils:suspend_if_needed(0);
          endfor
          else
          player:notify(tostr("Help DB ", help, " thinks it knows about `", what, "' but something's messed up."));
          player:notify(tostr("Tell ", help.owner.wizard ? "" | tostr(help.owner.name, " (", help.owner, ") or "), "a wizard."));
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>display_option</NAME>
        <CODE>
          ":display_option(name) =&gt; returns the value of the specified @display option";
          if ((caller == this) || $perm_utils:controls(caller_perms(), this))
          return $display_options:get(this.display_options, args[1]);
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>edit_option</NAME>
        <CODE>
          ":edit_option(name) =&gt; returns the value of the specified edit option";
          if ((caller == this) || ($object_utils:isa(caller, $generic_editor) || $perm_utils:controls(caller_perms(), this)))
          return $edit_options:get(this.edit_options, args[1]);
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_mail_option set_edit_option set_display_option</NAME>
        <CODE>
          ":set_edit_option(oname,value)";
          ":set_display_option(oname,value)";
          ":set_mail_option(oname,value)";
          "Changes the value of the named option.";
          "Returns a string error if something goes wrong.";
          if (!((caller == this) || $perm_utils:controls(caller_perms(), this)))
          return tostr(E_PERM);
          endif
          "...this is kludgy, but it saves me from writing the same verb 3 times.";
          "...there's got to be a better way to do this...";
          verb[1..4] = "";
          foo_options = verb + "s";
          "...";
          if (typeof(s = #0.(foo_options):set(this.(foo_options), @args)) == STR)
          return s;
          elseif (s == this.(foo_options))
          return 0;
          else
          this.(foo_options) = s;
          return 1;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@mailo*ptions @mail-o*ptions @edito*ptions @edit-o*ptions @displayo*ptions @display-o*ptions</NAME>
        <CODE>
          "@&lt;what&gt;-option &lt;option&gt; [is] &lt;value&gt;   sets &lt;option&gt; to &lt;value&gt;";
          "@&lt;what&gt;-option &lt;option&gt;=&lt;value&gt;        sets &lt;option&gt; to &lt;value&gt;";
          "@&lt;what&gt;-option +&lt;option&gt;     sets &lt;option&gt;   (usually equiv. to &lt;option&gt;=1";
          "@&lt;what&gt;-option -&lt;option&gt;     resets &lt;option&gt; (equiv. to &lt;option&gt;=0)";
          "@&lt;what&gt;-option !&lt;option&gt;     resets &lt;option&gt; (equiv. to &lt;option&gt;=0)";
          "@&lt;what&gt;-option &lt;option&gt;      displays value of &lt;option&gt;";
          set_task_perms(player);
          what = {"mail", "edit", "display"}[index("med", verb[2])];
          options = what + "_options";
          option_pkg = #0.(options);
          set_option = ("set_" + what) + "_option";
          if (!args)
          player:notify_lines({("Current " + what) + " options:", "", @option_pkg:show(this.(options), option_pkg.names)});
          return;
          elseif (typeof(presult = option_pkg:parse(args)) == STR)
          player:notify(presult);
          return;
          else
          if (length(presult) &gt; 1)
          if (typeof(sresult = this:(set_option)(@presult)) == STR)
          player:notify(sresult);
          return;
          elseif (!sresult)
          player:notify("No change.");
          return;
          endif
          endif
          player:notify_lines(option_pkg:show(this.(options), presult[1]));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_name</NAME>
        <CODE>
          "set_name(newname) attempts to change this.name to newname";
          "  =&gt; E_PERM   if you don't own this";
          "  =&gt; E_INVARG if the name is already taken or prohibited for some reason";
          "  =&gt; E_NACC   if the player database is not taking new names right now.";
          "  =&gt; E_ARGS   if the name is too long (controlled by $login.max_player_name)";
          if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
          return E_PERM;
          elseif (!is_player(this))
          "we don't worry about the names of player classes.";
          set_task_perms(caller_perms());
          return pass(@args);
          elseif ($player_db.frozen)
          return E_NACC;
          elseif (length(name = args[1]) &gt; $login.max_player_name)
          return E_ARGS;
          elseif (!($player_db:available(name, this) in {this, 1}))
          return E_INVARG;
          else
          old = this.name;
          this.name = name;
          if ((name != old) &amp;&amp; (!(old in this.aliases)))
          $player_db:delete(old);
          endif
          $player_db:insert(name, this);
          return 1;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_aliases</NAME>
        <CODE>
          "set_aliases(alias_list)";
          "For changing player aliases, we check to make sure that none of the aliases match existing player names/aliases.  Aliases containing spaces are not entered in the $player_db and so are not subject to this restriction ($string_utils:match_player will not match on them, however, so they only match if used in the immediate room, e.g., with match_object() or somesuch).";
          "Also we make sure that the .name is included in the .alias list.  In any situation where .name and .aliases are both being changed, do the name change first.";
          "  =&gt; 1        if successful, and aliases changed from previous setting.";
          "  =&gt; 0        if resulting work didn't change aliases from previous.";
          "  =&gt; E_PERM   if you don't own this";
          "  =&gt; E_NACC   if the player database is not taking new aliases right now.";
          "  =&gt; E_TYPE   if alias_list is not a list";
          "  =&gt; E_INVARG if any element of alias_list is not a string";
          if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
          return E_PERM;
          elseif (!is_player(this))
          "we don't worry about the names of player classes.";
          return pass(@args);
          elseif ($player_db.frozen)
          return E_NACC;
          elseif (typeof(aliases = args[1]) != LIST)
          return E_TYPE;
          elseif ((length(aliases = setadd(aliases, this.name)) &gt; ($object_utils:has_property($local, "max_player_aliases") ? $local.max_player_aliases | $maxint)) &amp;&amp; (length(aliases) &gt;= length(this.aliases)))
          return E_INVARG;
          else
          for a in (aliases)
          if (typeof(a) != STR)
          return E_INVARG;
          endif
          if ((!(index(a, " ") || index(a, "	"))) &amp;&amp; (!($player_db:available(a, this) in {this, 1})))
          aliases = setremove(aliases, a);
          endif
          endfor
          changed = 0;
          old = this.aliases;
          this.aliases = aliases;
          for a in (old)
          if (!(a in aliases))
          $player_db:delete2(a, this);
          changed = 1;
          endif
          endfor
          for a in (aliases)
          if (!(index(a, " ") || index(a, "	")))
          $player_db:insert(a, this);
          if (!(a in old))
          changed = 1;
          endif
          endif
          endfor
          return changed;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="at/to" IOBJ="any">
        <NAME>@rename*#</NAME>
        <CODE>
          if ((player != caller) || (player != this))
          return;
          endif
          set_task_perms(player);
          bynumber = verb == "@rename#";
          spec = $code_utils:parse_verbref(dobjstr);
          if (spec)
          if (!player.programmer)
          return player:notify(tostr(E_PERM));
          endif
          object = this:my_match_object(spec[1]);
          if (!$command_utils:object_match_failed(object, spec[1]))
          vname = spec[2];
          if (bynumber)
          vname = $code_utils:toint(vname);
          if (vname == E_TYPE)
          return player:notify("Verb number expected.");
          elseif ((vname &lt; 1) || `vname &gt; length(verbs(object)) ! E_PERM =&gt; 0')
          return player:notify("Verb number out of range.");
          endif
          endif
          try
          info = verb_info(object, vname);
          try
          result = set_verb_info(object, vname, listset(info, iobjstr, 3));
          player:notify("Verb name changed.");
          except e (ANY)
          player:notify(e[2]);
          endtry
          except (E_VERBNF)
          player:notify("That object does not define that verb.");
          except e (ANY)
          player:notify(e[2]);
          endtry
          endif
          elseif (bynumber)
          player:notify("@rename# can only be used with verbs.");
          elseif (pspec = $code_utils:parse_propref(dobjstr))
          if (!player.programmer)
          return player:notify(tostr(E_PERM));
          endif
          object = this:my_match_object(pspec[1]);
          if (!$command_utils:object_match_failed(object, pspec[1]))
          pname = pspec[2];
          try
          info = property_info(object, pname);
          try
          result = set_property_info(object, pname, {@info, iobjstr});
          player:notify("Property name changed.");
          except e (ANY)
          player:notify(e[2]);
          endtry
          except (E_PROPNF)
          player:notify("That object does not define that property.");
          except e (ANY)
          player:notify(e[2]);
          endtry
          endif
          else
          object = this:my_match_object(dobjstr);
          if (!$command_utils:object_match_failed(object, dobjstr))
          old_name = object.name;
          old_aliases = object.aliases;
          if (e = $building_utils:set_names(object, iobjstr))
          if (strcmp(object.name, old_name) == 0)
          name_message = tostr("Name of ", object, " (", old_name, ") is unchanged");
          else
          name_message = tostr("Name of ", object, " changed to \"", object.name, "\"");
          endif
          aliases = $string_utils:from_value(object.aliases, 1);
          if (object.aliases == old_aliases)
          alias_message = tostr(".  Aliases are unchanged (", aliases, ").");
          else
          alias_message = tostr(", with aliases ", aliases, ".");
          endif
          player:notify(name_message + alias_message);
          elseif (e == E_INVARG)
          player:notify("That particular name change not allowed (see help @rename).");
          if (object == player)
          player:notify($player_db:why_bad_name(player, iobjstr));
          endif
          elseif (e == E_NACC)
          player:notify("Oops.  You can't update that name right now; try again in a few minutes.");
          elseif (e == E_ARGS)
          player:notify(tostr("Sorry, name too long.  Maximum number of characters in a name:  ", $login.max_player_name));
          elseif (e == 0)
          player:notify("Name and aliases remain unchanged.");
          else
          player:notify(tostr(e));
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="at/to" IOBJ="any">
        <NAME>@addalias*# @add-alias*#</NAME>
        <CODE>
          "Syntax: @addalias &lt;alias&gt;[,...,&lt;alias&gt;] to &lt;object&gt;";
          "        @addalias &lt;alias&gt;[,...,&lt;alias&gt;] to &lt;object&gt;:&lt;verb&gt;";
          "";
          "The first form is used to add aliases to an object's list of aliases.  You can separate multiple aliases with commas.  The aliases will be checked against the object's current aliases and all aliases not already in the object's list of aliases will be added.";
          "";
          "Example:";
          "Muchkin wants to add new aliases to Rover the Wonder Dog:";
          "  @addalias Dog,Wonder Dog to Rover";
          "Since Rover the Wonder Dog already has the alias \"Dog\" but does not have the alias \"Wonder Dog\", Munchkin sees:";
          "  Rover the Wonder Dog(#4237) already has the alias Dog.";
          "  Alias Wonder Dog added to Rover the Wonder Dog(#4237).";
          "";
          "If the object is a player, spaces will also be assumed to be separations between aliases and each alias will be checked against the Player Name Database to make sure no one else is using it. Any already used aliases will be identified.";
          "";
          "Example:";
          "Munchkin wants to add his nicknames to his own list of aliases:";
          "  @addalias Foobar Davey to me";
          "@Addalias recognizes that Munchkin is trying to add an alias to a valid player and checks the aliases against the Player Name Database.  Unfortunately, DaveTheMan is already using the alias \"Davey\" so Munchkin sees:";
          "  DaveTheMan(#5432) is already using the alias Davey";
          "  Alias Foobar added to Munchkin(#1523).";
          "";
          "The second form of the @addalias command is for use by programmers, to add aliases to a verb they own.  All commas and spaces are assumed to be separations between aliases.";
          if (player != this)
          return;
          endif
          set_task_perms(player);
          bynumber = verb[$] == "#";
          spec = $code_utils:parse_verbref(iobjstr);
          if (spec)
          if (!player.programmer)
          return player:notify(tostr(E_PERM));
          endif
          object = player:my_match_object(spec[1]);
          if (!$command_utils:object_match_failed(object, spec[1]))
          vname = spec[2];
          if (bynumber)
          if ((vname = $code_utils:toint(vname)) == E_TYPE)
          return player:notify("Verb number expected.");
          elseif ((vname &lt; 1) || `vname &gt; length(verbs(object)) ! E_PERM =&gt; 0')
          return player:notify("Verb number out of range.");
          endif
          endif
          try
          info = verb_info(object, vname);
          old_aliases = $string_utils:explode(info[3]);
          used = {};
          for alias in (new_aliases = $list_utils:remove_duplicates($string_utils:explode(strsub(dobjstr, ",", " "))))
          if (alias in old_aliases)
          used = {@used, alias};
          new_aliases = setremove(new_aliases, alias);
          endif
          endfor
          if (used)
          player:notify(tostr(object.name, "(", object, "):", vname, " already has the alias", (length(used) &gt; 1) ? "es" | "", " ", $string_utils:english_list(used), "."));
          endif
          if (new_aliases)
          info = listset(info, aliases = $string_utils:from_list({@old_aliases, @new_aliases}, " "), 3);
          try
          result = set_verb_info(object, vname, info);
          player:notify(tostr("Alias", (length(new_aliases) &gt; 1) ? "es" | "", " ", $string_utils:english_list(new_aliases), " added to verb ", object.name, "(", object, "):", vname));
          player:notify(tostr("Verbname is now ", object.name, "(", object, "):\"", aliases, "\""));
          except e (ANY)
          player:notify(e[2]);
          endtry
          endif
          except (E_VERBNF)
          player:notify("That object does not define that verb.");
          except e (ANY)
          player:notify(e[2]);
          endtry
          endif
          elseif (bynumber)
          player:notify(tostr(verb, " can only be used with verbs."));
          else
          object = player:my_match_object(iobjstr);
          if (!$command_utils:object_match_failed(object, iobjstr))
          old_aliases = object.aliases;
          used = {};
          for alias in (new_aliases = $list_utils:remove_duplicates($list_utils:map_arg($string_utils, "trim", $string_utils:explode(is_player(object) ? strsub(dobjstr, " ", ",") | dobjstr, ","))))
          if (alias in old_aliases)
          used = {@used, alias};
          new_aliases = setremove(new_aliases, alias);
          elseif (is_player(object) &amp;&amp; valid(someone = $player_db:find_exact(alias)))
          player:notify(tostr(someone.name, "(", someone, ") is already using the alias ", alias, "."));
          new_aliases = setremove(new_aliases, alias);
          endif
          endfor
          if (used)
          player:notify(tostr(object.name, "(", object, ") already has the alias", (length(used) &gt; 1) ? "es" | "", " ", $string_utils:english_list(used), "."));
          endif
          if (new_aliases)
          if ((e = object:set_aliases(aliases = {@old_aliases, @new_aliases})) &amp;&amp; (object.aliases == aliases))
          player:notify(tostr("Alias", (length(new_aliases) &gt; 1) ? "es" | "", " ", $string_utils:english_list(new_aliases), " added to ", object.name, "(", object, ")."));
          player:notify(tostr("Aliases for ", $string_utils:nn(object), " are now ", $string_utils:from_value(aliases, 1)));
          elseif (e)
          player:notify("That particular name change not allowed (see help @rename or help @addalias).");
          elseif (e == E_INVARG)
          if ($object_utils:has_property(#0, "local"))
          if ($object_utils:has_property($local, "max_player_aliases"))
          max = $local.max_player_aliases;
          player:notify(("You are not allowed more than " + tostr(max)) + " aliases.");
          endif
          else
          player:notify("You are not allowed any more aliases.");
          endif
          elseif (e == E_NACC)
          player:notify("Oops.  You can't update that object's aliases right now; try again in a few minutes.");
          elseif (e == 0)
          player:notify("Aliases not changed as expected!");
          player:notify(tostr("Aliases for ", $string_utils:nn(object), " are now ", $string_utils:from_value(object.aliases, 1)));
          else
          player:notify(tostr(e));
          endif
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="out of/from inside/from" IOBJ="any">
        <NAME>@rmalias*# @rm-alias*#</NAME>
        <CODE>
          "Syntax: @rmalias &lt;alias&gt;[,...,&lt;alias&gt;] from &lt;object&gt;";
          "        @rmalias &lt;alias&gt;[,...,&lt;alias&gt;] from &lt;object&gt;:&lt;verb&gt;";
          "";
          "The first form is used to remove aliases from an object.  If the object is a valid player, space and commas will be assumed to be separations between unwanted aliases.  Otherwise, only commas will be assumed to be separations.";
          "[5/10/93 Nosredna: flushed above is_player feature";
          "Note that @rmalias will not affect the object's name, only its aliases.";
          "";
          "The second form is for use by programmers, to remove aliases from a verb they own.  All spaces and commas are assumed to be separations between unwanted aliases.";
          if (player != this)
          return;
          endif
          set_task_perms(player);
          bynumber = verb[$] == "#";
          spec = $code_utils:parse_verbref(iobjstr);
          if (spec)
          if (!player.programmer)
          player:notify(tostr(E_PERM));
          endif
          object = player:my_match_object(spec[1]);
          if (!$command_utils:object_match_failed(object, spec[1]))
          vname = spec[2];
          if (bynumber)
          if ((vname = $code_utils:toint(vname)) == E_TYPE)
          return player:notify("Verb number expected.");
          elseif ((vname &lt; 1) || `vname &gt; length(verbs(object)) ! E_PERM =&gt; 0')
          return player:notify("Verb number out of range.");
          endif
          endif
          try
          info = verb_info(object, vname);
          old_aliases = $string_utils:explode(info[3]);
          not_used = {};
          for alias in (bad_aliases = $list_utils:remove_duplicates($string_utils:explode(strsub(dobjstr, ",", " "))))
          if (!(alias in old_aliases))
          not_used = {@not_used, alias};
          bad_aliases = setremove(bad_aliases, alias);
          else
          old_aliases = setremove(old_aliases, alias);
          endif
          endfor
          if (not_used)
          player:notify(tostr(object.name, "(", object, "):", vname, " does not have the alias", (length(not_used) &gt; 1) ? "es" | "", " ", $string_utils:english_list(not_used), "."));
          endif
          if (bad_aliases &amp;&amp; old_aliases)
          info = listset(info, aliases = $string_utils:from_list(old_aliases, " "), 3);
          try
          result = set_verb_info(object, vname, info);
          player:notify(tostr("Alias", (length(bad_aliases) &gt; 1) ? "es" | "", " ", $string_utils:english_list(bad_aliases), " removed from verb ", object.name, "(", object, "):", vname));
          player:notify(tostr("Verbname is now ", object.name, "(", object, "):\"", aliases, "\""));
          except e (ANY)
          player:notify(e[2]);
          endtry
          elseif (!old_aliases)
          player:notify("You have to leave a verb with at least one alias.");
          endif
          except (E_VERBNF)
          player:notify("That object does not define that verb.");
          except e (ANY)
          player:notify(e[2]);
          endtry
          endif
          elseif (bynumber)
          player:notify(tostr(verb, " can only be used with verbs."));
          else
          object = player:my_match_object(iobjstr);
          if (!$command_utils:object_match_failed(object, iobjstr))
          old_aliases = object.aliases;
          not_used = {};
          for alias in (bad_aliases = $list_utils:remove_duplicates($list_utils:map_arg($string_utils, "trim", $string_utils:explode(dobjstr, ","))))
          "removed is_player(object) ? strsub(dobjstr, \" \", \",\") | --Nosredna";
          if (!(alias in old_aliases))
          not_used = {@not_used, alias};
          bad_aliases = setremove(bad_aliases, alias);
          else
          old_aliases = setremove(old_aliases, alias);
          endif
          endfor
          if (not_used)
          player:notify(tostr(object.name, "(", object, ") does not have the alias", (length(not_used) &gt; 1) ? "es" | "", " ", $string_utils:english_list(not_used), "."));
          endif
          if (bad_aliases)
          if (e = object:set_aliases(old_aliases))
          player:notify(tostr("Alias", (length(bad_aliases) &gt; 1) ? "es" | "", " ", $string_utils:english_list(bad_aliases), " removed from ", object.name, "(", object, ")."));
          player:notify(tostr("Aliases for ", object.name, "(", object, ") are now ", $string_utils:from_value(old_aliases, 1)));
          elseif (e == E_INVARG)
          player:notify("That particular name change not allowed (see help @rename or help @rmalias).");
          elseif (e == E_NACC)
          player:notify("Oops.  You can't update that object's aliases right now; try again in a few minutes.");
          elseif (e == 0)
          player:notify("Aliases not changed as expected!");
          player:notify(tostr("Aliases for ", $string_utils:nn(object), " are ", $string_utils:from_value(object.aliases, 1)));
          else
          player:notify(tostr(e));
          endif
          endif
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="as" IOBJ="any">
        <NAME>@desc*ribe</NAME>
        <CODE>
          set_task_perms(player);
          dobj = player:my_match_object(dobjstr);
          if ($command_utils:object_match_failed(dobj, dobjstr))
          "...lose...";
          elseif (e = dobj:set_description(iobjstr))
          player:notify("Description set.");
          else
          player:notify(tostr(e));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@mess*ages</NAME>
        <CODE>
          set_task_perms(player);
          if (dobjstr == "")
          player:notify(tostr("Usage:  ", verb, " &lt;object&gt;"));
          return;
          endif
          dobj = player:my_match_object(dobjstr);
          if ($command_utils:object_match_failed(dobj, dobjstr))
          return;
          endif
          found_one = 0;
          props = $object_utils:all_properties(dobj);
          if (typeof(props) == ERR)
          player:notify("You can't read the messages on that.");
          return;
          endif
          for pname in (props)
          len = length(pname);
          if ((len &gt; 4) &amp;&amp; (pname[len - 3..len] == "_msg"))
          found_one = 1;
          msg = `dobj.(pname) ! ANY';
          if (msg == E_PERM)
          value = "isn't readable by you.";
          elseif (!msg)
          value = "isn't set.";
          elseif (typeof(msg) == LIST)
          value = "is a list.";
          elseif (typeof(msg) != STR)
          value = "is corrupted! **";
          else
          value = "is " + $string_utils:print(msg);
          endif
          player:notify(tostr("@", pname[1..len - 4], " ", dobjstr, " ", value));
          endif
          endfor
          if (!found_one)
          player:notify("That object doesn't have any messages to set.");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@notedit</NAME>
        <CODE>
          $note_editor:invoke(dobjstr, verb);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@last-c*onnection</NAME>
        <CODE>
          "@last-c           reports when and from where you last connected.";
          "@last-c all       adds the 10 most recent places you connected from.";
          "@last-c confunc   is like `@last-c' but is silent on first login.";
          opts = {"all", "confunc"};
          i = 0;
          if (caller != this)
          return E_PERM;
          elseif (args &amp;&amp; ((length(args) &gt; 1) || (!(i = $string_utils:find_prefix(args[1], opts)))))
          this:notify(tostr("Usage:  ", verb, " [all]"));
          return;
          endif
          opt_all = i &amp;&amp; (opts[i] == "all");
          opt_confunc = i &amp;&amp; (opts[i] == "confunc");
          if (!(prev = this.previous_connection))
          this:notify("Something was broken when you logged in; tell a wizard.");
          elseif (prev[1] == 0)
          opt_confunc || this:notify("Your previous connection was before we started keeping track.");
          elseif (prev[1] &gt; time())
          this:notify("This is your first time connected.");
          else
          this:notify(tostr("Last connected ", this:ctime(prev[1]), " from ", prev[2]));
          if (opt_all)
          this:notify("Previous connections have been from the following sites:");
          for l in (this.all_connect_places)
          this:notify("   " + l);
          endfor
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_gender</NAME>
        <CODE>
          "set_gender(newgender) attempts to change this.gender to newgender";
          "  =&gt; E_PERM   if you don't own this or aren't its parent";
          "  =&gt; Other return values as from $gender_utils:set.";
          if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
          return E_PERM;
          else
          result = $gender_utils:set(this, args[1]);
          this.gender = (typeof(result) == STR) ? result | args[1];
          return result;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@gender</NAME>
        <CODE>
          set_task_perms(valid(caller_perms()) ? caller_perms() | player);
          if (!args)
          player:notify(tostr("Your gender is currently ", this.gender, "."));
          player:notify($string_utils:pronoun_sub("Your pronouns:  %s,%o,%p,%q,%r,%S,%O,%P,%Q,%R"));
          player:notify(tostr("Available genders:  ", $string_utils:english_list($gender_utils.genders, "", " or ")));
          else
          result = this:set_gender(args[1]);
          quote = (result == E_NONE) ? "\"" | "";
          player:notify(tostr("Gender set to ", quote, this.gender, quote, "."));
          if (typeof(result) != ERR)
          player:notify($string_utils:pronoun_sub("Your pronouns:  %s,%o,%p,%q,%r,%S,%O,%P,%Q,%R"));
          elseif (result != E_NONE)
          player:notify(tostr("Couldn't set pronouns:  ", result));
          else
          player:notify("Pronouns unchanged.");
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_brief</NAME>
        <CODE>
          "set_brief(value)";
          "set_brief(value, anything)";
          "If &lt;anything&gt; is given, add value to the current value; otherwise, just set the value.";
          if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
          return E_PERM;
          else
          if (length(args) == 1)
          this.brief = args[1];
          else
          this.brief = this.brief + args[1];
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@mode</NAME>
        <CODE>
          "@mode &lt;mode&gt;";
          "Current modes are brief and verbose.";
          "General verb for setting player `modes'.";
          "Modes are coded right here in the verb.";
          if (caller != this)
          player:tell("You can't set someone else's modes.");
          return E_PERM;
          endif
          modes = {"brief", "verbose"};
          mode = `modes[$string_utils:find_prefix(dobjstr, modes)] ! E_TYPE, E_RANGE =&gt; 0';
          if (!mode)
          player:tell("Unknown mode \"", dobjstr, "\".  Known modes:");
          for mode in (modes)
          player:tell("  ", mode);
          endfor
          return 0;
          elseif (mode == "brief")
          this:set_brief(1);
          elseif (mode == "verbose")
          this:set_brief(0);
          endif
          player:tell($string_utils:capitalize(mode), " mode set.");
          return 1;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@exam*ine</NAME>
        <CODE>
          "This verb should probably go away once 'examine' is in place.";
          if (dobjstr == "")
          player:notify(tostr("Usage:  ", verb, " &lt;object&gt;"));
          return;
          endif
          what = $string_utils:match_object(dobjstr, player.location);
          if ($command_utils:object_match_failed(what, dobjstr))
          return;
          endif
          player:notify(tostr(what.name, " (", what, ") is owned by ", valid(what.owner) ? what.owner.name | "a recycled player", " (", what.owner, ")."));
          player:notify(tostr("Aliases:  ", $string_utils:english_list(what.aliases)));
          desc = what:description();
          if (desc)
          player:notify_lines(desc);
          else
          player:notify("(No description set.)");
          endif
          if ($perm_utils:controls(player, what))
          player:notify(tostr("Key:  ", $lock_utils:unparse_key(what.key)));
          endif
          contents = what.contents;
          if (contents)
          player:notify("Contents:");
          for item in (contents)
          player:notify(tostr("  ", item.name, " (", item, ")"));
          endfor
          endif
          "Use dobjstr, not shortest alias.";
          name = dobjstr;
          "name = what.name;";
          "if (typeof(what.aliases) == LIST &amp;&amp; what.aliases != {})";
          "for alias in (what.aliases)";
          "if (length(alias) &lt;= length(name))";
          "name = alias;";
          "endif";
          "endfor";
          "endif";
          vrbs = {};
          commands_ok = what in {player, player.location};
          dull_classes = {$root_class, $room, $player, $prog};
          what = what;
          printed_working_msg = 0;
          while (what != $nothing)
          if ($command_utils:running_out_of_time())
          if (!printed_working_msg)
          player:notify("Working on list of obvious verbs...");
          printed_working_msg = 1;
          endif
          suspend(0);
          endif
          if (!(what in dull_classes))
          for i in [1..length(verbs(what))]
          if ($command_utils:running_out_of_time())
          if (!printed_working_msg)
          player:notify("Working on list of obvious verbs...");
          printed_working_msg = 1;
          endif
          suspend(0);
          endif
          info = verb_info(what, i);
          syntax = verb_args(what, i);
          if ((index(info[2], "r") &amp;&amp; ((syntax[2..3] != {"none", "this"}) &amp;&amp; (commands_ok || ("this" in syntax)))) &amp;&amp; verb_code(what, i))
          {dobj, prep, iobj} = syntax;
          if (syntax == {"any", "any", "any"})
          prep = "none";
          endif
          if (prep != "none")
          for x in ($string_utils:explode(prep, "/"))
          if (length(x) &lt;= length(prep))
          prep = x;
          endif
          endfor
          endif
          "This is the correct way to handle verbs ending in *";
          vname = info[3];
          while (j = index(vname, "* "))
          vname = tostr(vname[1..j - 1], "&lt;anything&gt;", vname[j + 1..$]);
          endwhile
          if (vname[$] == "*")
          vname = vname[1..$ - 1] + "&lt;anything&gt;";
          endif
          vname = strsub(vname, " ", "/");
          rest = "";
          if (prep != "none")
          rest = " " + ((prep == "any") ? "&lt;anything&gt;" | prep);
          if (iobj != "none")
          rest = tostr(rest, " ", (iobj == "this") ? name | "&lt;anything&gt;");
          endif
          endif
          if (dobj != "none")
          rest = tostr(" ", (dobj == "this") ? name | "&lt;anything&gt;", rest);
          endif
          vrbs = setadd(vrbs, ("  " + vname) + rest);
          endif
          endfor
          endif
          what = parent(what);
          endwhile
          if (vrbs)
          player:notify("Obvious Verbs:");
          player:notify_lines(vrbs);
          printed_working_msg &amp;&amp; player:notify("(End of list.)");
          elseif (printed_working_msg)
          player:notify("No obvious verbs found.");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>exam*ine</NAME>
        <CODE>
          set_task_perms(player);
          if (!dobjstr)
          player:notify(tostr("Usage:  ", verb, " &lt;object&gt;"));
          return E_INVARG;
          endif
          what = player.location:match_object(dobjstr);
          if ($command_utils:object_match_failed(what, dobjstr))
          return;
          endif
          what:do_examine(player);
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>add_feature</NAME>
        <CODE>
          "Add a feature to this player's features list.  Caller must be this or have suitable permissions (this or wizardly).";
          "If this is a nonprogrammer, then ask feature if it is feature_ok (that is, if it has a verb :feature_ok which returns a true value, or a property .feature_ok which is true).";
          "After adding feature, call feature:feature_add(this).";
          "Returns true if successful, E_INVARG if not a valid object, and E_PERM if !feature_ok or if caller doesn't have permission.";
          if ((caller == this) || $perm_utils:controls(caller_perms(), this))
          feature = args[1];
          if ((typeof(feature) != OBJ) || (!valid(feature)))
          return E_INVARG;
          "Not a valid object.";
          endif
          if ($code_utils:verb_or_property(feature, "feature_ok", this))
          "The object is willing to be a feature.";
          if (typeof(this.features) == LIST)
          "If list, we can simply setadd the feature.";
          this.features = setadd(this.features, feature);
          else
          "If not, we erase the old value and create a new list.";
          this.features = {feature};
          endif
          "Tell the feature it's just been added.";
          try
          feature:feature_add(this);
          except (ANY)
          "just ignore errors.";
          endtry
          return 1;
          "We're done.";
          else
          return E_PERM;
          "Feature isn't feature_ok.";
          endif
          else
          return E_PERM;
          "Caller doesn't have permission.";
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>remove_feature</NAME>
        <CODE>
          "Remove a feature from this player's features list.  Caller must be this, or have permissions of this, a wizard, or feature.owner.";
          "Returns true if successful, E_PERM if caller didn't have permission.";
          feature = args[1];
          if (((caller == this) || $perm_utils:controls(caller_perms(), this)) || (caller_perms() == feature.owner))
          if (typeof(this.features) == LIST)
          "If this is a list, we can just setremove...";
          this.features = setremove(this.features, feature);
          "Otherwise, we leave it alone.";
          endif
          "Let the feature know it's been removed.";
          try
          feature:feature_remove(this);
          except (ANY)
          "just ignore errors.";
          endtry
          return 1;
          "We're done.";
          else
          return E_PERM;
          "Caller didn't have permission.";
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@add-feature @addfeature</NAME>
        <CODE>
          "Usage:";
          "  @add-feature";
          "  @add-feature &lt;feature object&gt;";
          "Modified 10 Oct 94, by Michele, to check the warehouse and match.";
          "Lists all features or adds an object to your features list.";
          set_task_perms(player);
          if (dobjstr)
          if (dobj == $failed_match)
          dobj = $feature.warehouse:match_object(dobjstr);
          endif
          if (!$command_utils:object_match_failed(dobj, dobjstr))
          if (dobj in player.features)
          player:tell(dobjstr, " is already one of your features.");
          elseif (player:add_feature(dobj))
          player:tell(dobj, " (", dobj.name, ") added as a feature.");
          else
          player:tell("You can't seem to add ", dobj, " (", dobj.name, ") to your features list.");
          endif
          endif
          else
          player:tell("Usage:  @add-feature &lt;object&gt;");
          if (length($feature.warehouse.contents) &lt; 20)
          player:tell("Available features include:");
          player:tell("--------------------------");
          fe = {};
          for c in ($feature.warehouse.contents)
          fe = {(c in player.features) ? c:title() + " (*)" | c:title()};
          player:tell("  " + $string_utils:english_list(fe));
          endfor
          player:tell("--------------------------");
          player:tell("A * after the feature name means that you already have that feature.");
          endif
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@remove-feature @rmfeature</NAME>
        <CODE>
          "Usage:  @remove-feature &lt;feature object&gt;";
          "Remove an object from your .features list.";
          set_task_perms(player);
          if (dobjstr)
          features = player.features;
          if (!valid(dobj))
          dobj = $string_utils:match(dobjstr, features, "name", features, "aliases");
          endif
          if (!$command_utils:object_match_failed(dobj, dobjstr))
          if (dobj in features)
          player:remove_feature(dobj);
          player:tell(dobj, " (", dobj.name, ") removed from your features list.");
          else
          player:tell(dobjstr, " is not one of your features.");
          endif
          endif
          else
          player:tell("Usage:  @remove-feature &lt;object&gt;");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="for/about" IOBJ="any">
        <NAME>@features</NAME>
        <CODE>
          "Usage:  @features [&lt;name&gt;] for &lt;player&gt;";
          "List the feature objects matching &lt;name&gt; used by &lt;player&gt;.";
          if (!iobjstr)
          player:tell("Usage: @features [&lt;name&gt;] for &lt;player&gt;");
          return;
          elseif ($command_utils:player_match_failed(whose = $string_utils:match_player(iobjstr), iobjstr))
          return;
          endif
          features = {};
          for feature in (whose.features)
          if (!valid(feature))
          whose:remove_feature(feature);
          elseif ((!dobjstr) || ((dobjstr in feature.aliases) || ((pref = $string_utils:find_prefix(dobjstr, feature.aliases)) || (pref == $ambiguous_match))))
          features = listappend(features, feature);
          endif
          endfor
          if (features)
          len = max(length("Feature"), length(tostr(max_object()))) + 1;
          player:tell($string_utils:left("Feature", len), "Name");
          player:tell($string_utils:left("-------", len), "----");
          for feature in (features)
          player:tell($string_utils:left(tostr(feature), len), feature.name);
          endfor
          player:tell($string_utils:left("-------", len), "----");
          cstr = ((tostr(length(features)) + " feature") + ((length(features) &gt; 1) ? "s" | "")) + " found";
          if (whose != this)
          cstr = ((((cstr + " on ") + whose.name) + " (") + tostr(whose)) + ")";
          endif
          if (dobjstr)
          cstr = ((cstr + " matching \"") + dobjstr) + "\"";
          endif
          cstr = cstr + ".";
          player:tell(cstr);
          elseif (dobjstr)
          player:tell("No features found on ", whose.name, " (", whose, ") matching \"", dobjstr, "\".");
          else
          player:tell("No features found on ", whose.name, " (", whose, ").");
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@features</NAME>
        <CODE>
          "Usage:  @features [&lt;name&gt;]";
          "List the feature objects matching &lt;name&gt; used by player.";
          iobjstr = player.name;
          iobj = player;
          this:("@features")();
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@memory</NAME>
        <CODE>
          stats = memory_usage();
          if (!stats)
          player:notify("Sorry, but no memory-usage statistics are available for this server.");
          return;
          endif
          su = $string_utils;
          player:notify("Block Size   # In Use    # Free    Bytes In Use   Bytes Free");
          player:notify("----------   --------   --------   ------------   ----------");
          nused = nfree = bytesused = bytesfree = 0;
          kilo = 1024;
          meg = kilo * kilo;
          for x in (stats)
          if (x[2..3] != {0, 0})
          bsize = x[1];
          if ((bsize % meg) == 0)
          bsize = tostr(bsize / meg, " M");
          elseif ((bsize % kilo) == 0)
          bsize = tostr(bsize / kilo, " K");
          endif
          bused = x[1] * x[2];
          bfree = x[1] * x[3];
          player:notify(tostr(su:left(bsize, 10), "   ", su:right(su:group_number(x[2]), 8), "   ", su:right(su:group_number(x[3]), 8), "   ", su:right(su:group_number(bused), 12), "   ", su:right(su:group_number(bfree), 10)));
          nused = nused + x[2];
          nfree = nfree + x[3];
          bytesused = bytesused + bused;
          bytesfree = bytesfree + bfree;
          endif
          endfor
          player:notify("");
          player:notify(tostr(su:left("Totals:", 10), "   ", su:right(su:group_number(nused), 8), "   ", su:right(su:group_number(nfree), 8), "   ", su:right(su:group_number(bytesused), 12), "   ", su:right(su:group_number(bytesfree), 10)));
          player:notify("");
          player:notify(tostr("Total Memory Size: ", su:group_number(bytesused + bytesfree), " bytes."));
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@version</NAME>
        <CODE>
          if ($object_utils:has_property($local, "server_hardware"))
          hw = (" on " + $local.server_hardware) + ".";
          else
          hw = ".";
          endif
          player:notify(tostr("The MOO is currently running version ", server_version(), " of the LambdaMOO server code", hw));
          try
          {MOOname, sversion, coretime} = $core_history[1];
          player:notify(tostr("The database was derived from a core created on ", $time_utils:time_sub("$n $t, $Y", coretime), " at ", MOOname, " for version ", sversion, " of the server."));
          except (E_RANGE)
          player:notify("The database was created from scratch.");
          except (ANY)
          player:notify("No information is available on the database version.");
          endtry
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@uptime</NAME>
        <CODE>
          player:notify(tostr("The server has been up for ", $time_utils:english_time(time() - $last_restart_time), "."));
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@quit</NAME>
        <CODE>
          boot_player(player);
          "-- argh, let the player decide; #3:disfunc() takes care of this --Rog";
          "player:moveto(player.home)";
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>examine_commands_ok</NAME>
        <CODE>
          return this == args[1];
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>is_listening</NAME>
        <CODE>
          "return true if player is active.";
          return typeof(`idle_seconds(this) ! ANY') != ERR;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>moveto</NAME>
        <CODE>
          if (args[1] == #-1)
          return E_INVARG;
          this:notify("You are now in #-1, The Void.  Type `home' to get back.");
          endif
          set_task_perms(caller_perms());
          pass(@args);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>announce*_all_but</NAME>
        <CODE>
          return this.location:(verb)(@args);
          "temporarily let player:announce be noisy to player";
          if (verb == "announce_all_but")
          if (this in args[1])
          return;
          endif
          args = args[2..$];
          endif
          this:tell("(from within you) ", @args);
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>linewrap</NAME>
        <CODE>
          "Return a true value if this needs linewrapping.";
          "default is true if .linelen &gt; 0";
          return this.linelen &gt; 0;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@set-note-string @set-note-text</NAME>
        <CODE>
          "Usage:  @set-note-{string | text} {#xx | #xx.pname}";
          "        ...lines of text...";
          "        .";
          "";
          "For use by clients' local editors, to save new text for a note or object property.  See $note_editor:local_editing_info() for details.";
          set_task_perms(player);
          text = $command_utils:read_lines_escape((active = player in $note_editor.active) ? {} | {"@edit"}, {tostr("Changing ", argstr, "."), @active ? {} | {"Type `@edit' to take this into the note editor."}});
          if (text &amp;&amp; (text[1] == "@edit"))
          $note_editor:invoke(argstr, verb);
          who = $note_editor:loaded(player);
          $note_editor.texts[who] = text[2];
          return;
          endif
          text = text[2];
          if ((verb == "@set-note-string") &amp;&amp; (length(text) &lt;= 1))
          text = text ? text[1] | "";
          endif
          if (spec = $code_utils:parse_propref(argstr))
          o = player:my_match_object(spec[1]);
          p = spec[2];
          if ($object_utils:has_verb(o, vb = "set_" + p) &amp;&amp; (typeof(e = o:(vb)(text)) != ERR))
          player:tell("Set ", p, " property of ", o.name, " (", o, ") via :", vb, ".");
          elseif (text != (e = `o.(p) = text ! ANY'))
          player:tell("Error:  ", e);
          else
          player:tell("Set ", p, " property of ", o.name, " (", o, ").");
          endif
          elseif (typeof(note = $code_utils:toobj(argstr)) == OBJ)
          e = note:set_text(text);
          if (typeof(e) == ERR)
          player:tell("Error:  ", e);
          else
          player:tell("Set text of ", note.name, " (", note, ").");
          endif
          else
          player:tell("Error:  Malformed argument to ", verb, ": ", argstr);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>verb_sub</NAME>
        <CODE>
          text = args[1];
          if (a = `$list_utils:assoc(text, this.verb_subs) ! ANY')
          return a[2];
          else
          return $gender_utils:get_conj(text, this);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>ownership_quota</NAME>
        <CODE>
          if ($perm_utils:controls(caller_perms(), this))
          return this.(verb);
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>tell_lines</NAME>
        <CODE>
          lines = args[1];
          if (typeof(lines) != LIST)
          lines = {lines};
          endif
          if (this.gaglist || this.paranoid)
          "Check the above first, default case, to save ticks.  Paranoid gaggers are cost an extra three or so ticks by this, probably a net savings.";
          if (this:gag_p())
          return;
          endif
          if (this.paranoid == 2)
          z = this:whodunnit({@callers(1), {player, "", player}}, {this, $no_one}, {})[3];
          lines = {((("[start text by " + z.name) + " (") + tostr(z)) + ")]", @lines, ((("[end text by " + z.name) + " (") + tostr(z)) + ")]"};
          elseif (this.paranoid == 1)
          $paranoid_db:add_data(this, {{@callers(1), {player, "&lt;cmd-line&gt;", player}}, lines});
          endif
          endif
          "don't gather stats for now: $list_utils:check_nonstring_tell_lines(lines)";
          this:notify_lines(lines);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@lastlog</NAME>
        <CODE>
          "Copied from generic room (#3):@lastlog by Haakon (#2) Wed Dec 30 13:30:02 1992 PST";
          if (dobjstr != "")
          dobj = $string_utils:match_player(dobjstr);
          if (!valid(dobj))
          player:tell("Who?");
          return;
          endif
          folks = {dobj};
          else
          folks = players();
          endif
          day = week = month = ever = never = {};
          a_day = (24 * 60) * 60;
          a_week = 7 * a_day;
          a_month = 30 * a_day;
          now = time();
          for x in (folks)
          when = x.last_connect_time;
          how_long = now - when;
          if ((when == 0) || (when &gt; now))
          never = {@never, x};
          elseif (how_long &lt; a_day)
          day = {@day, x};
          elseif (how_long &lt; a_week)
          week = {@week, x};
          elseif (how_long &lt; a_month)
          month = {@month, x};
          else
          ever = {@ever, x};
          endif
          endfor
          for entry in ({{day, "the last day"}, {week, "the last week"}, {month, "the last 30 days"}, {ever, "recorded history"}})
          if (entry[1])
          player:tell("Players who have connected within ", entry[2], ":");
          for x in (entry[1])
          player:tell("  ", x.name, " last connected ", ctime(x.last_connect_time), ".");
          endfor
          endif
          endfor
          if (never)
          player:tell("Players who have never connected:");
          player:tell("  ", $string_utils:english_list($list_utils:map_prop(never, "name")));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_linelength</NAME>
        <CODE>
          "Set linelength.  Linelength must be an integer &gt;= 10.";
          "If wrap is currently off (i.e. linelength is less than 0), maintains sign.  That is, this function *takes* an absolute value, and coerces the sign to be appropriate.";
          "If you want to override the dwimming of wrap, pass in a second argument.";
          "returns E_PERM if not allowed, E_INVARG if linelength is too low, otherwise the linelength.";
          if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
          return E_PERM;
          elseif (abs(len = args[1]) &lt; 10)
          return E_INVARG;
          elseif (length(args) &gt; 1)
          this.linelen = len;
          else
          "DWIM here.";
          this.linelen = (this.linelen &gt; 0) ? len | (-len);
          return len;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_pagelength</NAME>
        <CODE>
          "Set pagelength. Must be an integer &gt;= 5, or 0 to turn pagelength off.";
          "Returns E_PERM if you shouldn't be doing this, E_INVARG if it's too low, otherwise, what it got set to.";
          if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
          return E_PERM;
          elseif (((len = args[1]) &lt; 5) &amp;&amp; (len != 0))
          return E_INVARG;
          else
          if ((this.pagelen = len) == 0)
          if (lb = this.linebuffer)
          "queued text remains";
          this:notify_lines(lb);
          clear_property(this, "linebuffer");
          endif
          endif
          return len;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_home</NAME>
        <CODE>
          "set_home(newhome) attempts to change this.home to newhome";
          "E_TYPE   if newhome doesn't have a callable :accept_for_abode verb.";
          "E_INVARG if newhome won't accept you as a resident.";
          "E_PERM   if you don't own this and aren't its parent.";
          "1        if it works.";
          newhome = args[1];
          if ((caller == this) || $perm_utils:controls(caller_perms(), this))
          if ($object_utils:has_callable_verb(newhome, "accept_for_abode"))
          if (newhome:accept_for_abode(this))
          return (typeof(e = `this.home = args[1] ! ANY') != ERR) || e;
          else
          return E_INVARG;
          endif
          else
          return E_TYPE;
          endif
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@registerme</NAME>
        <CODE>
          "@registerme as &lt;email-address&gt; -- enter a new email address for player";
          "   will change the database entry, assign a new password, and mail the new password to the player at the given email address.";
          if (player != this)
          return player:notify(tostr(E_PERM));
          endif
          who = this;
          if ($object_utils:isa(this, $guest))
          who:notify("Sorry, guests should use the '@request' command to request a character.");
          return;
          endif
          connection = $string_utils:connection_hostname(connection_name(who));
          if (!argstr)
          if ($wiz_utils:get_email_address(who))
          player:tell("You are currently registered as:  ", $wiz_utils:get_email_address(who));
          else
          player:tell("You are not currently registered.");
          endif
          player:tell("Use @registerme as &lt;address&gt; to change this.");
          return;
          elseif (((prepstr != "as") || (!iobjstr)) || dobjstr)
          player:tell("Usage: @registerme as &lt;address&gt;");
          return;
          endif
          email = iobjstr;
          if (email == $wiz_utils:get_email_address(this))
          who:notify("That is your current address.  Not changed.");
          return;
          elseif (reason = $wiz_utils:check_reregistration(this, email, connection))
          if (reason[1] == "-")
          if (!$command_utils:yes_or_no(reason[2..$] + ". Automatic registration not allowed. Ask to be registered at this address anyway?"))
          who:notify("Okay.");
          return;
          endif
          else
          return who:notify(tostr(reason, " Please try again."));
          endif
          endif
          if ($network.active &amp;&amp; (!reason))
          if (!$command_utils:yes_or_no(tostr("If you continue, your password will be changed, the new password mailed to `", email, "'. Do you want to continue?")))
          return who:notify("Registration terminated.");
          endif
          password = $wiz_utils:random_password(5);
          old = $wiz_utils:get_email_address(who) || "[ unregistered ]";
          who:notify(tostr("Registering you, and changing your password and mailing new one to ", email, "."));
          result = $network:sendmail(email, tostr("Your ", $network.MOO_Name, " character, ", who.name), "Reply-to: " + $login.registration_address, @$generic_editor:fill_string(tostr("Your ", $network.MOO_name, " character, ", $string_utils:nn(who), " has been registered to this email address (", email, "), and a new password assigned.  The new password is `", password, "'. Please keep your password secure. You can change your password with the @password command."), 75));
          if (result != 0)
          who:notify(tostr("Mail sending did not work: ", reason, ". Reregistration terminated."));
          return;
          endif
          who:notify(tostr("Mail with your new password forwarded. If you do not get it, send regular email to ", $login.registration_address, " with your character name."));
          $mail_agent:send_message($new_player_log, $new_player_log, "reg " + $string_utils:nn(this), {email, tostr("formerly ", old)});
          $registration_db:add(this, email, "Reregistered at " + ctime());
          $wiz_utils:set_email_address(this, email);
          who.password = crypt(password);
          who.last_password_time = time();
          else
          who:notify("No automatic reregistration: your request will be forwarded.");
          if (typeof(curreg = $registration_db:find(email)) == LIST)
          additional_info = {"Current registration information for this email address:", @$registration_db:describe_registration(curreg)};
          else
          additional_info = {};
          endif
          $mail_agent:send_message(this, $registration_db.registrar, "Registration request", {((("Reregistration request from " + $string_utils:nn(who)) + " connected via ") + connection) + ":", "", (("@register " + who.name) + " ") + email, ("@new-password " + who.name) + " is ", "", "Reason this request was forwarded:", reason, @additional_info});
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>ctime</NAME>
        <CODE>
          ":ctime([INT time]) =&gt; STR as the function.";
          "May be hacked by players and player-classes to reflect differences in time-zone.";
          return ctime(@args);
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>@age</NAME>
        <CODE>
          if ((dobjstr == "") || (dobj == player))
          dobj = player;
          else
          dobj = $string_utils:match_player(dobjstr);
          if (!valid(dobj))
          $command_utils:player_match_failed(dobj, dobjstr);
          return;
          endif
          endif
          time = dobj.first_connect_time;
          if (time == $maxint)
          duration = time() - dobj.last_disconnect_time;
          if (duration &lt; 86400)
          notice = $string_utils:from_seconds(duration);
          else
          notice = $time_utils:english_time((duration / 86400) * 86400);
          endif
          player:notify(tostr(dobj.name, " has never connected.  It was created ", notice, " ago."));
          elseif (time == 0)
          player:notify(tostr(dobj.name, " first connected before initial connections were being recorded."));
          else
          player:notify(tostr(dobj.name, " first connected on ", ctime(time)));
          duration = time() - time;
          if (duration &lt; 86400)
          notice = $string_utils:from_seconds(duration);
          else
          notice = $time_utils:english_time((duration / 86400) * 86400);
          endif
          player:notify(tostr($string_utils:pronoun_sub("%S %&lt;is&gt; ", dobj), notice, " old."));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
        <NAME>news</NAME>
        <CODE>
          "Usage: news [contents] [articles]";
          "";
          "Common uses:";
          "news           -- display all current news, or as @mail-options decree";
          "news new       -- display articles you haven't seen yet";
          "news all       -- display all current news";
          "news contents  -- display headers of current news";
          "news &lt;article&gt; -- display article";
          "news archive   -- display news which has been marked as archived.";
          set_task_perms(player);
          cur = this:get_current_message($news) || {0, 0};
          arch = 0;
          if (((!args) &amp;&amp; (o = player:mail_option("news"))) &amp;&amp; (o != "all"))
          "no arguments, use the player's default";
          args = {o};
          elseif (args == {"all"})
          args = {};
          elseif (args == {"archive"})
          arch = 1;
          args = {};
          endif
          if (hdrs_only = args &amp;&amp; (args[1] == "contents"))
          "Do the mail contents list";
          args[1..1] = {};
          endif
          if (args)
          if (typeof(seq = $news:_parse(args, @cur)) == STR)
          player:notify(seq);
          return;
          elseif (seq = $seq_utils:intersection(seq, $news.current_news))
          else
          player:notify((args == {"new"}) ? "No new news." | "None of those are current articles.");
          return;
          endif
          elseif (arch &amp;&amp; (seq = $news.archive_news))
          "yduJ hates this coding style.  Just so you know.";
          elseif (seq = $news.current_news)
          else
          player:notify("No news");
          return;
          endif
          if (hdrs_only)
          $news:display_seq_headers(seq, @cur);
          else
          player:set_current_message($news, @$news:news_display_seq_full(seq));
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@edit</NAME>
        <CODE>
          "Calls the verb editor on verbs, the note editor on properties, and on anything else assumes it's an object for which you want to edit the .description.";
          if (!args)
          ((player in $note_editor.active) ? $note_editor | $verb_editor):invoke(dobjstr, verb);
          elseif ($code_utils:parse_verbref(args[1]))
          if (player.programmer)
          $verb_editor:invoke(argstr, verb);
          else
          player:notify("You need to be a programmer to do this.");
          player:notify("If you want to become a programmer, talk to a wizard.");
          return;
          endif
          else
          $note_editor:invoke(dobjstr, verb);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>erase_paranoid_data</NAME>
        <CODE>
          if (!($perm_utils:controls(caller_perms(), this) || (this == caller)))
          return E_PERM;
          else
          $paranoid_db:erase_data(this);
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@move-new</NAME>
        <CODE>
          "'@move &lt;object&gt; to &lt;place&gt;' - Teleport an object. Example: '@move trash to #11' to move trash to the closet.";
          set_task_perms((caller == this) ? this | $no_one);
          if ((prepstr != "to") || (!iobjstr))
          player:tell("Usage: @move &lt;object&gt; to &lt;location&gt;");
          return;
          endif
          if ((!dobjstr) || (dobjstr == "me"))
          dobj = this;
          else
          dobj = here:match_object(dobjstr);
          if (!valid(dobj))
          dobj = player:my_match_object(dobjstr);
          endif
          endif
          if ($command_utils:object_match_failed(dobj, dobjstr))
          return;
          endif
          iobj = this:lookup_room(iobjstr);
          if ((iobj != $nothing) &amp;&amp; $command_utils:object_match_failed(iobj, iobjstr))
          return;
          endif
          if (((!player.programmer) &amp;&amp; (!$perm_utils:controls(this, dobj))) &amp;&amp; (this != dobj))
          player:tell("You may only @move your own things.");
          return;
          endif
          this:teleport(dobj, iobj);
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>notify_lines_suspended</NAME>
        <CODE>
          if (($perm_utils:controls(caller_perms(), this) || (caller == this)) || (caller_perms() == this))
          set_task_perms(caller_perms());
          for line in ((typeof(lines = args[1]) != LIST) ? {lines} | lines)
          $command_utils:suspend_if_needed(0);
          this:notify(tostr(line));
          endfor
          else
          return E_PERM;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>_chparent</NAME>
        <CODE>
          set_task_perms(caller_perms());
          return chparent(@args);
        </CODE>
      </VERB>
      <VERB OWNER="obj36" PERMS="d x r" DOBJ="none" PREP="none" IOBJ="none">
        <NAME>@users</NAME>
        <CODE>
          "Prints a count and compact list of the currently-connected players.";
          cp = connected_players();
          linelen = abs(player.linelen) || 79;
          player:tell_lines({tostr("There are ", length(cp), " players connected:"), @$generic_editor:fill_string($string_utils:english_list($list_utils:sort_suspended(0, $list_utils:map_prop(cp, "name"))), linelen)});
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
        <NAME>@password</NAME>
        <CODE>
          if (typeof(player.password) != STR)
          if (length(args) != 1)
          return player:notify(tostr("Usage:  ", verb, " &lt;new-password&gt;"));
          else
          new_password = args[1];
          endif
          elseif (length(args) != 2)
          player:notify(tostr("Usage:  ", verb, " &lt;old-password&gt; &lt;new-password&gt;"));
          return;
          elseif (player.password != crypt(tostr(args[1]), player.password))
          player:notify("That's not your old password.");
          return;
          elseif (is_clear_property(player, "password"))
          player:notify("Your password has a `clear' property.  Please refer to a wizard for assistance in changing it.");
          return;
          else
          new_password = args[2];
          endif
          if (r = $password_verifier:reject_password(new_password, player))
          player:notify(r);
          return;
          endif
          player.password = crypt(tostr(new_password));
          player.last_password_time = time();
          player:notify("New password set.");
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>recycle</NAME>
        <CODE>
          if ((caller == this) || $perm_utils:controls(caller_perms(), this))
          pass(@args);
          features = this.features;
          "Have to do this, or :feature_remove thinks you're a liar and doesn't believe.";
          this.features = {};
          for x in (features)
          try
          x:feature_remove(this);
          except (ANY)
          "Ignore errors";
          endtry
          $command_utils:suspend_if_needed(0);
          endfor
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>gc_gaglist</NAME>
        <CODE>
          ((caller == this) || $perm_utils:controls(caller_perms(), this)) || raise(E_PERM);
          if (g = this.gaglist)
          recycler = $recycler;
          for o in (g)
          if (!recycler:valid(o))
          g = setremove(g, o);
          endif
          endfor
          this.gaglist = g;
          endif
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>email_address</NAME>
        <CODE>
          set_task_perms(caller_perms());
          return this.email_address;
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>set_email_address</NAME>
        <CODE>
          set_task_perms(caller_perms());
          this.email_address = args[1];
        </CODE>
      </VERB>
      <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
        <NAME>reconfunc</NAME>
        <CODE>
          if (((valid(cp = caller_perms()) &amp;&amp; (caller != this)) &amp;&amp; (!$perm_utils:controls(cp, this))) &amp;&amp; (caller != $sysobj))
          return E_PERM;
          endif
          return this:confunc(@args);
        </CODE>
      </VERB>
      <OBJECT ID="obj40" FLAGS="f r" OWNER="obj2" LOCATION="obj-1">
        <NAME>Generic Mail Receiving Player</NAME>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>_mail_task</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>messages_going</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>mail_lists</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>mail_notify</NAME>
          <VALUE>{{}, {}}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>mail_forward</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>mail_options</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>message_keep_date</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>messages_kept</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>current_message</NAME>
          <VALUE>{0, 0}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>messages</NAME>
          <VALUE>{}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>features</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" >
          <NAME>previous_connection</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" >
          <NAME>email_address</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>last_disconnect_time</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>help</NAME>
          <VALUE>#85</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>more_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>linetask</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>linesleft</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" >
          <NAME>linebuffer</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>pagelen</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>owned_objects</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>linelen</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>current_folder</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" >
          <NAME>all_connect_places</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" >
          <NAME>last_connect_place</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>dict</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>brief</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>lines</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>page_absent_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>pq</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>pqc</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>page_origin_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>page_echo_msg</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>edit_options</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>last_connect_time</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" >
          <NAME>ownership_quota</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>gender</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>prc</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>ppc</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>poc</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>psc</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>pr</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>pp</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>po</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>ps</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>home</NAME>
          <VALUE>#62</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" >
          <NAME>password</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>gaglist</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>paranoid</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>display_options</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>verb_subs</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>first_connect_time</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" >
          <NAME>size_quota</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" >
          <NAME>last_password_time</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" >
          <NAME>last_connect_attempt</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c">
          <NAME>key</NAME>
          <VALUE>0</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="r">
          <NAME>aliases</NAME>
          <VALUE>{"Generic Mail Receiving Player"}</VALUE>
        </PROPERTY>
        <PROPERTY OWNER="obj2" PERMS="c r">
          <NAME>description</NAME>
        </PROPERTY>
        <PROPERTY OWNER="obj36" PERMS="r">
          <NAME>object_size</NAME>
          <VALUE>{66628, 919123692}</VALUE>
        </PROPERTY>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>mail_forward</NAME>
          <CODE>
            if (typeof(mf = this.(verb)) == STR)
            return $string_utils:pronoun_sub(mf, @args);
            else
            return mf;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>receive_message</NAME>
          <CODE>
            ":receive_message(msg,from)";
            if ((!$perm_utils:controls(caller_perms(), this)) &amp;&amp; (caller != this))
            return E_PERM;
            endif
            if (this:mail_option("no_dupcc", args[1][1], args[1][2]))
            "pass to :mail_option the TEXT versions of who the message is from and to";
            recipients = setremove($mail_agent:parse_address_field(args[1][3]), this);
            for x in (recipients)
            if (this:get_current_message(x))
            return 0;
            endif
            endfor
            endif
            if (this:mail_option("netmail"))
            msg = args[1];
            message = {"Forwarded: " + msg[4], "Original-date: " + ctime(msg[1]), "Original-From: " + msg[2], "Original-To: " + msg[3], ((("Reply-To: " + $string_utils:substitute(args[2].name, {{"@", "%"}})) + "@") + $network.moo_name) + ".moo.mud.org"};
            for x in (msg[5..$])
            message = {@message, @$generic_editor:fill_string(x, this:linelen())};
            endfor
            if (this:send_self_netmail(message, @listdelete(args, 1)) == 0)
            return 0;
            endif
            endif
            set_task_perms(this.owner);
            new = this:new_message_num();
            ncur = (new &lt;= 1) ? 0 | min(this:current_message(this), new);
            this:set_current_message(this, ncur);
            new = max(new, ncur + 1);
            this.messages = {@this.messages, {new, args[1]}};
            "... new-mail notification is now done directly by $mail_agent:raw_send";
            "... see :notify_mail...";
            return new;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>display_message</NAME>
          <CODE>
            ":display_message(preamble,msg) --- prints msg to player.";
            vb = ((this._mail_task == task_id()) || (caller == $mail_editor)) ? "notify_lines_suspended" | "tell_lines_suspended";
            preamble = args[1];
            player:(vb)({@(typeof(preamble) == LIST) ? preamble | {preamble}, @args[2], "--------------------------"});
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>parse_message_seq from_msg_seq %from_msg_seq to_msg_seq %to_msg_seq subject_msg_seq body_msg_seq kept_msg_seq unkept_msg_seq display_seq_headers display_seq_full messages_in_seq list_rmm new_message_num length_num_le length_date_le length_date_gt length_all_msgs exists_num_eq msg_seq_to_msg_num_list msg_seq_to_msg_num_string rm_message_seq undo_rmm expunge_rmm renumber keep_message_seq</NAME>
          <CODE>
            "parse_message_seq(strings,cur)         =&gt; msg_seq";
            "messages_in_seq(msg_seq);              =&gt; text of messages in msg_seq";
            "display_seq_headers(msg_seq[,current]) :displays summary lines of those msgs";
            "rmm_message_seq(msg_seq)               =&gt; string giving msg numbers removed";
            "undo_rmm()    =&gt; msg_seq of restored messages";
            "expunge_rmm() =&gt; number of messages expunged";
            "list_rmm()    =&gt; number of messages awaiting expunge";
            "renumber(cur) =&gt; {number of messages in folder, new_cur}";
            "";
            "See the corresponding routines on $mail_agent.";
            if ((caller == $mail_agent) || $perm_utils:controls(caller_perms(), this))
            set_task_perms(this.owner);
            return $mail_agent:(verb)(@args);
            else
            return E_PERM;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj36" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>msg_summary_line</NAME>
          <CODE>
            return $mail_agent:msg_summary_line(@args);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>msg_text</NAME>
          <CODE>
            ":msg_text(@msg) =&gt; list of strings.";
            "msg is a mail message (in the usual transmission format) being read BY this player.";
            "The default version of recipient:msg_full_text calls this to obtain the actual list of strings to display.  (this is a badly named verb).";
            "returns the actual list of strings to display.";
            return $mail_agent:to_text(@args);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>notify_mail</NAME>
          <CODE>
            ":notify_mail(from,recipients[,msgnums])";
            " used by $mail_agent:raw_send to notify this player about mail being sent";
            " from &lt;from&gt; to &lt;recipients&gt;.  &lt;msgnums&gt; if given gives the message number(s) assigned (in the event that the corresponding recipient actually kept the mail)";
            if (!$object_utils:connected(this))
            return;
            elseif (!((caller in {this, $mail_agent}) || $perm_utils:controls(caller_perms(), this)))
            return E_PERM;
            else
            {from, recipients, ?msgnums = {}} = args;
            from_name = $mail_agent:name(from);
            "... msgnums may be shorter than recipients or may have some slots filled";
            "... with 0's if msg numbers are not available for some recipients.";
            if ((t = this in recipients) &amp;&amp; ((length(msgnums) &gt;= t) &amp;&amp; msgnums[t]))
            "... you are getting the mail and moreover your :receive_message kept it.";
            namelist = $string_utils:english_list($list_utils:map_arg($mail_agent, "name", setremove(recipients, this)), "");
            this:notify(tostr("You have new mail (", msgnums[t], ") from ", from_name, namelist ? " which was also sent to " + namelist | "", "."));
            if (!this:mail_option("expert"))
            this:notify(tostr("Type `help mail' for info on reading it."));
            endif
            else
            "... vanilla notification; somebody got sent mail and you're finding out.";
            namelist = $string_utils:english_list({@t ? {"You"} | {}, @$list_utils:map_arg($mail_agent, "name", setremove(recipients, this))}, "");
            this:tell(tostr(namelist, (length(recipients) == 1) ? " has" | " have", " just been sent new mail by ", from_name, "."));
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>current_message</NAME>
          <CODE>
            ":current_message([recipient])";
            " =&gt; current message number for the given recipient (defaults to this).";
            " =&gt; 0 if we have no record of that recipient";
            "      or current message happens to be 0.";
            "This verb is mostly obsolete; consider using :get_current_message()";
            if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
            raise(E_PERM);
            elseif ((!args) || (args[1] == this))
            return this.current_message[1];
            elseif (a = $list_utils:assoc(args[1], this.current_message))
            return a[2];
            else
            return 0;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>get_current_message</NAME>
          <CODE>
            ":get_current_message([recipient])";
            " =&gt; {msg_num, last_read_date} for the given recipient.";
            " =&gt; 0 if we have no record of that recipient.";
            if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
            raise(E_PERM);
            elseif ((!args) || (args[1] == this))
            if (length(this.current_message) &lt; 2)
            "Whoops, this got trashed---fix it up!";
            this.current_message = {0, time(), @this.current_message};
            endif
            return this.current_message[1..2];
            elseif (a = $list_utils:assoc(args[1], this.current_message))
            return a[2..3];
            else
            return 0;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_current_message</NAME>
          <CODE>
            ":set_current_message(recipient[,number[,date]])";
            "Returns the new {number,last-read-date} pair for recipient.";
            if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
            raise(E_PERM);
            endif
            {recip, ?number = E_NONE, ?date = 0} = args;
            cm = this.current_message;
            if (recip == this)
            this.current_message[2] = max(date, cm[2]);
            if (number != E_NONE)
            this.current_message[1] = number;
            endif
            return this.current_message[1..2];
            elseif (i = $list_utils:iassoc(recip, cm))
            return (this.current_message[i] = {recip, (number == E_NONE) ? cm[i][2] | number, max(date, cm[i][3])})[2..3];
            else
            entry = {recip, (number != E_NONE) &amp;&amp; number, date};
            this.current_message = {@cm, entry};
            return entry[2..3];
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>make_current_message</NAME>
          <CODE>
            ":make_current_message(recipient[,index])";
            "starts a new current_message record for recipient.";
            "index, if given, indicates where recipient is to be";
            "  placed (n = at or after nth entry in .current_message).";
            recip = args[1];
            cm = this.current_message;
            if (length(args) &gt; 1)
            i = max(2, min(args[2], length(cm)));
            else
            i = 0;
            endif
            if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
            raise(E_PERM);
            elseif (recip == this)
            "...self...";
            elseif (j = $list_utils:iassoc(recip, cm))
            "...already present...";
            if (i)
            if (j &lt; i)
            this.current_message = {@cm[1..j - 1], @cm[j + 1..i], cm[j], @cm[i + 1..$]};
            elseif (j &gt; (i + 1))
            this.current_message = {@cm[1..i], cm[j], @cm[i + 1..j - 1], @cm[j + 1..$]};
            endif
            endif
            else
            this.current_message = listappend(cm, {recip, 0, 0}, @i ? {i} | {});
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>kill_current_message</NAME>
          <CODE>
            ":kill_current_message(recipient)";
            "entirely forgets current message for this recipient...";
            "Returns true iff successful.";
            if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
            raise(E_PERM);
            else
            return ((recip = args[1]) != this) &amp;&amp; ((i = $list_utils:iassoc(recip, cm = this.current_message)) &amp;&amp; (this.current_message = listdelete(cm, i)));
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>current_folder</NAME>
          <CODE>
            ":current_folder() =&gt; default folder to use, always an object, usually `this'";
            set_task_perms(caller_perms());
            return ((!this:mail_option("sticky")) || this.current_folder) &amp;&amp; this;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>set_current_folder</NAME>
          <CODE>
            set_task_perms(caller_perms());
            return this.current_folder = args[1];
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>parse_folder_spec</NAME>
          <CODE>
            ":parse_folder_spec(verb,args,expected_preposition[,allow_trailing_args_p])";
            " =&gt; {folder, msg_seq_args, trailing_args}";
            set_task_perms(caller_perms());
            folder = this:current_folder();
            if (!prepstr)
            return {folder, args[2], {}};
            endif
            {verb, args, prep, ?extra = 0} = args;
            p = prepstr in args;
            if (prepstr != prep)
            "...unexpected preposition...";
            if (extra &amp;&amp; (!index(prepstr, " ")))
            return {folder, args[1..p - 1], args[p..$]};
            else
            player:tell("Usage:  ", verb, " [&lt;message numbers&gt;] [", prep, " &lt;folder/list-name&gt;]");
            endif
            elseif (!((p &lt; length(args)) &amp;&amp; (fname = args[p + 1])))
            "...preposition but no iobj...";
            player:tell(verb, " ", $string_utils:from_list(args, " "), " WHAT?");
            elseif ($mail_agent:match_failed(folder = $mail_agent:match_recipient(fname, this), fname))
            "...bogus mail folder...";
            else
            return {folder, args[1..p - 1], args[p + 2..$]};
            endif
            return 0;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>parse_mailread_cmd</NAME>
          <CODE>
            ":parse_mailread_cmd(verb,args,default,prep[,trailer])";
            "  handles anything of the form  `VERB message_seq [PREP folder ...]'";
            "    default is the default msg-seq to use if none given";
            "    prep is the expected prepstr (assumes prepstr is set), usually `on'";
            "    trailer, if present and true, indicates trailing args are permitted.";
            "  returns {recipient object, message_seq, current_msg,\"...\"} or 0";
            set_task_perms(caller_perms());
            if (!(pfs = this:parse_folder_spec(@listdelete(args, 3))))
            return 0;
            endif
            {verb, args, default, prep, ?extra = 0} = args;
            folder = pfs[1];
            cur = this:get_current_message(folder) || {0};
            if (typeof(pms = folder:parse_message_seq(pfs[2], @cur)) == LIST)
            rest = {@listdelete(pms, 1), @pfs[3]};
            if ((!extra) &amp;&amp; rest)
            "...everything should have been gobbled by :parse_message_seq...";
            player:tell("I don't understand `", rest[1], "'");
            return 0;
            elseif (pms[1])
            "...we have a nonempty message sequence...";
            return {folder, pms[1], cur, rest};
            elseif (used = (length(pfs[2]) + 1) - length(pms))
            "...:parse_message_seq used some words, but didn't get anything out of it";
            pms = ("%f %&lt;has&gt; no `" + $string_utils:from_list(pfs[2][1..used], " ")) + "' messages.";
            elseif (typeof(pms = folder:parse_message_seq(default, @cur)) == LIST)
            "...:parse_message_seq used nothing, try the default; wow it worked";
            return {folder, pms[1], cur, rest};
            endif
            elseif (typeof(pms) == ERR)
            player:tell($mail_agent:name(folder), " is not readable by you.");
            if (!$object_utils:isa(folder, $mail_recipient))
            player:tell("Use * to indicate a non-player mail recipient.");
            endif
            return 0;
            endif
            if (folder == this)
            subst = {{"%f's", "Your"}, {"%f", "You"}, {"%&lt;has&gt;", "have"}};
            elseif (is_player(folder))
            subst = {{"%f", folder.name}, {"%&lt;has&gt;", $gender_utils:get_conj("has", folder)}};
            else
            subst = {{"%f", $mail_agent:name(folder)}, {"%&lt;has&gt;", "has"}};
            endif
            player:tell($string_utils:substitute(pms, {@subst, {"%%", "%"}}));
            return 0;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@mail</NAME>
          <CODE>
            "@mail &lt;msg-sequence&gt;                --- as in help @mail";
            "@mail &lt;msg-sequence&gt; on &lt;recipient&gt; --- shows mail on mailing list or player.";
            set_task_perms(valid(cp = caller_perms()) ? cp | player);
            if (p = this:parse_mailread_cmd("@mail", args, this:mail_option("@mail") || $mail_agent.("player_default_@mail"), "on"))
            this:set_current_folder(folder = p[1]);
            msg_seq = p[2];
            seq_size = $seq_utils:size(msg_seq);
            if ((lim = player:mail_option("manymsgs")) &amp;&amp; ((lim &lt;= seq_size) &amp;&amp; (!$command_utils:yes_or_no(tostr("You are about to see ", seq_size, " message headers.  Continue?")))))
            player:notify(tostr("Aborted.  @mailoption manymsgs=", lim));
            return;
            endif
            if (1 != seq_size)
            player:notify(tostr(seq_size, " messages", (folder == this) ? "" | (" on " + $mail_agent:name(folder)), ":"));
            endif
            folder:display_seq_headers(msg_seq, @p[3]);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@read @peek</NAME>
          <CODE>
            "@read &lt;msg&gt;...                  -- as in help @read";
            "@read &lt;msg&gt;... on *&lt;recipient&gt;  -- reads messages on recipient.";
            "@peek ...                       -- like @read, but don't set current message";
            set_task_perms(valid(cp = caller_perms()) ? cp | player);
            if (p = this:parse_mailread_cmd("@read", args, "", "on"))
            this:set_current_folder(folder = p[1]);
            msg_seq = p[2];
            if ((lim = player:mail_option("manymsgs")) &amp;&amp; ((lim &lt;= (seq_size = $seq_utils:size(msg_seq))) &amp;&amp; (!$command_utils:yes_or_no(tostr("You are about to see ", seq_size, " messages.  Continue?")))))
            player:notify(tostr("Aborted.  @mailoption manymsgs=", lim));
            return;
            endif
            this._mail_task = task_id();
            if (cur = folder:display_seq_full(msg_seq, tostr("Message %d", (folder == this) ? "" | (" on " + $mail_agent:name(folder)), ":")))
            if (verb != "@peek")
            this:set_current_message(folder, @cur);
            endif
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@next @prev</NAME>
          <CODE>
            set_task_perms(player.owner);
            if (dobjstr &amp;&amp; (!(n = toint(dobjstr))))
            player:notify(tostr("Usage:  ", verb, "[&lt;number&gt;] [on &lt;recipient&gt;]"));
            elseif (dobjstr)
            this:("@read")(tostr(verb[2..5], n), @listdelete(args, 1));
            else
            this:("@read")(verb[2..5], @args);
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@rmm*ail</NAME>
          <CODE>
            "@rmm &lt;message-sequence&gt; [from &lt;recipient&gt;].   Use @unrmm if you screw up.";
            " Beware, though.  @unrmm can only undo the most recent @rmm.";
            set_task_perms(player);
            if (!(p = this:parse_mailread_cmd("@rmm", args, "cur", "from")))
            "...parse failed, we've already complained...";
            elseif ((!prepstr) &amp;&amp; ((p[1] != this) &amp;&amp; (!$command_utils:yes_or_no(("@rmmail from " + $mail_agent:name(p[1])) + ".  Continue?"))))
            "...wasn't the folder player was expecting...";
            player:notify("@rmmail aborted.");
            else
            this:set_current_folder(folder = p[1]);
            e = folder:rm_message_seq(p[2]);
            if (typeof(e) == ERR)
            player:notify(tostr($mail_agent:name(folder), ":  ", e));
            else
            count = ((n = $seq_utils:size(p[2])) == 1) ? "." | tostr(" (", n, " messages).");
            fname = (folder == this) ? "" | (" from " + $mail_agent:name(folder));
            player:notify(tostr("Deleted ", e, fname, count));
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="none" IOBJ="none">
          <NAME>@renumber</NAME>
          <CODE>
            set_task_perms(player);
            if (!dobjstr)
            folder = this:current_folder();
            elseif ($mail_agent:match_failed(folder = $mail_agent:match_recipient(dobjstr), dobjstr))
            return;
            endif
            cur = this:current_message(folder);
            fname = $mail_agent:name(folder);
            if (typeof(h = folder:renumber(cur)) == ERR)
            player:notify(tostr(h));
            else
            if (!h[1])
            player:notify(tostr("No messages on ", fname, "."));
            else
            player:notify(tostr("Messages on ", fname, " renumbered 1-", h[1], "."));
            this:set_current_folder(folder);
            if (h[2] &amp;&amp; this:set_current_message(folder, h[2]))
            player:notify(tostr("Current message is now ", h[2], "."));
            endif
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@unrmm*ail</NAME>
          <CODE>
            "@unrmm [on &lt;recipient&gt;]  -- undoes the previous @rmm on that recipient.";
            set_task_perms(player);
            if (!(p = this:parse_folder_spec("@unrmm", args, "on")))
            return;
            endif
            dobjstr = $string_utils:from_list(p[2], " ");
            keep = 0;
            if ((!dobjstr) || (keep = index("keep", dobjstr) == 1))
            do = "undo_rmm";
            elseif (index("expunge", dobjstr) == 1)
            do = "expunge_rmm";
            elseif (index("list", dobjstr) == 1)
            do = "list_rmm";
            else
            player:notify(tostr("Usage:  ", verb, " [expunge|list] [on &lt;recipient&gt;]"));
            return;
            endif
            this:set_current_folder(folder = p[1]);
            if (msg_seq = folder:(do)(@keep ? {keep} | {}))
            if (do == "undo_rmm")
            player:notify(tostr($seq_utils:size(msg_seq), " messages restored to ", $mail_agent:name(folder), "."));
            folder:display_seq_headers(msg_seq, 0);
            else
            player:notify(tostr(msg_seq, " zombie message", (msg_seq == 1) ? " " | "s ", (do == "expunge_rmm") ? "expunged from " | "on ", $mail_agent:name(folder), "."));
            endif
            elseif (typeof(msg_seq) == ERR)
            player:notify(tostr($mail_agent:name(folder), ":  ", msg_seq));
            else
            player:notify(tostr("No messages to ", (do == "expunge_rmm") ? "expunge from " | "restore to ", $mail_agent:name(folder)));
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@send</NAME>
          <CODE>
            if (args &amp;&amp; (args[1] == "to"))
            args = listdelete(args, 1);
            endif
            subject = {};
            for a in (args)
            if (((i = index(a, "=")) &gt; 3) &amp;&amp; (index("subject", a[1..i - 1]) == 1))
            args = setremove(args, a);
            a[1..i] = "";
            subject = {a};
            endif
            endfor
            $mail_editor:invoke(args, verb, @subject);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@answer @repl*y</NAME>
          <CODE>
            "@answer &lt;msg&gt; [on *&lt;recipient&gt;] [&lt;flags&gt;...]";
            set_task_perms(who = valid(caller_perms()) ? caller_perms() | player);
            if (p = this:parse_mailread_cmd(verb, args, "cur", "on", 1))
            if ($seq_utils:size(p[2]) != 1)
            player:notify("You can only answer *one* message at a time.");
            elseif (LIST != typeof(flags_replytos = $mail_editor:check_answer_flags(@p[4])))
            player:notify_lines({tostr("Usage:  ", verb, " [message-# [on &lt;recipient&gt;]] [flags...]"), "where flags include any of:", "  all        reply to everyone", "  sender     reply to sender only", "  include    include the original message in your reply", "  noinclude  don't include the original in your reply"});
            else
            this:set_current_folder(p[1]);
            $mail_editor:invoke(2, verb, p[1]:messages_in_seq(p[2])[1][2], @flags_replytos);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@forward</NAME>
          <CODE>
            "@forward &lt;msg&gt; [on *&lt;recipient&gt;] to &lt;recipient&gt; [&lt;recipient&gt;...]";
            set_task_perms(valid(cp = caller_perms()) ? cp | player);
            if (!(p = this:parse_mailread_cmd(verb, args, "", "on", 1)))
            "...lose...";
            return;
            elseif ($seq_utils:size(sequence = p[2]) != 1)
            player:notify("You can only forward *one* message at a time.");
            return;
            elseif ((length(p[4]) &lt; 2) || (p[4][1] != "to"))
            player:notify(tostr("Usage:  ", verb, " [&lt;message&gt;] [on &lt;folder&gt;] to &lt;recip&gt;..."));
            return;
            endif
            recips = {};
            for rs in (listdelete(p[4], 1))
            if ($mail_agent:match_failed(r = $mail_agent:match_recipient(rs), rs))
            return;
            endif
            recips = {@recips, r};
            endfor
            this:set_current_folder(folder = p[1]);
            m = folder:messages_in_seq(sequence)[1];
            msgnum = m[1];
            msgtxt = m[2];
            from = msgtxt[2];
            if (msgtxt[4] != " ")
            subject = tostr("[", from, ":  ", msgtxt[4], "]");
            elseif ((h = "" in msgtxt) &amp;&amp; (h &lt; length(msgtxt)))
            subject = tostr("[", from, ":  `", msgtxt[h + 1][1..min(20, $)], "']");
            else
            subject = tostr("[", from, "]");
            endif
            result = $mail_agent:send_message(player, recips, subject, $mail_agent:to_text(@msgtxt));
            if (!result)
            player:notify(tostr(result));
            elseif (result[1])
            player:notify(tostr("Message ", msgnum, @(folder == this) ? {} | {" on ", $mail_agent:name(folder)}, " @forwarded to ", $mail_agent:name_list(@listdelete(result, 1)), "."));
            else
            player:notify("Message not sent.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@gripe</NAME>
          <CODE>
            $mail_editor:invoke($gripe_recipients, "@gripe", "@gripe: " + argstr);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@typo @bug @suggest*ion @idea @comment</NAME>
          <CODE>
            subject = tostr($string_utils:capitalize(verb[2..$]), ":  ", (loc = this.location).name, "(", loc, ")");
            if (this != player)
            return E_PERM;
            elseif (argstr)
            result = $mail_agent:send_message(this, {loc.owner}, subject, argstr);
            if (result &amp;&amp; result[1])
            player:notify(tostr("Your ", verb, " sent to ", $mail_agent:name_list(@listdelete(result, 1)), ".  Input is appreciated, as always."));
            else
            player:notify(tostr("Huh?  This room's owner (", loc.owner, ") is invalid?  Tell a wizard..."));
            endif
            return;
            elseif (!($object_utils:isa(loc, $room) &amp;&amp; loc.free_entry))
            player:notify_lines({tostr("You need to make it a one-liner, i.e., `", verb, " something or other'."), "This room may not let you back in if you go to the Mail Room."});
            elseif ($object_utils:isa(loc, $generic_editor))
            player:notify_lines({tostr("You need to make it a one-liner, i.e., `", verb, " something or other'."), "Sending you to the Mail Room from an editor is usually a bad idea."});
            else
            $mail_editor:invoke({tostr(loc.owner)}, verb, subject);
            endif
            if (verb == "@bug")
            player:notify("For a @bug report, be sure to mention exactly what it was you typed to trigger the error...");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@skip</NAME>
          <CODE>
            "@skip [*&lt;folder/mailing_list&gt;...]";
            "  sets your last-read time for the given lists to now, indicating your";
            "  disinterest in any new messages that might have appeared recently.";
            set_task_perms(player);
            current_folder = this:current_folder();
            for a in (args || {0})
            if (a ? $mail_agent:match_failed(folder = $mail_agent:match_recipient(a), a) | (folder = this:current_folder()))
            "...bogus folder name, done...  No, try anyway.";
            if (this:kill_current_message(this:my_match_object(a)))
            player:notify("Invalid folder, but found it subscribed anyway.  Removed.");
            endif
            else
            lseq = folder:length_all_msgs();
            unread = (n = this:get_current_message(folder)) ? folder:length_date_gt(n[2]) | lseq;
            this:set_current_message(folder, lseq &amp;&amp; folder:messages_in_seq({lseq, lseq + 1})[1][1], time());
            player:notify(tostr(unread ? tostr("Ignoring ", unread) | "No", " unread message", (unread != 1) ? "s" | "", " on ", $mail_agent:name(folder)));
            if (current_folder == folder)
            this:set_current_folder(this);
            endif
            endif
            endfor
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@subscribe*-quick @unsubscribed*-quick</NAME>
          <CODE>
            "@subscribe *&lt;folder/mailing_list&gt; [with notification] [before|after *&lt;folder&gt;]";
            "  causes you to be notified when new mail arrives on this list";
            "@subscribe";
            "  just lists available mailing lists.";
            "@unsubscribed";
            "  prints out available mailing lists you aren't already subscribed to.";
            "@subscribe-quick and @unsubscribed-quick";
            "  prints out same as above except without mail list descriptions, just names.";
            set_task_perms(player);
            quick = 0;
            if (qi = index(verb, "-q"))
            verb = verb[1..qi - 1];
            quick = 1;
            endif
            fname = {@args, 0}[1];
            if (!fname)
            ml = $list_utils:slice(this.current_message[3..$]);
            all_mlists = {@$mail_agent.contents, @this.mail_lists};
            if ((length(all_mlists) &gt; 50) &amp;&amp; (!$command_utils:yes_or_no(tostr("There are ", length(all_mlists), " mailing lists.  Are you sure you want the whole list?"))))
            return player:tell("OK, aborting.");
            endif
            for c in (all_mlists)
            $command_utils:suspend_if_needed(0);
            if ((c:is_usable_by(this) || c:is_readable_by(this)) &amp;&amp; ((verb != "@unsubscribed") || (!(c in ml))))
            c:look_self(quick);
            endif
            endfor
            player:notify(tostr("-------- end of ", verb, " -------"));
            return;
            elseif (verb == "@unsubscribed")
            player:notify("@unsubscribed does not take arguments.");
            return;
            elseif ($mail_agent:match_failed(folder = $mail_agent:match_recipient(fname), fname))
            return;
            elseif (folder == this)
            player:notify("You don't need to @subscribe to yourself");
            return;
            elseif ($object_utils:isa(folder, $mail_recipient) ? !folder:is_readable_by(this) | (!$perm_utils:controls(this, folder)))
            player:notify("That mailing list is not readable by you.");
            return;
            endif
            notification = this in folder.mail_notify;
            i = 0;
            beforeafter = 0;
            while (length(args) &gt;= 2)
            if (length(args) &lt; 3)
            player:notify(args[2] + " what?");
            return;
            elseif (args[2] in {"with", "without"})
            with = args[2] == "with";
            if (index("notification", args[3]) != 1)
            player:notify(tostr("with ", args[3], "?"));
            return;
            elseif (!$object_utils:isa(folder, $mail_recipient))
            player:notify(tostr("You cannot use ", verb, " to change mail notification from a non-$mail_recipient."));
            elseif ((!with) == (!notification))
            "... nothing to do...";
            elseif (with)
            if (this in folder:add_notify(this))
            notification = 1;
            else
            player:notify("This mail recipient does not allow immediate notification.");
            endif
            else
            folder:delete_notify(this);
            notification = 0;
            endif
            elseif (args[2] in {"before", "after"})
            if (beforeafter)
            player:notify((args[2] == beforeafter) ? tostr("two `", beforeafter, "'s?") | "Only use one of `before' or `after'");
            return;
            elseif ($mail_agent:match_failed(other = $mail_agent:match_recipient(args[3]), args[3]))
            return;
            elseif (other == this)
            i = 2;
            elseif (!(i = $list_utils:iassoc(other, this.current_message)))
            player:notify(tostr("You aren't subscribed to ", $mail_agent:name(other), "."));
            return;
            endif
            beforeafter = args[2];
            i = i - (beforeafter == "before");
            if (this:mail_option("rn_order") != "fixed")
            player:notify("Warning:  Do `@mail-option rn_order=fixed' if you do not want your @rn listing reordered when you next login.");
            endif
            endif
            args[2..3] = {};
            endwhile
            this:make_current_message(folder, @i ? {i} | {});
            len = folder:length_all_msgs();
            player:notify(tostr($mail_agent:name(folder), " has ", len, " message", (len == 1) ? "" | "s", ".", notification ? "  You will be notified immediately when new messages are posted." | "  Notification of new messages will be printed when you connect."));
            this:set_current_folder(folder);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>mail_catch_up</NAME>
          <CODE>
            set_task_perms((caller == this) ? this.owner | caller_perms());
            this:set_current_folder(this);
            dates = new_cm = head = {};
            sort = this:mail_option("rn_order") || "read";
            for n in (this.current_message)
            $command_utils:suspend_if_needed(0);
            if (typeof(n) != LIST)
            head = {@head, n};
            elseif ($object_utils:isa(folder = n[1], $mail_recipient) &amp;&amp; folder:is_readable_by(this))
            "...set current msg to be the last one you could possibly have read.";
            if (n[3] &lt; folder.last_msg_date)
            i = folder:length_date_le(n[3]);
            n[2] = i &amp;&amp; folder:messages_in_seq(i)[1];
            endif
            if (sort == "fixed")
            new_cm = {n, @new_cm};
            elseif (sort == "send")
            j = $list_utils:find_insert(dates, folder.last_msg_date - 1);
            dates = listinsert(dates, folder.last_msg_date, j);
            new_cm = listinsert(new_cm, n, j);
            else
            new_cm = listappend(new_cm, n, $list_utils:iassoc_sorted(n[3] - 1, new_cm, 3));
            endif
            endif
            endfor
            this.current_message = {@head, @$list_utils:reverse(new_cm)};
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="none" PREP="none" IOBJ="none">
          <NAME>@rn check_mail_lists @subscribed @rn-full</NAME>
          <CODE>
            set_task_perms((caller == this) ? this.owner | caller_perms());
            which = {};
            cm = this.current_message;
            cm[1..2] = ((verb == "@rn") || (verb == "@rn-full")) ? {{this, @cm[1..2]}} | {};
            all = verb == "@subscribed";
            fast = this:mail_option("fast_check") &amp;&amp; (verb != "@rn-full");
            for n in (cm)
            rcpt = n[1];
            if (rcpt == $news)
            "... $news is handled separately ...";
            elseif ($mail_agent:is_recipient(rcpt))
            if (fast)
            if (rcpt == this)
            nmsgs = ((m = this.messages) &amp;&amp; (m[length(m)][2][1] &gt; n[3])) ? $maxint | 0;
            else
            try
            nmsgs = (n[1].last_msg_date &gt; n[3]) ? $maxint | 0;
            except (E_PERM, E_PROPNF)
            player:notify(tostr("Bogus recipient ", rcpt, " removed from .current_message."));
            this.current_message = setremove(this.current_message, n);
            nmsgs = 0;
            endtry
            endif
            else
            nmsgs = n[1]:length_date_gt(n[3]);
            endif
            if (nmsgs || all)
            which = {@which, {n[1], nmsgs}};
            endif
            else
            player:notify(tostr("Bogus recipient ", rcpt, " removed from .current_message."));
            this.current_message = setremove(this.current_message, n);
            endif
            $command_utils:suspend_if_needed(0);
            endfor
            if (which)
            player:notify(tostr((verb == "@subscribed") ? "You are subscribed to the following" | "There is new activity on the following", (length(which) &gt; 1) ? " lists:" | " list:"));
            for w in (which)
            name = (w[1] == this) ? " me" | $mail_agent:name(w[1]);
            player:notify(tostr($string_utils:left("    " + name, 40), " ", (w[2] == $maxint) ? "has" | w[2], " new message", (w[2] == 1) ? "" | "s"));
            $command_utils:suspend_if_needed(0);
            endfor
            if (verb != "check_mail_lists")
            player:notify("-- End of listing");
            endif
            elseif ((verb == "@rn") || (verb == "@rn-full"))
            player:notify("No new activity on any of your lists.");
            elseif (verb == "@subscribed")
            player:notify("You aren't subscribed to any mailing lists.");
            endif
            return which;
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>mail_option</NAME>
          <CODE>
            ":mail_option(name)";
            "Returns the value of the specified mail option";
            if ((caller in {this, $mail_editor, $mail_agent}) || $perm_utils:controls(caller_perms(), this))
            return $mail_options:get(this.mail_options, args[1]);
            else
            return E_PERM;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@unsub*scribe</NAME>
          <CODE>
            "@unsubscribe [*&lt;folder/mailing_list&gt; ...]";
            "entirely removes the record of your current message for the named folders,";
            "indicating your disinterest in anything that might appear there in the future.";
            set_task_perms(player);
            unsubscribed = {};
            current_folder = this:current_folder();
            for a in (args || {0})
            if (a != 0)
            folder = $mail_agent:match_recipient(a);
            if (folder == $failed_match)
            folder = this:my_match_object(a);
            endif
            else
            folder = current_folder;
            endif
            if (!valid(folder))
            "...bogus folder name...  try removing it anyway.";
            if (this:kill_current_message(folder))
            player:notify("Invalid folder, but found it subscribed anyway.  Removed.");
            else
            $mail_agent:match_failed(folder, a);
            endif
            elseif (folder == this)
            player:notify(tostr("You can't ", verb, " yourself."));
            else
            if (!this:kill_current_message(folder))
            player:notify(tostr("You weren't subscribed to ", $mail_agent:name(folder)));
            if ($object_utils:isa(folder, $mail_recipient))
            result = folder:delete_notify(this);
            if ((typeof(result) == LIST) &amp;&amp; (result[1] == this))
            player:notify("Removed you from the mail notifications list.");
            endif
            endif
            else
            unsubscribed = {@unsubscribed, folder};
            if ($object_utils:isa(folder, $mail_recipient))
            folder:delete_notify(this);
            endif
            endif
            endif
            endfor
            if (unsubscribed)
            player:notify(tostr("Forgetting about ", $string_utils:english_list($list_utils:map_arg($mail_agent, "name", unsubscribed))));
            if (current_folder in unsubscribed)
            this:set_current_folder(this);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>send_self_netmail</NAME>
          <CODE>
            ":send_self_netmail(msg [ ,from ])";
            "return 0 if successful, otherwise error.";
            if (!$perm_utils:controls(caller_perms(), this))
            return E_PERM;
            elseif (error = $network:invalid_email_address($wiz_utils:get_email_address(this)))
            return "Invalid email address: " + error;
            else
            msg = args[1];
            if (length(args) &gt; 1)
            from = args[2];
            this:notify(tostr("Receiving mail from ", from:title(), " (", from, ") and forwarding it to your .email_address."));
            endif
            oplayer = player;
            player = this;
            error = $network:sendmail($wiz_utils:get_email_address(this), @msg);
            if (error &amp;&amp; (length(args) &gt; 1))
            this:notify(tostr("Mail sending failed: ", error));
            endif
            player = oplayer;
            return error;
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@netforw*ard</NAME>
          <CODE>
            "@netforward &lt;msg&gt;...                  -- as in help on @netforward";
            "@netforward &lt;msg&gt;... on *&lt;recipient&gt;  -- netforwards messages on recipient.";
            "This command forwards mail-messages to your registered email-address.";
            if (player != this)
            return player:tell(E_PERM);
            endif
            if (reason = $network:email_will_fail(email = $wiz_utils:get_email_address(player)))
            return player:notify(tostr("Cannot forward mail to your email address: ", reason));
            endif
            set_task_perms(valid(cp = caller_perms()) ? cp | player);
            if (p = player:parse_mailread_cmd(verb, args, "", "on"))
            player:set_current_folder(folder = p[1]);
            msg_seq = p[2];
            folderstr = (folder == player) ? "" | tostr(" from ", $mail_agent:name(folder));
            if ((!this:mail_option("expert_netfwd")) &amp;&amp; (!$command_utils:yes_or_no(tostr("You are about to forward ", seq_size = $seq_utils:size(msg_seq), " message(s)", folderstr, " to your registered email-address, ", email, ".  Continue?"))))
            player:notify(tostr("@Netforward cancelled."));
            return;
            endif
            player:notify("Attempting to send network mail...");
            player._mail_task = task_id();
            multiple_vals = this:format_for_netforward(folder:messages_in_seq(msg_seq), folderstr);
            netmail = multiple_vals[1];
            header = multiple_vals[2];
            reason = player:send_self_netmail({header, @netmail});
            player:notify((reason == 0) ? tostr("@netforward of ", header, " completed.") | tostr("@netforward failed: ", reason, "."));
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@@sendmail</NAME>
          <CODE>
            "Syntax: @@sendmail";
            "This is intended for use with client editors.  You probably don't want to try using this command manually.";
            "Reads a formatted mail message, extracts recipients, subject line and/or reply-to header and sends message without going to the mailroom.  Example:";
            "";
            "@@send";
            "To: Rog (#4292)";
            "Subject: random";
            "";
            "first line";
            "second line";
            ".";
            "";
            "Currently, header lines must have the same format as in an actual message.";
            set_task_perms(player);
            if (args)
            player:notify(tostr("The ", verb, " command takes no arguments."));
            $command_utils:read_lines();
            return;
            elseif (this != player)
            player:notify(tostr("You can't use ", this.pp, " ", verb, " verb."));
            $command_utils:read_lines();
            return;
            endif
            msg = $command_utils:read_lines();
            end_head = ("" in msg) || (length(msg) + 1);
            from = this;
            subject = "";
            replyto = "";
            rcpts = {};
            body = msg[end_head + 1..$];
            for i in [1..end_head - 1]
            line = msg[i];
            if (index(line, "Subject:") == 1)
            subject = $string_utils:trim(line[9..$]);
            elseif (index(line, "To:") == 1)
            if (!(rcpts = $mail_agent:parse_address_field(line)))
            player:notify("No recipients found in To: line");
            return;
            endif
            elseif (index(line, "Reply-to:") == 1)
            if ((!(replyto = $mail_agent:parse_address_field(line))) &amp;&amp; $string_utils:trim(line[10..$]))
            player:notify("No address found in Reply-to: line");
            return;
            endif
            elseif (index(line, "From:") == 1)
            "... :send_message() bombs if designated sender != player ...";
            if (!(from = $mail_agent:parse_address_field(line)))
            player:notify("No sender found in From: line");
            return;
            elseif (length(from) &gt; 1)
            player:notify("Multiple senders?");
            return;
            endif
            from = from[1];
            elseif (i = index(line, ":"))
            player:notify(tostr("Unknown header \"", line[1..i], "\""));
            return;
            else
            player:notify("Blank line must separate headers from body.");
            return;
            endif
            endfor
            if (!rcpts)
            player:notify("No To: line found.");
            elseif (!(subject || body))
            player:notify("Blank message not sent.");
            else
            player:notify("Sending...");
            result = $mail_agent:send_message(from, rcpts, replyto ? subject | {subject, replyto}, body);
            if (e = result &amp;&amp; result[1])
            if (length(result) == 1)
            player:notify("Mail actually went to no one.");
            else
            player:notify(tostr("Mail actually went to ", $mail_agent:name_list(@listdelete(result, 1)), "."));
            endif
            else
            player:notify(tostr((typeof(e) == ERR) ? e | ("Bogus recipients:  " + $string_utils:from_list(result[2]))));
            player:notify("Mail not sent.");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@keep-m*ail @keepm*ail</NAME>
          <CODE>
            "@keep-mail [&lt;msg-sequence&gt;|none] [on &lt;recipient&gt;]";
            "marks the indicated messages as `kept'.";
            set_task_perms(valid(cp = caller_perms()) ? cp | player);
            if (!args)
            return player:notify("Usage:  @keep-mail [&lt;msg-sequence&gt;|none] [on &lt;recipient&gt;]");
            elseif (args[1] == "none")
            args[1..1] = {};
            if (!(pfs = this:parse_folder_spec(verb, args, "on", 0)))
            return;
            elseif (pfs[2])
            player:notify(tostr(verb, " &lt;message-sequence&gt; or `none', but not both."));
            return;
            endif
            this:set_current_folder(folder = pfs[1]);
            if (e = folder:keep_message_seq({}))
            player:notify(tostr("Messages on ", $mail_agent:name(folder), " are no longer marked as kept."));
            else
            player:notify(tostr(e));
            endif
            return;
            elseif (p = this:parse_mailread_cmd(verb, args, "", "on"))
            if ((folder = p[1]) != this)
            "... maybe I'll take this clause out some day...";
            player:notify(tostr(verb, " can only be used on your own mail collection."));
            return;
            endif
            this:set_current_folder(folder);
            if (e = folder:keep_message_seq(msg_seq = p[2]))
            player:notify(tostr("Message", match(e, "[.,]") ? "s " | " ", e, " now marked as kept."));
            elseif (typeof(e) == ERR)
            player:notify(tostr(e));
            else
            player:notify(tostr(((seq_size = $seq_utils:size(msg_seq)) == 1) ? "That message is" | "Those messages are", " already marked as kept."));
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>my_match_recipient</NAME>
          <CODE>
            ":my_match_recipient(string) =&gt; matches string against player's private mailing lists.";
            if (!(string = args[1]))
            return $nothing;
            elseif (string[1] == "*")
            string = string[2..$];
            endif
            return $string_utils:match(string, this.mail_lists, "aliases");
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>expire_old_messages</NAME>
          <CODE>
            set_task_perms(caller_perms());
            if (!$perm_utils:controls(caller_perms(), this))
            return E_PERM;
            else
            seq = this:expirable_msg_seq();
            if (seq)
            this:rm_message_seq(seq);
            return this:expunge_rmm();
            else
            return 0;
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>msg_full_text</NAME>
          <CODE>
            ":msg_full_text(@msg) =&gt; list of strings.";
            "msg is a mail message (in the usual transmission format).";
            "display_seq_full calls this to obtain the actual list of strings to display.";
            return player:msg_text(@args);
            "default is to leave it up to the player how s/he wants it to be displayed.";
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@resend</NAME>
          <CODE>
            "@resend &lt;msg&gt; [on *&lt;recipient&gt;] to &lt;recipient&gt; [&lt;recipient&gt;...]";
            set_task_perms(valid(caller_perms()) ? caller_perms() | player);
            "...";
            "... parse command...";
            "...";
            if (!(p = this:parse_mailread_cmd(verb, args, "", "on", 1)))
            "...lose...";
            return;
            elseif ($seq_utils:size(sequence = p[2]) != 1)
            player:notify("You can only resend *one* message at a time.");
            return;
            elseif ((length(p[4]) &lt; 2) || (p[4][1] != "to"))
            player:notify(tostr("Usage:  ", verb, " [&lt;message&gt;] [on &lt;folder&gt;] to &lt;recip&gt;..."));
            return;
            endif
            recips = {};
            for rs in (listdelete(p[4], 1))
            if ($mail_agent:match_failed(r = $mail_agent:match_recipient(rs), rs))
            return;
            endif
            recips = {@recips, r};
            endfor
            this:set_current_folder(folder = p[1]);
            "...";
            "... retrieve original message...";
            "...";
            {msgnum, msgtxt} = folder:messages_in_seq(sequence)[1];
            if (forward_style = this:mail_option("resend_forw"))
            "...message will be from player...";
            pmh = $mail_agent:parse_misc_headers(msgtxt, "Reply-To", "Original-Date", "Original-From");
            orig_from = pmh[3][3] || msgtxt[2];
            else
            "...message will be from author...";
            pmh = $mail_agent:parse_misc_headers(msgtxt, "Reply-To", "Original-Date", "Original-From", "Resent-By", "Resent-To");
            orig_from = pmh[3][3];
            from = $mail_agent:parse_address_field(msgtxt[2])[1];
            to = $mail_agent:parse_address_field(msgtxt[3]);
            endif
            "...";
            "... report bogus headers...";
            "...";
            if (bogus = pmh[2])
            player:notify("Bogus headers stripped from original message:");
            for b in (bogus)
            player:notify("  " + b);
            endfor
            if (!$command_utils:yes_or_no("Continue?"))
            player:notify("Message not resent.");
            return;
            endif
            endif
            "...";
            "... subject, replyto, original-date, original-from ...";
            "...";
            hdrs = {msgtxt[4], pmh[3][1], {"Original-Date", pmh[3][2] || ctime(msgtxt[1])}, @orig_from ? {{"Original-From", orig_from}} | {}, @pmh[1]};
            "...";
            "... send it ...";
            "...";
            if (forward_style)
            result = $mail_agent:send_message(player, recips, hdrs, pmh[4]);
            else
            "... resend inserts resent-to and resent-by...";
            result = $mail_agent:resend_message(player, recips, from, to, hdrs, pmh[4]);
            endif
            "...";
            "... report outcome...";
            "...";
            if (!result)
            player:notify(tostr(result));
            elseif (result[1])
            player:notify(tostr("Message ", msgnum, @(folder == this) ? {} | {" on ", $mail_agent:name(folder)}, " @resent to ", $mail_agent:name_list(@listdelete(result, 1)), "."));
            else
            player:notify("Message not resent.");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>make_current_message_new</NAME>
          <CODE>
            ":make_current_message(recipient[,index])";
            "starts a new current_message record for recipient.";
            "index, if given, indicates where recipient is to be";
            "  placed (n = at or after nth entry in .current_message).";
            recip = args[1];
            cm = this.current_message;
            if (length(args) &gt; 1)
            i = max(2, min(args[2], length(cm)));
            else
            i = 0;
            endif
            if ((caller != this) &amp;&amp; (!$perm_utils:controls(caller_perms(), this)))
            raise(E_PERM);
            elseif (recip == this)
            "...self...";
            elseif (j = $list_utils:iassoc(recip, cm))
            "...already present...";
            if (i)
            if (j &lt; i)
            this.current_message = {@cm[1..j - 1], @cm[j + 1..i], cm[j], @cm[i + 1..$]};
            elseif (j &gt; (i + 1))
            this.current_message = {@cm[1..i], cm[j], @cm[i + 1..j - 1], @cm[j + 1..$]};
            endif
            endif
            else
            this.current_message = listappend(cm, {recip, 0, 0}, @i ? {i} | {});
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>expirable_msg_seq</NAME>
          <CODE>
            "Return a sequence indicating the expirable messages for this player.";
            set_task_perms(caller_perms());
            if (!$perm_utils:controls(caller_perms(), this))
            return E_PERM;
            elseif (!(curmsg = this:get_current_message(this)))
            "No messages!  Don't even try.";
            return {};
            elseif (0 &gt;= (period = this:mail_option("expire") || $mail_agent.player_expire_time))
            "...no expiration allowed here...";
            return {};
            else
            return $seq_utils:remove(this:unkept_msg_seq(), 1 + this:length_date_le(min(time() - period, curmsg[2] - 86400)));
            "... the 86400 is pure fudge...";
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>format_for_netforward</NAME>
          <CODE>
            "Takes a message sequence (the actual messages, not just the sequence describing it) and grovels over it filling text etc.  Returns a two valued list: {formatted message, header for same}";
            set_task_perms(caller_perms());
            {message_seq, folderstr} = args;
            netmail = {};
            linelen = this:linelen();
            maxmsg = minmsg = 0;
            for msg in (message_seq)
            minmsg = minmsg ? min(msg[1], minmsg) | msg[1];
            maxmsg = maxmsg ? max(msg[1], maxmsg) | msg[1];
            lines = {tostr("Message ", msg[1], folderstr, ":"), tostr("Date:     ", ctime(msg[2][1])), "From:     " + msg[2][2], "To:       " + msg[2][3], @(length(subj = msg[2][4]) &gt; 1) ? {"Subject:  " + subj} | {}};
            for line in (msg[2][5..$])
            if (typeof(line) != STR)
            "I don't know how this can happen, but apparently non-strings can end up in the mail message.  So, cope.";
            line = tostr(line);
            endif
            lines = {@lines, @$generic_editor:fill_string(line, linelen)};
            $command_utils:suspend_if_needed(0);
            endfor
            netmail = {@netmail, @lines, "", "--------------------------", "", ""};
            endfor
            header = tostr($network.MOO_name, " Message(s) ", minmsg, @(minmsg != maxmsg) ? {" - ", maxmsg} | {}, folderstr);
            return {netmail, header};
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>format_for_netforward_debug</NAME>
          <CODE>
            "Takes a message sequence (the actual messages, not just the sequence describing it) and grovels over it filling text etc.  Returns a two valued list: {formatted message, header for same}";
            set_task_perms(caller_perms());
            {message_seq, folderstr} = args;
            netmail = {};
            linelen = this:linelen();
            maxmsg = minmsg = 0;
            for msg in (message_seq)
            minmsg = minmsg ? min(msg[1], minmsg) | msg[1];
            maxmsg = maxmsg ? max(msg[1], maxmsg) | msg[1];
            lines = {tostr("Message ", msg[1], folderstr, ":"), tostr("Date:     ", ctime(msg[2][1])), "From:     " + msg[2][2], "To:       " + msg[2][3], @(length(subj = msg[2][4]) &gt; 1) ? {"Subject:  " + subj} | {}};
            for line in (msg[2][5..$])
            if (typeof(line) != STR)
            "I don't know how this can happen, but apparently non-strings can end up in the mail message.  So, cope.";
            line = tostr(line);
            endif
            lines = {@lines, @$generic_editor:fill_string(line, linelen)};
            $command_utils:suspend_if_needed(0);
            endfor
            netmail = {@netmail, @lines, "", "--------------------------", "", ""};
            endfor
            header = tostr($network.MOO_name, " Message(s) ", minmsg, @(minmsg != maxmsg) ? {" - ", maxmsg} | {}, folderstr);
            return {netmail, header};
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="none" PREP="none" IOBJ="none">
          <NAME>@nn</NAME>
          <CODE>
            "@nn  -- reads the first new message on the first mail_recipient (in .current_message) where new mail exists.";
            set_task_perms(valid(cp = caller_perms()) ? cp | player);
            cm = this.current_message;
            cm[1..2] = {{this, @cm[1..2]}};
            for n in (cm)
            if ($mail_agent:is_recipient(n[1]))
            if (new = n[1]:length_date_gt(n[3]))
            next = (n[1]:length_all_msgs() - new) + 1;
            this:set_current_folder(folder = n[1]);
            this._mail_task = task_id();
            cur = folder:display_seq_full({next, next + 1}, tostr("Message %d", " on ", $mail_agent:name(folder), ":"));
            this:set_current_message(folder, @cur);
            return;
            endif
            else
            player:notify(tostr("Bogus recipient ", n[1], " removed from .current_message."));
            this.current_message = setremove(this.current_message, n);
            endif
            endfor
            player:tell("No News (is good news)");
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@unread</NAME>
          <CODE>
            "@unread &lt;msg&gt; [on *&lt;recipient&gt;]  -- resets last-read-date for recipient to just before the first of the indicated messages.";
            set_task_perms(player);
            if (p = this:parse_mailread_cmd("@unread", args, "cur", "on"))
            this:set_current_folder(folder = p[1]);
            msg_ord = $seq_utils:first(msg_seq = p[2]);
            msgdate = folder:messages_in_seq(msg_ord)[2][1] - 1;
            if ((!(cm = this:get_current_message(folder))) || (cm[2] &lt; msgdate))
            player:notify("Already unread.");
            else
            if (folder == this)
            this.current_message[2] = msgdate - 1;
            else
            this:kill_current_message(folder);
            this:set_current_message(folder, cm[1], min(cm[2], msgdate));
            endif
            folder:display_seq_headers({msg_ord, msg_ord + 1}, cm[1], msgdate);
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@refile @copym*ail</NAME>
          <CODE>
            "@refile/@copym*ail &lt;msg-sequence&gt; [on &lt;recipient&gt;] to &lt;recipient&gt;";
            "@refile will delete the messages from the source folder.  @copym does not.";
            "I'm not happy with this one, yet...";
            set_task_perms(player);
            if (!(p = this:parse_mailread_cmd("@refile", args, "cur", "on", 1)))
            "...lose...";
            elseif ((length(p[4]) != 2) || (p[4][1] != "to"))
            player:notify(tostr("Usage:  ", verb, " [&lt;message numbers&gt;] [on &lt;folder&gt;] to &lt;folder&gt;"));
            elseif ($mail_agent:match_failed(dest = $mail_agent:match_recipient(p[4][2]), p[4][2]))
            "...bogus destination folder...";
            else
            source = p[1];
            msg_seq = p[2];
            for m in (source:messages_in_seq(msg_seq))
            if (!(e = dest:receive_message(m[2], source)))
            player:notify(tostr("Copying msg. ", m[1], ":  ", e));
            return;
            endif
            $command_utils:suspend_if_needed(0);
            endfor
            if (refile = verb == "@refile")
            if (typeof(e = source:rm_message_seq(msg_seq)) == ERR)
            player:notify(tostr("Deleting from ", source, ":  ", e));
            endif
            endif
            count = tostr(n = $seq_utils:size(msg_seq), " message", (n == 1) ? "" | "s");
            fname = (source == this) ? "" | tostr(is_player(source) ? " from " | " from *", source.name, "(", source, ")");
            suffix = tostr(is_player(dest) ? " to " | " to *", dest.name, "(", dest, ").");
            player:notify(tostr(refile ? "Refiled " | "Copied ", count, fname, suffix));
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@quickr*eply @qreply</NAME>
          <CODE>
            "@qreply &lt;msg&gt; [on *&lt;recipient&gt;] [&lt;flags&gt;...]";
            "like @reply only, as in @qsend, we prompt for the message text using ";
            "$command_utils:read_lines() rather than invoking the $mail_editor.";
            set_task_perms(who = valid(cp = caller_perms()) ? cp | player);
            if (!(p = this:parse_mailread_cmd(verb, args, "cur", "on", 1)))
            "...garbled...";
            elseif ($seq_utils:size(p[2]) != 1)
            player:notify("You can only answer *one* message at a time.");
            elseif (LIST != typeof(flags_replytos = $mail_editor:check_answer_flags("noinclude", @p[4])))
            player:notify_lines({tostr("Usage:  ", verb, " [message-# [on &lt;recipient&gt;]] [flags...]"), "where flags include any of:", "  all        reply to everyone", "  sender     reply to sender only", tostr("  include    include the original message in reply (can't do this for ", verb, ")"), "  noinclude  don't include the original in your reply"});
            elseif ("include" in flags_replytos[1])
            player:notify(tostr("Can't include message on a ", verb));
            else
            this:set_current_folder(p[1]);
            if (to_subj = $mail_editor:parse_msg_headers(p[1]:messages_in_seq(p[2])[1][2], flags_replytos[1]))
            player:notify(tostr("To:       ", $mail_agent:name_list(@to_subj[1])));
            if (to_subj[2])
            player:notify(tostr("Subject:  ", to_subj[2]));
            endif
            if (replytos = flags_replytos[2])
            player:notify(tostr("Reply-to: ", $mail_agent:name_list(@replytos)));
            endif
            hdrs = {to_subj[2], replytos || {}};
            player:notify("Enter lines of message:");
            message = $command_utils:read_lines_escape((active = player in $mail_editor.active) ? {} | {"@edit"}, {tostr("You are composing mail to ", $mail_agent:name_list(@to_subj[1]), "."), @active ? {} | {"Type `@edit' to take this into the mail editor."}});
            if (typeof(message) == ERR)
            player:notify(tostr(message));
            elseif (message[1] == "@edit")
            $mail_editor:invoke(1, verb, to_subj[1], @hdrs, message[2]);
            elseif (!message[2])
            player:notify("Blank message not sent.");
            else
            result = $mail_agent:send_message(this, to_subj[1], hdrs, message[2]);
            if (result &amp;&amp; result[1])
            player:notify(tostr("Message sent to ", $mail_agent:name_list(@listdelete(result, 1)), "."));
            else
            player:notify("Message not sent.");
            endif
            endif
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="none" PREP="none" IOBJ="none">
          <NAME>@mail-all-new*-mail</NAME>
          <CODE>
            "@mail-all-new-mail";
            " Prints headers for all new mail on every mail-recipient mentioned in .current_message.";
            set_task_perms(valid(cp = caller_perms()) ? cp | player);
            cm = this.current_message;
            cm[1..2] = {{this, @cm[1..2]}};
            this._mail_task = task_id();
            nomail = 1;
            new_cms = {};
            for f in (cm)
            if (!($object_utils:isa(folder = f[1], $player) || $object_utils:isa(folder, $mail_recipient)))
            player:notify(tostr(folder, " is neither a $player nor a $mail_recipient"));
            elseif (typeof(flen = folder:length_all_msgs()) == ERR)
            player:notify(tostr($mail_agent:name(folder), " ", flen));
            elseif (msg_seq = $seq_utils:range(folder:length_date_le(f[3]) + 1, flen))
            nomail = 0;
            player:notify("===== " + $string_utils:left(tostr($mail_agent:name(folder), " (", s = $seq_utils:size(msg_seq), " message", (s == 1) ? ") " | "s) "), 40, "="));
            folder:display_seq_headers(msg_seq, @f[2..3]);
            player:notify("");
            $command_utils:suspend_if_needed(2);
            endif
            endfor
            if (nomail)
            player:notify("You don't have any new mail anywhere.");
            else
            player:notify("===== " + $string_utils:left("End of new mail ", 40, "="));
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="any" PREP="none" IOBJ="none">
          <NAME>@read-all-new*-mail @ranm</NAME>
          <CODE>
            "@read-all-new-mail [yes]";
            " Prints all new mail on every mail-recipient mentioned in .current_message";
            " Generally this will spam you into next Tuesday.";
            " You will be queried for whether you want your last-read dates updated";
            "   but you can specify \"yes\" on the command line to suppress this.";
            "   If you do so, last-read dates will be updated after each folder read.";
            set_task_perms(valid(cp = caller_perms()) ? cp | player);
            noconfirm = args &amp;&amp; ("yes" in args);
            cm = this.current_message;
            cm[1..2] = {{this, @cm[1..2]}};
            this._mail_task = task_id();
            nomail = 1;
            new_cms = {};
            for f in (cm)
            if (!($object_utils:isa(folder = f[1], $player) || $object_utils:isa(folder, $mail_recipient)))
            player:notify(tostr(folder, " is neither a $player nor a $mail_recipient"));
            elseif (typeof(flen = folder:length_all_msgs()) == ERR)
            player:notify(tostr($mail_agent:name(folder), " ", flen));
            elseif (msg_seq = $seq_utils:range(folder:length_date_le(f[3]) + 1, flen))
            nomail = 0;
            player:notify("===== " + $string_utils:left(tostr($mail_agent:name(folder), " (", s = $seq_utils:size(msg_seq), " message", (s == 1) ? ") " | "s) "), 40, "="));
            player:notify("");
            if (cur = folder:display_seq_full(msg_seq, tostr("Message %d", (folder == this) ? "" | (" on " + $mail_agent:name(folder)), ":")))
            if (noconfirm)
            this:set_current_message(folder, @cur);
            this:set_current_folder(folder);
            else
            new_cms = {@new_cms, {folder, @cur}};
            endif
            player:notify("");
            endif
            endif
            $command_utils:suspend_if_needed(1);
            this._mail_task = task_id();
            endfor
            if (nomail)
            player:notify("You don't have any new mail anywhere.");
            elseif (player:notify("===== " + $string_utils:left("End of new mail ", 40, "=")) || (noconfirm || $command_utils:yes_or_no("Did you get all of that?")))
            for n in (new_cms)
            this:set_current_message(@n);
            this:set_current_folder(n[1]);
            endfor
            player:notify("Last-read-dates updated");
            else
            player:notify("Last-read-dates not updated");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="any" IOBJ="any">
          <NAME>@quick*send @qsend</NAME>
          <CODE>
            "Syntax: @quicksend &lt;recipients(s)&gt; [subj=&lt;text&gt;] [&lt;message&gt;]";
            "Sends the recipients(s) a quick message, wit{out having to go to the mailroom. If there is more than one recipients, place them all in quotes. If the subj contains spaces, place it in quotes.";
            "To put line breaks in the message, use a caret (^).";
            "If no message is given, prompt for lines of message.";
            "Examples:";
            "@quicksend Alice subj=\"Wonderland is neat!\" Have you checked out the Wonderland scenario yet? I think you'd like it!";
            "@quicksend \"Ethel Fred\" Have you seen Lucy around?^--Ricky";
            set_task_perms($object_utils:isa(player, $guest) ? player.owner | player);
            if (!args)
            player:notify(tostr("Usage: ", verb, " &lt;recipients(s)&gt; [subj=&lt;text&gt;] [&lt;message&gt;]"));
            return E_INVARG;
            elseif (this != player)
            player:notify(tostr("You can't use ", this.pp, " @quicksend verb."));
            return E_PERM;
            elseif (!(recipients = $mail_editor:parse_recipients({}, $string_utils:explode(args[1]))))
            return;
            else
            if ((length(args) &gt; 1) &amp;&amp; ((eq = index(args[2], "=")) &amp;&amp; (index("subject", args[2][1..eq - 1]) == 1)))
            subject = $string_utils:trim(args[2][eq + 1..$]);
            ws = $string_utils:word_start(argstr);
            argstr = argstr[1..ws[1][2]] + argstr[ws[2][2] + 1..$];
            args = listdelete(args, 2);
            else
            subject = "";
            endif
            if (length(args) &gt; 1)
            unbroken = argstr[(argstr[1] == "\"") ? length(args[1]) + 4 | (length(args[1]) + 2)..$] + "^";
            message = {};
            while (unbroken)
            if (i = index(unbroken, "^"))
            message = {@message, unbroken[1..i - 1]};
            endif
            unbroken = unbroken[i + 1..$];
            endwhile
            else
            if (!(subject || player:mail_option("nosubject")))
            player:notify("Subject:");
            subject = $command_utils:read();
            endif
            player:notify("Enter lines of message:");
            message = $command_utils:read_lines_escape((active = player in $mail_editor.active) ? {} | {"@edit"}, {tostr("You are composing mail to ", $mail_agent:name_list(@recipients), "."), @active ? {} | {"Type `@edit' to take this into the mail editor."}});
            if (typeof(message) == ERR)
            player:notify(tostr(message));
            return;
            elseif (message[1] == "@edit")
            $mail_editor:invoke(1, verb, recipients, subject, {}, message[2]);
            return;
            elseif (!(message[2] || subject))
            player:notify("Blank message not sent.");
            return;
            endif
            message = message[2];
            endif
            result = $mail_agent:send_message(this, recipients, subject, message);
            if (result &amp;&amp; result[1])
            player:notify(tostr("Message sent to ", $mail_agent:name_list(@listdelete(result, 1)), "."));
            else
            player:notify("Message not sent.");
            endif
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>init_for_core</NAME>
          <CODE>
            if (caller_perms().wizard)
            pass();
            this.mail_options = {};
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>confunc</NAME>
          <CODE>
            if (((valid(cp = caller_perms()) &amp;&amp; (caller != this)) &amp;&amp; (!$perm_utils:controls(cp, this))) &amp;&amp; (caller != #0))
            return E_PERM;
            endif
            nm = this:length_all_msgs() - this:length_date_le(this:get_current_message()[2]);
            if (nm)
            this:notify(tostr("You have new mail (", nm, " message", (nm == 1) ? "" | "s", ").", this:mail_option("expert") ? "" | "  Type 'help mail' for info on reading it."));
            endif
            this:mail_catch_up();
            this:check_mail_lists();
            pass(@args);
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d r" DOBJ="any" PREP="at/to" IOBJ="any">
          <NAME>@add-notify</NAME>
          <CODE>
            "Ideally, in order for one person to be notified that another person has new mail, both the mail recipient and the notification recipient should agree that this is an OK transfer of information.";
            "Usage:  @add-notify me to player";
            "    Sends mail to player saying that I want to be added to their mail notification property.";
            "Usage:  @add-notify player to me";
            "    Makes sure that player wants to be notified, if so, adds them to my .mail_notify property.  (Deletes from temporary record.)";
            if (this == dobj)
            target = $string_utils:match_player(iobjstr);
            if ($command_utils:player_match_failed(target, iobjstr))
            return;
            elseif (this in target.mail_notify[1])
            player:tell("You already receive notifications when ", target.name, " receives mail.");
            elseif (this in target.mail_notify[2])
            player:tell("You already asked to be notified when ", target.name, " receives mail.");
            else
            $mail_agent:send_message(player, {target}, "mail notification request", {tostr($string_utils:nn(this), " would like to receive mail notifications when you get mail."), "Please type:", tostr("  @add-notify ", this.name, " to me"), "if you wish to allow this action."});
            player:tell("Notifying ", $string_utils:nn(target), " that you would like to be notified when ", target.ps, " receives mail.");
            target.mail_notify[2] = setadd(target.mail_notify[2], this);
            endif
            elseif (this == iobj)
            target = $string_utils:match_player(dobjstr);
            if ($command_utils:player_match_failed(target, dobjstr))
            return;
            elseif (target in this.mail_notify[2])
            this.mail_notify[1] = setadd(this.mail_notify[1], target);
            this.mail_notify[2] = setremove(this.mail_notify[2], target);
            player:tell(target.name, " will be notified when you receive mail.");
            else
            player:tell("It doesn't look like ", target.name, " wants to be notified when you receive mail.");
            endif
            else
            player:tell("Usage:  @add-notify me to player");
            player:tell("        @add-notify player to me");
            endif
          </CODE>
        </VERB>
        <VERB OWNER="obj2" PERMS="d x r" DOBJ="this" PREP="none" IOBJ="this">
          <NAME>mail_notify</NAME>
          <CODE>
            if ((length(this.mail_notify) &gt; 0) &amp;&amp; (typeof(this.mail_notify[1]) == LIST))
            return this.mail_notify[1];
            else
            return this.mail_notify;
            endif
          </CODE>
        </VERB>
        <OBJECT ID="obj38" FLAGS="r programmer player" OWNER="obj36" LOCATION="obj-1">
          <NAME>Everyman</NAME>
          <PROPERTY OWNER="obj2" PERMS="r">
            <NAME>queued_task_limit</NAME>
            <VALUE>0</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>_mail_task</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>messages_going</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>mail_lists</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="r">
            <NAME>mail_notify</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>mail_forward</NAME>
            <VALUE>"Everyman ($no_one) can not receive mail."</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>mail_options</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>message_keep_date</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>messages_kept</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>current_message</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>messages</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>features</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" >
            <NAME>previous_connection</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" >
            <NAME>email_address</NAME>
            <VALUE>""</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="r">
            <NAME>last_disconnect_time</NAME>
            <VALUE>2147483647</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>help</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>more_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>linetask</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>linesleft</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" >
            <NAME>linebuffer</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>pagelen</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" PERMS="r">
            <NAME>owned_objects</NAME>
            <VALUE>{}</VALUE>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="r">
            <NAME>linelen</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>current_folder</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" >
            <NAME>all_connect_places</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj2" >
            <NAME>last_connect_place</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>dict</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>brief</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c">
            <NAME>lines</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>page_absent_msg</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>pq</NAME>
          </PROPERTY>
          <PROPERTY OWNER="obj36" PERMS="c r">
            <NAME>pqc</NAME>
          </PROPERTY>
          <PROP
