TODO
----

Cleanup on recycling


ISSUES
------

Protocols are not robust when it comes to following--make sure no
security holes, and think about common cases of unintentionally
breaking it.


PROTOCOLS
---------

It is sometimes helpful for an object to know if another object
follows a protocol; for instance, a located object would like to make
sure that its location follows the container protocol.

Unfortunately, this is a very complicated issue in an environment
involving multiple untrusted programmers.  The system described here
is not bulletproof, but should be good enough in practice.

The current system involves a couple of non-overridable root object
methods and a few methods on $sys.  The methods are:

$root.follows(protocol):

	Returns true if the system object trusts this object to follow
	<protocol>, which is a symbol.  For instance, $located could
	use "if (loc.follows('container))" to ask if the system object
	trusts loc to follow the container protocol.

	Checking is done by doing a has_ancestor() on each object in
	$sys.followers(protocol).  This is not robust: the object may
	change parents, and it can override non-overridable methods on
	the ancestor by including other parents.  Therefore, you
	should use .follows() as a heuristic only, and should not rely
	on it for security.

$root.is_agent(protocol);

	Returns true if the system object thinks this object can act
	as an agent of <protocol>, a symbol.  Agents of a protocol
	commonly have special permissions; for instance,
	$sys.add_parent can only be called by methods on agents of
	the hierarchy protocol; it checks this with
	"if (!caller().is_agent('hierarchy))".

	Checking is done by determining whether the current object is
	in $sys.agents(protocol).  This is robust.

$sys.followers(protocol):

	Returns a list of objects which follow <protocol>, a symbol.
	If $sys has not been instructed to trust any objects to follow
	<protocol>, this method returns the empty list.

$sys.agents(protocol):

	Returns a list of agents of <protocol>, a symbol.  If $sys has
	not been instructed to trust any agents of <protocol>, this
	method returns the empty list.

$sys.trust(object, protocol, type) (wizard-only):

	Instructs the system object to trust <object> to follow or be
	an agent of <protocol>, according to <type>, which should be
	either 'follow or 'agent.

$sys.untrust(object, protocol)

	Stops trusting <object> to follow or be an agent of
	<protocol>.