reference updates, including diagrams
[org.ibex.core.git] / doc / reference / reference.xml
diff --git a/doc/reference/reference.xml b/doc/reference/reference.xml
new file mode 100644 (file)
index 0000000..4850109
--- /dev/null
@@ -0,0 +1,2450 @@
+<ibex-doc title="The Ibex Reference" subtitle="Nitrogen Release" author="Adam Megacz" email="adam@ibex.org">
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Introduction">
+
+    <i>
+    If you are reading the html version of this document and are
+    thinking of printing it out, you might be interested in the nicely
+    typeset <link url="reference.pdf" text="pdf version"/> produced
+    with LaTeX.
+    </i>
+
+    This document is a <b>reference</b>. It is not a
+    <b>specification</b> or a
+    <b>tutorial</b>.
+    
+    This document does not guide the user gently through examples (as a
+    tutorial would), and it doesn't provide enough detail and formality
+    for a third party to construct a compatible re-implementation of the
+    Ibex Core (as a specification would).
+    
+    Rather, the goal of this document is to completely describe every
+    aspect of the environment that the Ibex Core provides to client
+    applications, from the bottom up. If you want to be an Ibex expert,
+    this is the right document to read. It is assumed that you are already
+    familiar with XML and with either JavaScript or ECMAscript.
+    
+    If you need to use or rely on some behavior you notice in the Ibex
+    Core, but which is not clearly defined here, please post to <link
+    url="http://lists.ibex.org/listinfo/users" text="the users mailing list"/>.
+    
+  <section title="Key Concepts">
+  
+    <definition term="The Core">
+         Ibex itself; the native code (or Java bytecode) that runs on
+         the client.  This term does not include the <i>Wildebeest</i>
+         or the <i>UI</i></definition>
+  
+    <definition term="The UI / The Application">
+         A set of files (mostly XML, JavaScript, and PNG images)
+         bundled up in a zip archive, ending with the "<t>.ibex</t>"
+         extension.  Together, these files specify the appearance and
+         behavior of the application's user interface.
+         </definition>
+  
+    <definition term="The Server">
+         We will use the term "the server" to refer to any other
+         computer which the client makes XML-RPC or SOAP calls
+         to. Note that it is possible for the client and server to be
+         the same machine.</definition>
+  
+    <definition term="Wildebeest">
+         This is a very small piece of code that is downloaded the
+         first time a client uses Ibex. It downloads the Ibex core,
+         verifies its signature, and launches it with the appropriate
+         parameters indicating where to find the initial UI.
+         Wildebeest works differently on every platform, and is outside
+         the scope of this document.</definition>
+  
+    <definition term="put/write">
+         In ECMAscript, when you change the value of a property on an
+         object, you are <i>putting</i> to that property, or
+         <i>writing</i> to it. For example, the ECMAscript expression
+         "<t>foo.bar = 5</t>" <i>puts</i> the value 5 to the bar
+         property on object foo.</definition>
+  
+    <definition term="get/read">
+         In ECMAscript, when you access the value of a property on an
+         object, you are <i>getting</i> that property, or
+         <i>reading</i> from it. For example, the ECMAscript
+         expression "<t>return (3 + foo.bar)</t>" <i>gets</i> the
+         value of bar property on object foo and then adds 3 to it
+         before returning the result.</definition>
+  
+    <definition term="JavaScript">
+        We will use the terms JavaScript and ECMAScript
+        interchangeably in this document.  The Ibex interpreter is not
+        completely ECMA-compliant, however (see <link
+        appendix="ECMAscript compliance"/> for details).
+        </definition>
+
+  </section>
+
+  <section title="Life Cycle of an Ibex Application">
+  
+    <image url="lifecycle.pdf" caption="The Lifecycle of an Ibex Application"/>
+
+    A user typically begins an Ibex session by clicking on a link to
+    an Ibex application.  This link serves the {\tt launch.html} file
+    to the user's browser, which in turn downloads the appropriate
+    {\it Wildebeest} -- currently either an ActiveX Control
+    (Win32/MSIE), XPInstaller (Mozilla), or Signed Applet (all
+    others).
+
+    The Wildebeest downloads the appropriate core for the user's
+    machine and verifies its digital signature.  It then launches the
+    core, which downloads the UI (an <t>.ibex</t> archive), loads it,
+    applies the <t>main.t</t> template (found in the archive), and
+    renders it onto the screen, running any associated JavaScript
+    code.
+      
+    The user interacts with the application by clicking and moving the
+    mouse, and by pressing keys on the keyboard.  These actions trigger
+    fragments of JavaScript code which are designated to handle events.
+    This JavaScript code can then relay important information back to the
+    server using XML-RPC or SOAP, or it can modify the structure and
+    properties of the user interface to change its appearance, thereby
+    giving feedback to the user.
+      
+    The Ibex core quits when the last remaining surface has been destroyed.
+
+  </section>
+
+
+  <section title="Surfaces">
+  
+    <image url="offscreen.pdf" width="2in"
+           caption="An Ibex surface positioned at (83,0)"/>
+    Each top-level window in an Ibex UI is called a
+    <i>surface</i>. There are two kinds of surfaces: <i>frames</i>,
+    which usually have a platform-specific titlebar and border, and
+    <i>windows</i>, which never have any additional platform-specific
+    decorations.
+    
+    Whenever we refer to the size or position
+    of a surface, we are referring to the size or position of the
+    UI-accessible portion of the surface; this does not include any
+    platform-specific decorations. This means that if you set the
+    position of a frame to (0,0), the platform-specific titlebar will
+    actually be off the screen on most platforms (it will be above and
+    to the left of the top-left corner of the screen).
+
+    Surfaces are not actual JavaScript objects; you cannot obtain a
+    reference to a surface.  However, each surface is uniquely identified
+    by its <i>root box</i>, described in the next section.
+      
+  </section>
+  
+  <section title="Boxes">
+  
+    A <i>box</i> is the fundamental unit from which all Ibex user
+    interfaces are built.  Boxes can contain other boxes (referred to as
+    its <i>children</i>).  Each surface has a single box associated with
+    it called the <i>root box</i>; the root box and its children (and
+    its children's children, and so on) form the surface's <i>box
+    tree</i>.
+     
+    There are three ways to think of a box:
+    <list>
+  
+        As a rendered visualization on the screen (the "<i>Visual Representation</i>")
+  
+        As a JavaScript object (the "<i>Object Representation</i>")
+  
+        As as an XML tag (the "XML Template Representation").
+  
+    </list>
+
+    <image url="threeviews.pdf" caption="The three representations of an Ibex box"/>
+  
+    All three representations are equally valid, and being able to
+    figure out what an action in one representation would mean in terms
+    of the other two representations is crucial to a solid understanding
+    of Ibex.
+      
+  </section>
+</section>
+  
+<section title="The XML Template Representation">
+
+  A template (discussed in the next section) is an XML file which acts
+  as a blueprint for constructing a tree of boxes.  We call this
+  construction process <i>applying</i>, since unlike
+  <i>instantiation</i> in object-oriented programming systems, you
+  always apply a template to a pre-existing box, and you can apply
+  multiple templates to the same box.
+
+  Each XML tag corresponds to a single box, or to another template
+  which will be applied to that box.  For example, a <t>scrollbar</t>
+  template, when applied, will construct a tree of boxes which has the
+  visual appearance and behavior of a scrollbar.
+    
+  Although it is useful to think of the XML tags as being boxes, keep
+  in mind that the XML representation is only a blueprint for
+  constructing a tree of JavaScript objects.  Once the template has
+  been instantiated, the XML is effectively "thrown away", and
+  JavaScript code is free to alter the boxes.  Once the process of
+  applying a template is complete, Ibex completely forgets the fact
+  that it has applied a particular template to a particular box.  One
+  consequence of this approach is that if you think of templates as
+  classes, then Ibex has no equivalent for Java's <t>instanceof</t>
+  operator.
+
+  Each template is an XML document whose root element is
+  <t>&lt;ibex></t>.  Here is a sample template file:
+
+  <pre>
+  <ibex xmlns:lib="ibex.lib">
+
+      <meta:doc>
+          This is a cool widget.
+      </meta:doc>
+
+      // this code is executed only once
+      static = { instances : [] };
+
+      // this element applies the ibex.lib.focusable template
+      <lib:focusable/>
+
+      <ui:box cols="5">
+          static.instances.push(thisbox);
+          <ui:box id="container"/>
+          <ui:checkbox/>
+          <ui:box>
+              <lib:scrollbar/>
+          </ui:box>
+      </ui:box>
+  </ibex>
+  </pre>
+
+  The following two namespaces are predefined and need not be declared
+  using <t>xmlns</t>:
+
+  <definition term="meta">
+      <t>http://xmlns.ibex.org/meta</t>
+
+      This will be referred to as the "<t>meta</t> namespace" in the
+      remainder of this document.
+      </definition>
+
+  <definition term="ui">
+      <t>http://xmlns.ibex.org/ui</t>
+
+      This will be referred to as the "<t>ui</t> namespace" in the
+      remainder of this document.
+      </definition>
+
+  Additionally, the default namespace for the document will be set to
+  the template's package FIXME.
+
+  <section title="Static Code">
+
+    If the root <t>&lt;ibex&gt;</t> element contains any non-whitespace
+    text content, this text is interpreted as JavaScript code and is
+    executed the first time the template is referenced.  This code is
+    executed in a fresh scope containing two predefined properties:
+  
+    <definition term="ibex">
+      The Ibex Object (described in <ref section="The Ibex Object"/>)
+      </definition>
+  
+    <definition term="static">
+      A reference to this template's <i>static object</i>, which is
+      initially <t>null</t>.  The static object can be accessed (read
+      and written) from both static scripts as well as instance
+      scripts in a particular template. FIXME
+      </definition>
+
+    </section>
+  
+  <section title="Metadata">
+
+    Any immediate children of the root element which are in the
+    <t>meta</t> namespace are treated as metadata and are exempted from
+    the rest of the template application process.  Currently only one
+    type of metadata element is defined:
+  
+    <list>
+        <t>&lt;meta:doc&gt;</t>: structured documentation for the
+        template.
+    </list>
+
+  </section>
+
+  <section title="Other Elements">
+
+    All remaining children of the root element are treated as elements
+    to be <i>applied</i> to the box, in the order in which they appear
+    in the file using the following procedure.
+  
+    <remark text="While this process outlined below sounds very
+                  complex, it actually works pretty intuitively. The
+                  description below is given in great detail since
+                  most applications will wind up being unintentionally
+                  dependent on subtle features of this process.
+                  However, most of the time you can just pretend that
+                  the XML tags and the boxes are the same thing."/>
+
+      <heading title="Intuitive Description"/>
+
+      ... FIXME
+
+      During a box initialization, script-private references to a
+      box's descendants with <t>id</t> attributes are placed on the
+      box. These references allow scripts on that box to easily refer
+      to descendant nodes created by the template in which the script
+      appears. For example, these two blocks of code have exactly the
+      same effect:
+      
+      <pre>
+      <ui:box>                           <ui:box>
+          <ui:box id="foo"/>                 <ui:box/>
+          $foo.color = "red";             var $foo = this[0];
+                                          $foo.color = "red";
+      </ui:box>                          </ui:box>
+      </pre>
+
+      <heading title="Precise Description"/>
+  
+      To apply an XML tag <t><b>x</b></t> to a box <t><b>b</b></t>, perform the following
+      operations, in this order:
+      
+      <list type="ordered">
+  
+          Allocate a fresh scope <t><b>s</b></t> whose parent scope is
+          <t><b>b</b></t>.
+          
+          Process each child element or text segment of <t><b>x</b></t>
+          in the order they appear in the document:
+  
+          <list>
+  
+              Treat each text segment <t><b>t</b></t> as JavaScript code
+              and execute it with <t><b>s</b></t> as the root scope.
+  
+              For each child element <t><b>x'</b></t> of <t><b>x</b></t>:
+  
+              <list>
+                  Create a new box <t><b>b'</b></t>.
+                  
+                  If the name of tag <t><b>x'</b></t> is not
+                  "<t>box</t>" in the <t>ui</t> namespace, prepend the
+                  tag's namespace identifier uri (if any) to the name of
+                  the tag, and use the result as a key to retrieve a
+                  property from the root stream (defined later).
+                  Interpret the resulting stream as a template and apply
+                  that template to <t><b>b'</b></t>.
+                  
+                  (recursively) apply <t><b>x'</b></t> to <t><b>b'</b></t>.
+                  
+                  If <t><b>x'</b></t> has an <t>id</t> attribute, declare a variable
+                  in <t><b>s</b></t> whose name is the value of the <t>id</t>
+                  attribute, prefixed with the <t>$</t> character, and whose
+                  value is <t><b>b'</b></t>
+                  
+                  Copy any <t>$</t>-variables created during the application
+                  of <t><b>x'</b></t> into scope <t><b>s</b></t>.
+                  
+                  Append <t><b>b'</b></t> as the last child of <t><b>b</b></t>.
+              </list>
+          </list>
+          
+          Apply any attributes on <t><b>x</b></t> to <t><b>b</b></t>, except for
+          <t>id</t>.  Since XML specifies that the order of attributes
+          cannot be significant, Ibex processes attributes in
+          alphabetical order by attribute name.  For example, if
+          <t><b>x</b></t> has the attribute <t>foo="bar"</t>, then the
+          equivalent of the statement <t>B.foo="bar";</t> will be
+          performed, with the following exceptions:
+  
+          <list>
+              If the value portion of the attribute is the string
+              "<t>true</t>", put the boolean <t>true</t>. If the
+              value is "<t>false</t>", put the boolean <t>false</t>.
+          
+              If the value is a valid ECMAscript number, put it as a
+              number (instead of a string).
+                   
+              If the value begins with a dollar sign (<t>$</t>),
+              retrieve the value of the corresponding variable in
+              <t><b>s</b></t> and use that value instead.
+           
+              If the value begins with a dot (<t>.</t>), prepend the
+              attributes' namespace identifier uri (if any) and
+              interpret the remainder as a property to be retrieved from
+              the root stream (defined later).
+          </list>
+      </list>
+
+      <heading title="Initialization Invariants"/>  
+
+      The last two steps are referred to as the <i>initialization</i> of the
+      node.  There are two important aspects of this ordering to be aware of:
+               
+      <list type="unordered">
+  
+          A given box will be fully initialized before its parent is
+          given a reference to that box.  This way, parents can be
+          certain that they will never wind up accessing a box when it
+          is in a partially-initialized state.
+          
+          Attributes are applied <i>after</i> scripts are run so that
+          the attributes will trigger any <i>traps</i> (defined later)
+          placed by the script.
+  
+      </list>
+
+  </section>
+    
+</section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Layout and Rendering">
+
+    <section title="Visual Components">
+  
+      Each box occupies a rectangular region on the surface.  The visual
+      appearance of a surface is created by rendering each box in its tree.
+      Unless the <t>clip</t> attribute is <t>false</t>, each box will
+      clip its childrens' visual representations to its own, so that the
+      children appear "confined to" the parent.  Children are rendered after
+      their parents so they appear "on top of" their parents.
+      
+      Each box has two major visual components, each with subcomponents:
+      
+      FIXME: diagram
+      
+      <definition term="path">
+  
+          A box's <t>path</t> consists of zero or more lines and curves.
+          The path may be filled with a color, gradient, or texture, and
+          may be stroked with a line of a given thickness and color.  If
+          the path is not specified, it defaults to the perimiter of the
+          box.  [<i>Note: Vector Graphics support (including the ability
+          to set the <t>path</t> property to anything other than the
+          default) is currently not implemented</i>].
+  
+          A path also has:
+  
+          <list>
+              an associated <t>strokecolor</t>, which is a color
+  
+              an associated <t>strokewidth</t>, which is a number
+              specifying the width of the stroke.  [<i>Note: Vector
+              Graphics support (including the <t>strokewidth</t>
+              property) is currently not implemented</i>]
+              
+              a <t>fill</t>, which is either a color, gradient, or
+              texture
+          </list>        
+          </definition>
+  
+      <definition term="text">
+  
+          Each box also has a single line of <t>text</t>, whose
+          appearance is determined by its:
+  
+          <list>
+              associated <t>font</t>, which can be any font supported by
+              the <link url="http://www.freetype.org" text="FreeType2"/>
+              library.
+              
+              an associated <t>fontsize</t> in <i>pixels</i>
+              
+              an associated <t>textcolor</t>
+          </list>
+          </definition>
+  
+      These eight components plus the size of a box fully specify its
+      appearance.  Every single box you see in Ibex is drawn only on the
+      basis of these components and its size.
+    </section>  
+
+    <section title="Size and Position">
+
+      The size and position of every box is determined by its
+      properties, its childrens' sizes, and its parent's size and
+      position.  Box layout and rendering happens in four phases:
+      <i>packing</i>, <i>constraining</i>, <i>placing</i>, and
+      <i>rendering</i>.  The Core is careful to only perform a phase on
+      a box if the box has changed in a way that invalidates the work
+      done the last time that phase was performed.  The packing and
+      constraining phases are performed in a single traversal of the
+      tree (packing is preorder, constraining is postorder), and the
+      placing and rendering phases are performed in a second traversal
+      of the tree (first placing, then rendering, both preorder).
+      
+      For brevity, the rest of this chapter deals only with width and
+      columns.  Height and rows is treated identically and independently.
+      Also, it is important to note that the term <i>minimum width</i> is
+      not the same thing as the property <t>minwidth</t>, although they
+      are closely related.
+      
+      <heading title="The Size of the Root Box"/>
+  
+      When the user resizes a window, Ibex changes the root box's
+      <t>maxwidth</t> and <t>maxheight</t> to match the size chosen by
+      the user and then determines the root box's size using the same sizing
+      rules it uses for other boxes.
+      
+      Ibex will always attempt to prevent the
+      user from making the surface smaller than the root box's
+      <t>minwidth</t> and <t>minheight</t>.  If the <t>hshrink</t> or
+      <t>vshrink</t> flag is set, Ibex will try to prevent the user from
+      resizing the surface at all.  However, not all platforms give Ibex
+      enough control to do this.
+      
+      <image url="alignmentpoint.pdf" caption="The effect of alignment points on layout" width="3in"/>
+    <heading title="The alignment point"/>
+  
+      When talking about positioning, we will often refer to the
+      <i>alignment point</i>.
+      
+          If the <t>align</t> property is "<t>center</t>", then the
+          alignment point is the center of the box.
+          
+          If the <t>align</t> property is "<t>topleft</t>",
+          "<t>bottomleft</t>", "<t>topright</t>", or
+          "<t>bottomright</t>", then the alignment point is
+          corresponding corner of the box.
+          
+          If the <t>align</t> property is "<t>top</t>",
+          "<t>bottom</t>", "<t>right</t>", or "<t>left</t>", then
+          the alignment point is middle of the corresponding edge of the
+          box.
+  
+      When positioning a child box, the alignment point is determined by
+      the <i>parent's</i> <t>align</t> property.  When rendering a
+      visual element (a texture, path, or text string) within a box, the
+      alignment point is determined by the <i>box's own</i> <t>align</t>
+      property.
+      
+      A simple way to think about this is that whenever there are two boxes
+      involved in the decision, you should use the parent's alignment point.
+      
+    <section title="Packing">
+  
+      A grid of <i>cells</i> is created within the parent.  If the
+      parent's <t>cols</t> property is set to 0, the cell grid has an
+      infinite number of columns.  Either <t>cols</t> or <t>rows</t>
+      must be zero, but not both.
+          
+      If a child's <t>visible</t> property is <t>false</t>, it does
+      not occupy any cells (and is not rendered).  Otherwise, each child
+      occupies a rectangular set of cells <t>child.colspan</t> cells
+      wide and <t>child.rowspan</t> cells high.
+          
+      The Core iterates over the cells in the grid in the following
+      order: if <t>rows</t> is 0, the Core iterates across each column
+      before proceeding to the next row; otherwise rows come before
+      columns.  At each cell, the Core attempts to place the <i>first
+      remaining unplaced child's</i> top-left corner in that cell
+      (with the child occupying some set of cells extending down and
+      to the right of that cell).  If the parent has a fixed number of
+      columns and the child's <t>colspan</t> exceeds that limit, the
+      child is placed in column zero regardless, but only occupies the
+      available set of cells (it does not "hang off the end" of the
+      box).  <image url="layout.pdf" width="1in"/>
+      
+      <pre>
+      <ui:box cols="3">
+          <ui:box id="1" />
+          <ui:box id="2" rowspan="2" />
+          <ui:box id="3" colspan="2" />
+          <ui:box id="4" />
+          <ui:box id="5" colspan="2" />
+      </ui:box>
+
+
+
+      </pre>
+      
+      </section>
+  
+    <section title="Constraining">
+  
+          Each box's minimum width is computed recursively as the
+          maximum of:
+  
+          <list>
+              Its <t>minwidth</t>
+               
+              The width of the box's <t>text</t> (after applying the
+              box's <t>transform</t>) [<i>Note: Vector Graphics support
+              (including the <t>transform</t> property) is currently not
+              implemented</i>].
+               
+              The width of the box's path (after applying the box's
+              <t>transform</t>) <i>if the box is <t>packed</t></i>.
+               
+              The width of the bounding box enclosing the box's cells.
+          </list>
+          
+          The minimum width of each cell is computed as the minimum
+          width of the box occupying it divided by the box's
+          <t>colspan</t>.
+          
+          If a box's <t>hshrink</t> property is set to
+          <t>true</t>, the box's maximum width is the same as its
+          minimum width; otherwise it is the box's
+          <t>maxwidth</t>.
+          
+          The maximum width of each cell is the <t>maxwidth</t> of
+          the box occupying it divided by the box's
+          <t>colspan</t>.
+    </section>  
+
+    <section title="Placing">
+  
+          Each column's <i>actual width</i> is set to the maximum
+          <i>minimum width</i> of all the cells in that column.
+          <b>NOTE:</b> although a column or row can be sized smaller
+          than its "minimum width" or larger than its "maximum width", a
+          box will <i>never</i> be smaller than its <t>minwidth</t> or
+          larger than its <t>maxwidth</t>.
+          
+          Each column's maximum width is the largest maximum width of
+          the cells in that column, but no smaller than the column's
+          minimum width.
+  
+          A value <t>k</t> is chosen such that when each column's width
+          is set to <t>min(maximum width, max(minimum width, k))</t>,
+          the sum of all the column widths equals the parent's width.
+          If no such value exists, positive or negative infinity is used
+          (whichever is appropriate).  Each column is then set to the
+          width dictated by <t>k</t>.
+          
+          Next, the rows and columns are positioned within the parent
+          box.  The rows and columns are transformed according to the
+          parent's <t>transform</t> property [<i>Note: Vector Graphics
+          support (including the <t>transform</t> property) is currently
+          not implemented</i>]., and the bounding box of the resulting
+          cells are placed such that the cells' alignment point
+          coincides with the parent's alignment point (both alignment
+          points are determined by the parent's <t>align</t> property).
+      
+          <image url="grid.pdf" caption="Positioning grid cells"/>
+
+          <b>Packed boxes:</b> Each packed box's actual position
+          and size is then set to the aggregation of the actual sizes of
+          the cells it spans.  If this size exceeds the box's maximum
+          width, the box is sized to its maximum width and centered
+          horizontally within the space occupied by its cells.
+  
+          <b>Non-packed boxes</b>: each non-packed box is transformed
+          according to the parent's <t>transform</t> property and then
+          positioned so that its alignment point is <t>(child.x,
+          child.y)</t> pixels from the parent's alignment point (both
+          alignment points are determined by the parent's <t>align</t>
+          property).
+          
+      </section>
+  </section>
+  
+  <section title="Rendering">
+
+    Boxes are rendered in a depth-first, pre-order traversal.  Note that
+    this may cause a non-packed box to overlap its siblings.
+    
+    <list type="ordered">
+        
+        If the box's <t>transform</t> property is non-null, the
+        coordinate space is transformed accordingly for the rest of
+        this phase and for the rendering of all children.  [<i>Note:
+        Vector Graphics support (including the <t>transform</t>
+        property) is currently not implemented</i>].
+        
+        If the box is packed and has a non-<t>null</t> path, the
+        path is translated such that the alignment point of the path's
+        bounding box coincides with the box's alignment point (both
+        alignment points are determined by the box's <t>align</t>
+        property).
+        
+        If a box has a path, that path is filled with the color,
+        gradient, or image specified by the <t>fill</t> property and
+        stroked with the color and width specified by the
+        <t>strokecolor</t> and <t>strokewidth</t> properties.
+        
+        If the box has a non-null <t>text</t> attribute,
+        the text is rendered in <t>font</t> with size
+        <t>fontsize</t> and color <t>textcolor</t>.  The text is
+        then translated such that the alignment point of the text's
+        bounding box coincides with the box's alignment point (both
+        alignment points are determined by the box's <t>align</t>
+        property).
+        
+        The box's children are rendered (pre-order traversal).
+
+    </list>
+    
+    </section>
+
+  </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Box Properties">
+
+  Each box is a full-fledged ECMAscript object, and can store
+  key-value pairs as properties.  Some of these keys have special
+  meaning, which will be explained later.  Each box's numeric
+  properties hold its <i>child boxes</i>.
+
+  <section title="Rendering Properties">
+
+    Every box has several special properties which control how it is
+    drawn. In general, if you put an
+    invalid value to a special property, no action will be taken -- the
+    put will be ignored.
+    
+    <property name="strokecolor" type="string" default="clear">
+
+             If the value is a 5-character hex string (<t>#RGB</t>),
+             7-character hex string (<t>#RRGGBB</t>), 9-character hex
+             string (<t>#AARRGGBB</t>), the box's stroke color will be set
+             to that color. 
+
+             If the value is one of the <link
+             url="http://www.color.org/ICC-1A_1999-04.PDF"
+             text="ICC"/> colors (the same set of color names
+             supported by SVG), the stroke color be set to that color.
+
+             If the value is <t>null</t>, the stroke color will be set
+             to clear (<t>#00000000</t>).
+             </property>
+    
+    <property name="strokewidth" type="int" default="1">
+             The width (in pixels) to stroke the path with.
+             </property>
+    
+    <property name="fill">
+             This property can be set to any of the values specified for
+             <t>strokecolor</t>.  
+             Alternatively, if the value written is an object, its stream
+             will be read and interpreted as a PNG, GIF, or JPEG image,
+             which will become the texture for this box, and the box's
+             <t>minwidth</t> and <t>minheight</t> properties will be
+             automatically set to the dimensions of the image.
+             </property>
+    
+    <property name="path" type="string" default='""'>
+            The box's path.  The grammar and feature set supported are
+            identical to that specified in <link
+            url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
+            section 8"/>.
+            </property>
+    
+    <property name="text" type="string" default='""'>
+            The box's text; writing <t>null</t> to this property sets it
+            to <t>""</t>.
+            </property>
+    
+    <property name="textcolor" type="number" default="black">
+            The color in which to render the font; accepts the same values as <t>strokecolor</t>.
+            </property>
+
+    <property name="font" type="stream" default=".ibex.ui.font.sansserif">
+            When an object is written to this property, its stream is read
+            using the <link url="http://www.freetype.org" text="FreeType 2 library"/>,
+            and the resulting font is used to render the
+            box's <t>text</t>.
+            </property>
+            
+    <property name="fontsize" type="number" default="10">
+            The size (in points) to render the text.
+            </property>
+    
+    </section>
+
+  <section title="Layout Properties">
+    
+    <property name="shrink" type="boolean" default="false">
+        If set to <t>true</t>, this box will shrink
+        (horizontally/vertically/both) to the smallest size allowed by
+        its children and the bounding box of its path.
+        </property>
+    
+    <property name="x y" type="integer" default="varies">
+        If the box is a root box, this is the (x/y)-coordinate of the
+        surface; otherwise it is the distance between the parent's
+        alignment point and this box's alignment point.
+        </property>
+    
+    <property name="minwidth minheight" type="integer" default="0">
+        The desired minimum width and height.
+        </property>
+    
+    <property name="maxwidth maxheight" type="integer" default="ibex.ui.maxdim">
+        The desired maximum width and height.
+        </property>
+    
+    <property name="width height" type="integer">
+        When read, this is the current (width/height) of this box.
+        Writing to this property is equivalent to writing to
+        <i>both</i> the minimum and maximum (width/height).
+        </property>
+    
+    <property name="cols rows" type="integer" default="0">
+        The number of (columns/rows) in which to lay out the children of this
+        box.  If set to zero, the number of (columns/rows) is unconstrained.
+        Either <t>rows</t> or <t>cols</t> must be zero.  If
+        <t>0</t> is written to <t>cols</t> when <t>rows</t> is
+        <t>0</t>, the write is ignored.  If a nonzero value is
+        written to <t>cols</t> when <t>rows</t> is nonzero,
+        <t>rows</t> is set to <t>0</t>, and vice versa.
+        </property>
+    
+    <property name="colspan rowspan" type="integer" default="1">
+        The number of (columns/rows) that this box spans within its parent.
+        </property>
+    
+    <property name="align" type="string" default="center">
+        Determines the box's alignment point for positioning its text,
+        texture, path, and children.
+        </property>
+    
+    <property name="visible" type="boolean" default="true">
+        If set to <t>false</t>, this box will be rendered as if its
+        width and height were zero. If this is a root box, the
+        associated surface will be hidden.
+
+        When reading from this property, the value <t>false</t> will
+        be returned if this box <i>or any of its ancestors</i> is not
+        visible.  Thus it is possible to write <t>true</t> to a box's
+        <t>visible</t> property and then read back <t>false</t>.
+        </property>
+    
+    <property name="packed" type="boolean" default="true">
+        The layout strategy for this box.  If set to <t>true</t>, the
+        box occupies no cells and is laid out independently of its
+        siblings.
+        </property>
+    
+    </section>
+
+  <section title="Child Control Properties">
+    
+    <property name="redirect" type="box" default="thisbox">
+        Writing to this property sets the box's redirect target. This
+        property cannot be read from, and can only be written to if
+        the value being written is a <i>descendant</i> of the current
+        value.
+
+        If a box has a non-null redirect target, reads and writes to
+        any of the other properties in this section will be forwarded
+        to the redirect target.
+
+        The <t>redirect</t> attribute is very useful for hiding the
+        internal structure of a widget, and for allowing widgets to act as
+        "smart" containers for other widgets. For example, a menu widget might
+        have an invisible child as its redirect target; this way, when boxes
+        representing items on the menu are added as children of the menu
+        widget, they do not appear until the menu is pulled down.
+        </property>
+    
+    <property name="numeric properties" type="int" default="">
+        The <i>n</i>th child of box <t>b</t> can be accessed by reading from
+        <t>b[n]</t>. The <i>n</i>th child can be removed by writing
+        <t>null</t> to <t>b[n]</t> (the child will become parentless). A
+        new child can be inserted <i>before</i> the <i>n</i>th child by
+        writing it to <t>b[n]</t>; if the value written is already a child of
+        <t>b</t>, it will be removed from <t>b</t> first. It is important
+        to note that this behavior is different from ECMAscript arrays --
+        writing a non-<t>null</t> value to <t>b[n]</t> does not eliminate
+        the <i>n</i>th child; it merely shifts it over one position.  
+        <b>Note:</b> Unlike most JavaScript objects, enumerating a Box's
+        properties with the JavaScript <t>for..in</t> construct will
+        enumerate <i>only</i> the box's children and not any other properties.
+        </property>
+    
+    <property name="clip" type="boolean" default="true">
+        If <t>true</t>, the visual representation of this box's
+        children will be clipped to the boundaries of this box.
+        <b>Note:</b> setting this property to <t>false</t> imposes a
+        substantial performance penalty.
+        </property>
+    
+    <property name="numchildren" type="integer" default="0">
+        The number of children this box has.
+        </property>
+    
+   
+    <property name="surface" type="" default="null">
+        FIXME
+        If this box has a parent, this property returns
+        <t><i>parent</i>.surface</t>; otherwise it returns null.
+        This property is a simple building block that the widget
+        library uses to implement more complex functionality such as
+        focus control and popups.
+        </property>
+    
+    </section>
+
+  <section title="Other Box Properties">
+    
+    <property name="cursor" type="string" default="null">
+        The shape that the cursor should take when inside this
+        box. Valid values are: "<t>default</t>" , "<t>wait</t>",
+        "<t>crosshair</t>", "<t>text</t>", "<t>hand</t>", and
+        "<t>move</t>", as well as resizing cursors"<t>east</t>",
+        "<t>west</t>", "<t>north</t>", "<t>south</t>",
+        "<t>northwest</t>", "<t>northeast</t>",
+        "<t>southwest</t>", and "<t>southeast</t>". Note that on
+        some platforms, resize cursors for opposite directions (such
+        as <t>northwest</t> and <t>southeast</t> are the
+        same).
+        If a box's cursor is <t>null</t>, its parent's cursor will
+        be used. If the root box's cursor is null, the
+        "<t>default</t>" cursor will be used.
+        </property>
+
+    <property name="static" type="object" default="N/A">
+        Reading from this property will return the parent scope used
+        to execute the <t><static/></t> block of the template
+        in which the currently-executing code resides.
+        </property>
+       
+    <property name="thisbox" type="box" default=" ">
+       Returns a reference to the box itself.
+       If <t>null</t> is written to this property, and this box is
+       the root box of a surface, the box will be detached and the
+       surface destroyed. If this box has a parent, it will be
+       detached from its parent.
+       </property>
+    
+    <property name="indexof()" type="function" default=" ">
+        This property is actually a function; invoking
+        <t>parent.indexof(child)</t> will return the numerical index
+        of <t>child</t> in <t>parent</t> if <t>child</t> is a
+        child of <t>parent</t> (or <t>parent</t>'s redirect
+        target), and <t>-1</t> otherwise. Writing to this property
+        has no effect.
+        </property>
+
+    <property name="distanceto()" type="function" default=" ">
+        This property is actually a function; invoking
+        <t>box.distanceto(otherbox)</t> will return an object with two
+        properties, <t>x</t> and <t>y</t>, containing the horizontal
+        and vertical distance between the two boxes (negative if
+        <t>otherbox</t> is to the left of / above <t>box</t>).  This
+        can be used to determine the relative placement of two boxes
+        on different branches of the box tree.
+        </property>
+
+    </section>
+
+  <section title="Root Box Properties">
+    
+    The following special properties are only meaningful on the root box
+    of a surface.
+    
+    <property name="Focused">
+        The value <t>true</t> is put to this property on the root box
+        when the surface gains the input focus, and <t>false</t> when
+        the surface loses the input focus. Reading from this value will
+        return <t>true</t> if the surface is focused and <t>false</t>
+        if it is not. Putting <t>true</t> to this property will
+        <i>not</i> cause the surface to "steal" the input focus from other
+        windows.
+        </property>
+    
+    <property name="Maximized">
+        The value <t>true</t> is put to this property on the root box
+        when the surface is maximized, and <t>false</t> when the surface
+        is un-maximized. Reading from this value will return <t>true</t>
+        if the surface is maximized and <t>false</t> if it is
+        not. Putting <t>true</t> to this property will maximize the
+        window, and putting <t>false</t> to this property will
+        unmaximize the window.
+        Note that not all platforms support maximization.
+        </property>
+    
+    <property name="Minimized">
+        The value <t>true</t> is put to this property on the root box
+        when the surface is minimized, and <t>false</t> when the surface
+        is unminimized. Reading from this value will return <t>true</t>
+        if the surface is minimized and <t>false</t> if it is
+        not. Putting <t>true</t> to this property will minimize the
+        window, and putting <t>false</t> will unminimize it.
+        </property>
+    
+    <property name="Close">
+        When the user attempts to close a surface, the value
+        <t>true</t> will be put to this property. Scripts may trap
+        this property to prevent the window from closing. Putting the
+        value
+        <t>true</t> to this property on a root box has the same
+        effect as putting <t>null</t> to the <t>thisbox</t>
+        property.
+        </property>
+    
+    <property name="icon">
+        The surface's icon. This is usually displayed on the titlebar of a
+        window.  The value should be an object whose stream is a PNG image. Note
+        that not all platforms support this property.
+        </property>
+    
+    <property name="titlebar">
+        The surface's titlebar text. Note that not all platforms support
+        this property. Only ASCII characters 0x20-0x7F are permitted.
+        </property>
+    
+    </section>
+
+  </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Streams">
+    
+    <heading title="Every object has a stream..."/>
+
+    Every object has a <i>stream</i> associated with it.  A stream is a
+    sequence of bytes that can be read or written to.
+    
+    By default an object has an empty stream (zero bytes).  However, some objects
+    (returned from special methods on the <t>ibex</t> object) have
+    streams yielding data read from an url, file, or a component of a zip
+    archive.  In a future release, the stream associated with a box will
+    be an .ibex template which, when applied, will fully reconstitute the
+    box's state.
+    
+    <heading title="...but streams are not objects"/>
+    
+    Despite the ubiquity of streams, you cannot actually reference a
+    stream, since it is not an object.  Instead, you simply reference the
+    object it belongs to.  If you are familiar with Java, this is similar
+    to how every Java object has a monitor associated with it, but you
+    cannot directly manipulate the monitor (you can't pass around a
+    reference to just the monitor).
+    
+    In the rest of the section we will sometimes refer to "getting
+    properties from a stream" or "passing a stream to a function"; this is
+    just shorthand for saying to perform those actions on the object the
+    stream belongs to.
+    
+  <section title="Creating Streams from URLs">
+    
+    You can create a stream from a URL by calling
+    
+    <pre>
+    var r = ibex.stream.url("http://...");
+    </pre>
+    
+    This will return an object whose stream draws data from the specified
+    URL.  Streams are loaded lazily whenever possible.
+    
+    </section>
+
+  <section title="Getting Substreams">
+
+    Most stream objects let you access
+    substreams using the usual JavaScript operators <t>[]</t> and
+    <t>.</t>, as well as the <t>for..in</t> syntax.
+    
+    <pre>
+    // r1 and r2 are equivalent but not equal (!=)
+    var r1 = ibex.stream.url("http://www.ibex.org/foo/bar.html");
+    var r2 = ibex.stream.url("http://www.ibex.org/foo")["bar.html"];
+    </pre>
+    
+    </section>
+
+  <section title="The Root Stream">
+
+    The empty-string property on the <t>ibex</t> object is called the
+    <i>root stream</i>.  You can access this object as <t>ibex..</t> or
+    <t>ibex[""]</t>.  Additionally, any expression which starts with a
+    dot is treated as property to be retrieved from the root stream.  The
+    following three expressions are equivalent:
+    
+    <pre>
+    ibex..foo
+    ibex[""].foo
+    .foo
+    </pre>
+
+    </section>
+
+  <section title="Static Blocks">
+
+    FIXME
+
+    You can access variables within the static block of a template by
+    appending a double period (<t>..</t>) and the variable name to the
+    stream used to load that template:
+    
+    <pre>
+    <!-- org/ibex/themes/linux/scrollbar.ibex -->
+            foo = 12;
+    ...
+    // elsewhere
+    ibex.log.print(org.ibex.themes.linux.scrollbar..foo);  // prints "12"
+    </pre>
+    
+    </section>
+
+  <section title="Formatting Streams">
+
+    If you attempt to send a stream as part of an XML-RPC call, the
+    stream will be read in its entirity, Base64-encoded, and transmitted
+    as a <t><base64/></t> element.
+    
+    Ibex supports two special URL protocols.  The first is <t>data:</t>,
+    which inteprets the rest of the URL as a Base64 encoded sequence of
+    bytes to use as a source.  The other is <t>utf8:</t> which
+    interpretets the rest of the string as a Unicode character sequence to
+    be UTF-8 encoded as a string of bytes to use as a source.
+    
+    <pre>
+    var r5 = ibex.stream.url("data:WFWE876WEh99sd76f");
+    var r6 = ibex.stream.url("utf8:this is a test");
+    </pre>
+
+    You can read a UTF-8 encoded string from a stream like this:
+    
+    <pre>
+    var myString = ibex.stream.fromUTF(ibex.stream.url("utf8:testing..."));
+    </pre>
+    You can also parse XML from a stream using SAX like this:
+    
+    <pre>
+    ibex.stream.xml.sax(
+      ibex.stream.url("http://foo.com/foo.xml"),
+        { beginElement : function(tagname, attributeKeyValuePairs) { ... },
+          endElement   : function(tagname) { ... },
+          content      : function(contentString) { ... }
+          whitespace   : function(whitespaceString) { ... }
+        });
+    </pre>
+    
+    </section>
+
+  </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="The Ibex object">
+
+    The <t>ibex</t> object is present in the top-level scope of every
+    script.  It has the following properties:
+    
+  <heading title="General"/>
+
+    <property name="ibex.box">
+        reading from this property returns a new box
+        </property>
+    <property name="ibex.clone(o)">
+        creates a clone of object
+        </property>
+    <property name="ibex.bless(s)">
+        returns a blessed clone of stream
+        </property>
+
+  <heading title="ECMA Library Objects"/>
+
+    <property name="ibex.date">
+        reading from this property returns a new date
+        </property>
+    <property name="ibex.math">
+        this object contains the ECMA math functions
+        </property>
+    <property name="ibex.regexp(s)">
+        return a regexp object corresponding to string <i>s</i>
+        </property>
+    <property name="ibex.string">
+        this object contains the ECMA string manipulation functions
+        </property>
+
+  <heading title="Logging"/>
+
+    <property name="ibex.log.debug(m1, ... mn)">
+        log the debug messages <i>m1</i> through <i>mn</i>.
+        <i>o</i>
+        </property>
+
+    <property name="ibex.log.info(m1, ... mn)">
+        log the info messages <i>m1</i> through <i>mn</i>.
+        </property>
+
+    <property name="ibex.log.warn(m1, ... mn)">
+        log the warning messages <i>m1</i> through <i>mn</i>.
+        </property>
+
+    <property name="ibex.log.error(m1, ... mn)">
+        log the error messages <i>m1</i> through <i>mn</i>.
+        </property>
+
+    <heading title="User Interface"/>
+
+    <property name="ibex.ui.browser(u)">
+        opens a new browser window with URL <i>u</i>
+        </property>
+
+    <property name="ibex.ui.key.control">
+        true if the control key is depressed
+        </property>
+
+    <property name="ibex.ui.key.shift">
+        true if the shift key is depressed
+        </property>
+
+    <property name="ibex.ui.key.alt">
+        true if the alt key is depressed
+        </property>
+
+    <property name="ibex.ui.key.name.alt">
+        the name of the "alt" key (usually either "alt", "meta", or
+        "option")
+        </property>
+
+    <property name="ibex.ui.clipboard">
+        the contents of the clipboard; can be read and written to
+        </property>
+
+    <property name="ibex.ui.maxdim">
+        the maximum dimension of any UI element; usually
+        2<sup>31</sup>, but may be smaller
+        </property>
+
+    <property name="ibex.ui.screen.width">
+        the width of the screen, in pixels
+        </property>
+
+    <property name="ibex.ui.screen.height">
+        the height of the screen, in pixels
+        </property>
+
+    <property name="ibex.ui.mouse.button">
+        either 0, 1, 2, or 3, indicating the mouse button currently
+        being pressed
+        </property>
+
+    <property name="ibex.ui.frame">
+        when a box is written to this property, it becomes the root
+        box of a new window
+        </property>
+
+    <property name="ibex.ui.window">
+        when a box is written to this property, it becomes the root
+        box of a new frame
+        </property>
+
+    <property name="ibex.ui.font.serif">
+        an object whose stream is a a builtin serif font
+        </property>
+
+    <property name="ibex.ui.font.sansserif">
+        an object whose stream is a builtin sans-serif font
+        </property>
+
+    <property name="ibex.ui.font.monospace">
+        an object whose stream is a a builtin fixed-width font
+        </property>
+
+  <heading title="Networking"/>
+
+    <property name="ibex.net.rpc.xml(u)">
+        return an XML-RPC call object with endpoint URL <i>u</i>
+        </property>
+
+    <property name="ibex.net.rpc.soap(u,">
+        return a SOAP call object with endpoint URL <i>u</i>,
+        SoapAction <i>a</i>, and XML Namespace <i>n</i>
+        </property>
+
+  <heading title="Threads"/>
+
+    <property name="ibex.thread">
+        when a function is written to this property, a new thread is
+        forked to call it
+        </property>
+
+    <property name="ibex.thread.yield()">
+        yield the current thread
+        </property>
+
+    <property name="ibex.thread.sleep(n)">
+        sleep for <i>n</i> milliseconds
+        </property>
+
+  <heading title="Streams"/>
+
+    <property name="ibex.stream.url(u)">
+         returns a new object whose stream is drawn from URL <i>u</i>
+        </property>
+
+    <property name="ibex.stream.unzip(s)">
+        unpacks a zip archive from <i>s</i>'s stream
+        </property>
+
+    <property name="ibex.stream.uncab(s)">
+        unpacks a cab archive from <i>s</i>'s stream
+        </property>
+
+    <property name="ibex.stream.cache(s,k)">
+        valign=top>wraps a disk-backed read cache keyed on <i>k</i>
+        around <i>s</i>'s stream
+        </property>
+
+    <property name="ibex.stream.watch(s,f)">
+        returns an object whose stream is drawn from <i>s</i>'s
+        stream, but invokes <i>f(n,d)</i> as it is read from.
+        </property>
+
+    <property name="ibex.stream.parse.xml(s, h)">
+        Use SAX to parse the XML document on stream <i>s</i> with
+        handler <i>h</i>
+        </property>
+
+    <property name="ibex.stream.parse.html(s, h)">
+        Same as <t>parse.xml()</t>, but tries to fix broken HTML.
+        </property>
+
+    <property name="ibex.stream.parse.utf8(s)">
+        treat <i>s</i>'s stream as a string encoded as a UTF-8 byte stream and return the string
+        </property>
+
+    <property name="ibex.stream.homedir">
+        <t>ibex.stream.tempdir</t>
+        </property>
+
+  <heading title="Cryptography"/>
+
+    <property name="ibex.crypto.rsa(k,s)">
+        <i>not implemented yet:</i> return a
+        stream which rsa-decrypts stream <i>s</i> with key <i>k</i>
+        </property>
+
+    <property name="ibex.crypto.rc4(k,s)">
+        <i>not implemented yet:</i> return a
+        stream which rc4-decrypts stream <i>s</i> with key <i>k</i>
+        </property>
+
+    <property name="ibex.crypto.md5(s)">
+        <i>not implemented yet:</i> immediately
+        MD5-hash stream <i>s</i>
+        </property>
+
+    <property name="ibex.crypto.sha1(s)">
+        <i>not implemented yet:</i> immediately
+        SHA1-hash stream <i>s</i>
+        </property>
+
+</section>
+<!-- ----------------------------------------------------------------------- -->
+<section title="Traps">
+
+    You can add a trap to a property by applying the <t>++=</t> operator
+    to a function with one argument.  The trap will be invoked whenever
+    that property is written to.
+    
+    <pre>
+    <ui:box>
+        foo ++= function(z) {
+           ibex.log.info("foo is " + z);
+        }
+    </ui:box>
+    </pre>
+
+    If another script were to set the property "<t>foo</t>"
+    on the box above to the value <t>5</t>, the function above would be
+    invoked with the argument <t>5</t>. The function would then log
+    the string "<t>foo is 5</t>".
+    
+    Within a trap, the expression <t>trapee</t> can be used to
+    get a reference to the box on which the trap was placed.
+    
+    The expression <t>trapname</t> returns the name of the
+    trap executing the current function. This is useful when a function
+    is applied to multiple traps. For example:
+    
+    <pre>
+    <ui:box>
+        func ++= function(z) {
+            ibex.log.info("called trap " + trapname);
+        }
+        foo ++= func;
+        bar ++= func;
+    </ui:box>
+    </pre>
+    
+  <section title="Removing Traps">
+
+    You can remove a trap by using the <t>--=</t> operator with the same
+    function you added as a trap:
+    
+    <pre>
+    <ui:box>
+        var myfunc = function(z) { /* ... */ }
+        // add the trap
+        func ++= myfunc;
+        // ...
+        // remove the trap
+        func --= myfunc;
+    </ui:box>
+    </pre>
+    
+    </section>
+
+  <heading title="Multiple Traps on the Same Property"/>
+
+    When the trapped property is <i>written</i> to, each of the trap
+    functions placed on it will be invoked in the opposite order that
+    they were placed on the box -- the most recently placed trap will
+    execute first. This last-to-first execution of traps is called
+    <i>cascading</i>. After the last trap is invoked, the value is
+    stored on the box (remember, boxes are objects, so they can hold
+    properties just like all other ECMAscript objects).
+    
+  <section title="Manual Cascades">
+
+    There are two additional tricks you can use when placing traps. The
+    first is a <i>manual cascade</i>. If you want to cascade to lower
+    traps in the middle of a function, or you want to cascade with a
+    different value than the value passed to you (in effect "lying" to
+    lower traps), you can use <t>cascade</t>. For example:
+    
+    <pre>
+    <ui:box color="black">
+        color ++= function(c) {
+            ibex.log.info("refusing to change colors!");
+            cascade = "black";
+        }
+    </ui:box>
+    </pre>
+
+    This effectively creates a box whose color cannot be changed, and
+    which complains loudly if you try to do so.
+    
+    Do <i>not</i> try to do something like this:
+    
+    <pre>
+    <ui:box color="black">
+        color ++= function(z) {
+            color = "black";      // INFINITE LOOP! BAD!!!
+        }
+    </ui:box>
+    </pre>
+    To prevent automatic cascading, return <t>true</t> from your function:
+    
+    <pre>
+    <ui:box color="black">
+        color ++= function(z) {
+            return true;          // the box's color will not change
+        }
+    </ui:box>
+    </pre>
+
+    </section>
+
+  <section title="Read Traps">
+
+    The other trick is a <i>read-trap</i>. Read traps are just like normal
+    traps, except that you  use a function that takes zero arguments instead of one. Read traps
+    also do not automatically cascade.
+    
+    <pre>
+    <ui:box>
+        doublewidth <t>++=</t> function() { return 2 * width; }
+    </ui:box>
+    </pre>
+
+    If another script attempts to read from the <t>doublewidth</t>
+    property on this box, the value it gets will be twice the actual width
+    of the box.  Note that
+    the actual <t>doublewidth</t> property on the box never gets written
+    to, since the trap does not cascade.
+    
+    You can manually cascade on read traps as well:
+    
+    <pre>
+    <ui:box>
+        text <t>++=</t> function() { return "my text is " + cascade; }
+    </ui:box>
+    </pre>
+
+    Read traps are only rarely needed -- most of the time a write trap
+    should be enough.
+    
+    </section>
+
+  <heading title="Prohibited Traps"/>
+
+    To prevent confusing and hard-to-debug behaviors, scripts may not
+    place traps on any of the properties described in the sections
+    <link text="Box Layout Properties" section="Layout Properties"/>, <link
+    section="Child-Control Properties"/>, or <link section="Other Box
+    Properties"/> except for <t>childadded</t>,
+    <t>childremoved</t> and <t>surface</t>.  FIXME: remove?
+    
+  <heading title="Exceptions and Traps"/>
+
+    If an uncaught exception is thrown from a trap, Ibex will log the
+    exception, but will <i>not</i> propagate it to the code which
+    triggered the trap. If the trap was a read trap, the value
+    <t>null</t> will be returned.
+    FIXME: is this right?
+
+  <heading title="Architectural Significance of Traps"/>
+
+    Traps are the backbone of Ibex. Since almost all UI programming is
+    event/demand driven, traps eliminate the need for separate
+    member/getter/setter declarations, often cutting the amount of typing
+    you have to do to a third of what it would normally be.
+
+  <section title="Cloning">
+
+    <i>Cloning</i> is a companion technique for traps; together they can
+    be used to simulate any sort of environment you might need.  When you
+    call <t>ibex.clone(o)</t>, Ibex returns a new object (called the
+    <i>clone</i>) which compares with equality (<t>==</t>) to the
+    original object.  Furthermore, both objects are "equal" as keys in
+    hashtables, so:
+    
+    <pre>
+    var hash = {};
+    var theclone = ibex.clone(o);
+    hash[o] = 5;
+    ibex.log.info(hash[theclone]);    // prints "5"
+    </pre>
+
+    Any writes to properties on the clone will actually write to
+    properties on the original object, and reads from properties on the
+    clone will read properties on the original object.  In fact, the only
+    thing that can be used to distinguish the original from the clone is
+    traps -- a trap placed on the clone is <i>not</i> placed on the
+    original object as well.
+    
+    </section>
+
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Threads">
+
+  <section title="Contexts">
+
+    From the perspective of an application writer, Ibex is strictly
+    single-threaded.  Ibex is always in exactly one of the following three
+    <i>contexts</i>:
+    
+    <list type="unordered">
+
+        <b>Rendering Context</b> -- (redrawing the screen)
+        
+        <b>Event Context</b> (executing javascript traps triggered by an event)
+        
+        <b>Thread Context</b> (executing a background thread spawned with <t>ibex.thread</t>)
+
+    </list>
+    
+    There are two important restrictions on what can be done in particular contexts:
+    
+    <list type="unordered">
+
+        The <t>box.mouse</t> property and its subproperties
+        (<t>x</t>, <t>y</t>, and <t>inside</t>) can only be read
+        from within the Event Context, or in a thread context
+        <i>after</i> a the <t>box.mouse</t> property on this box or
+        an ancestor box has been written to.
+        
+        Blocking operations (anything that accesses the network or
+        disk) can only be performed in the Thread Context.
+
+    </list>
+
+    </section>
+
+  <section title="Background Threads">
+
+    Ibex offers easy access to threads. Spawning a background thread is as
+    simple as writing a function to the <t>ibex.thread</t> property:
+    
+    <pre>
+    ibex.thread = function() {
+        ibex.log.info("this is happening in a background thread!");
+    }
+    </pre>
+
+    The argument set passed to the function is currently undefined and is
+    reserved for use in future versions of Ibex. Scripts should not
+    depend on the number or content of these arguments.
+    
+    Ibex is <i>cooperatively multitasked</i>, so threads must not process
+    for too long.  This was a deliberate choice; cooperatively
+    multitasked environments do not require complex locking primitives
+    like mutexes and semaphores which are difficult for novices to
+    understand.  The disadvantage of cooperative multitasking is that one
+    thread can hog the CPU.  This is unlikely to happen in Ibex for two reasons:
+    first, all blocking I/O operations <i>automatically</i> yield the CPU,
+    so the overall user interface never becomes unresponsive because it is
+    waiting for a disk or network transfer.  Second, since Ibex is strictly
+    a user interface platform, Ibex scripts are unlikely to perform highly
+    compute-intensive operations that keep the CPU busy for more than a
+    few milliseconds.
+    
+    </section>
+</section>
+
+<section title="Events">
+
+    Every execution of the Event Context begins with an event, which
+    consists of a key/value pair, and a mouse position, which consists of
+    an x and y coordinate.  The possible keys are <t>_Press[1-3]</t>,
+    <t>_Release[1-3]</t>, <t>_Click[1-3]</t>, <t>_DoubleClick[1-3]</t>,
+    <t>_Move</t>, <t>_KeyPressed</t>, and <t>_KeyReleased</t>.
+    
+    Here are two example events:
+    
+    An event is triggered by writing the key to the value on a box.  This
+    triggers any trap handlers which may be present.  Once these handlers
+    have executed, Ibex figures out which child of the current box contains
+    the mouse (taking into account that some boxes may cover up others)
+    and writes the key and value to that box.  If none of the box's
+    children contain the mouse position, Ibex removes the leading
+    underscore from the key name and writes the value to
+    <i>that</i> property.  Once all the traps on that property have
+    executed, the value is written to the box's parent.
+    
+    Intuitively, Ibex delivers the underscored event to every box from the
+    root to the target, and then delivers the non-underscored event to
+    that same set of boxes in reverse order.  So the event travels down
+    the tree to the target, and then back up to the root.  The following
+    example prints out "first second third fourth" in that order.
+    
+    <pre>
+    <ui:box>
+        _Press1 ++= function(b) { ibex.log.info("first"); }
+         Press1 ++= function(b) { ibex.log.info("fourth"); }
+        <ui:box>
+          _Press1 ++= function(b) { ibex.log.info("second"); }
+           Press1 ++= function(b) { ibex.log.info("third"); }
+        </ui:box>
+    </ui:box>
+    </pre>
+
+    In general, you should use the <i>non-underscore</i> names to respond
+    to user input and use the underscored names when you want to override
+    child boxes' behavior or route events to particular boxes (for
+    example, when implementing a focus protocol).  This is why the
+    underscored elements are delivered to parents before children (so
+    parents can override their childrens' behavior), but non-underscored
+    events are delivered to children before parents (since, visually, a
+    mouse click is usually "intended" for the leaf box underneath the
+    cursor).
+    
+    </section>
+
+  <heading title="Stopping the Process"/>
+
+    At any point in this sequence, a trap handler can choose not to
+    cascade (by returning <t>true</t> from the trap handler function).
+    This will immediately cease the propagation of the event.  This is how
+    you would indicate that an event has been "handled".
+    
+  <heading title="Non-Propagating Events"/>
+
+    Ibex uses the following events to notify a box about changes that
+    only matter to that particular box.  These events do not propagate
+    either up or down the tree.
+
+    <property name="Enter Leave">
+        The value <t>true</t> is written to this property when the mouse (enters/leaves) the box.
+        </property>
+    
+    <property name="SizeChange">
+        The value <t>true</t> is put to this property after the size
+        of this box changes.
+        </property>
+
+    <property name="ChildChange">
+        When a child is added or removed, that child is written to
+        this property.  The write is always performed <i>after</i> the
+        addition or removal, so these two cases can be distinguished
+        by checking <t>indexof(child)</t>.
+
+        Note that if the parent's redirect target is set to another
+        box, this trap will only be invoked when children are
+        manipulated by reading and writing to the parent.  Reads and
+        writes directly to the redirect target will <i>not</i> trigger
+        this trap.
+
+        Note also that this traps is still triggered if a box's
+        <t>redirect</t> target is <i>null</i>.  This is useful for
+        boxes that need to accept children and then relocate them
+        elsewhere.
+        </property>
+    
+  <section title="Listing of Events">
+    
+    <property name="Press1 Press2 Press3">
+        Indicates that the use has pressed a mouse button.  On
+        platforms with three mouse buttons, the <i>middle</i> button
+        is button 3 -- this ensures that applications written to only
+        use two buttons (1 and 2) will work intuitively on three button
+        platforms.
+        </property>
+    
+    <property name="Release1 Release2 Release3">
+        Indicates that the use has released a mouse button.
+        </property>
+    
+    <property name="Click1 Click2 Click3">
+        Indicates that the user has pressed and released the
+        mouse button without moving the mouse much (exactly how
+        much is platform-dependent).
+        </property>
+    
+    <property name="DoubleClick1 DoubleClick2 DoubleClick3">
+        Indicates that the user has clicked the 
+        mouse button twice within a short period of time (exactly how long is platform-dependent).
+        </property>
+    
+    <property name="Move">
+        Indicates that the mouse has moved while within this box, or that
+        the mouse while outside this box <i>if a button was pressed while within this box and has not yet been released</i>
+        </property>
+    
+    <property name="KeyPressed KeyReleased">
+
+        A string is written to this property when a key is pressed or
+        released If the key was any other key, a multi-character
+        string describing the key will be put. For simplicity, we use
+        the VK_ constants in the <link
+        url="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.event.KeyEvent.html#VK_0"
+        text=" Java 1.1 API java.awt.event.KeyEvent class"/>.  When a
+        key is pressed or released, the string put will be the portion
+        of its VK_ constant after the underscore, all in lower case.
+
+        <list>
+        If the shift key was depressed immediately before the
+        event took place, then the string will be capitalized. Special
+        keynames are also capitalized; shift+home is reported as
+        "<t>HOME</t>".  Symbols are capitalized as they appear on the
+        keyboard; for example, on an American QWERTY keyboard, shift+2
+        is reported as "<t>@</t>".
+
+        If the alt, meta, or command key was depressed immediately
+        before this key was pressed, then the string will be prefixed
+        with the string "<t>A-</t>". If the control key was depressed
+        while this key was pressed, then the string will be prefixed
+        with the string "<t>C-</t>". If both alt and control are
+        depressed, the string is prefixed with "<t>C-A-</t>".
+
+        Ibex does not distinguish between a key press resulting from
+        the user physically pushing down a key, and a 'key press'
+        resulting from the keyboard's typematic repeat. In the rare
+        case that an application needs to distinguish between these
+        two events, it should watch for KeyReleased messages and
+        maintain an internal key-state vector.
+        </list>
+        </property>
+
+    </section>
+
+</section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Networking">
+    
+  <section title="XML-RPC">
+    
+    XML-RPC objects can be created by calling <t>ibex.net.rpc.xml(<i>XML-RPC
+    URL</i>)</t>, and then invoking methods on that object. For example,
+    
+    <pre>
+    Press1 += function(v) {
+        ibex.thread = function() {
+            color = ibex.net.rpc.xml("http://xmlrpc.ibex.org/RPC2/").
+                       color.getTodaysColor("Friday");
+        }
+    }
+    </pre>
+    
+    When the user clicks the first mouse button on this box, it will
+    contact the server <t>xmlrpc.ibex.org</t>, route to the
+    <t>/RPC2/</t> handler and invoke the <t>getTodaysColor()</t>
+    method on the <t>color</t> object with a single string argument
+    "<t>Friday</t>". The return value will be used to change the color
+    of the box the user clicked on.
+    
+    Note that in this example we spawned a background thread to handle the
+    request -- the <t>Press1</t> event is delivered in the foreground
+    thread, and XML-RPC methods may only be invoked in background
+    threads. This is to prevent the UI from "locking up" if the server
+    takes a long time to reply.
+    
+    If the XML-RPC method faults, an object will be thrown with two
+    properties: <t>faultCode</t> and <t>faultString</t>, as defined in
+    the <link url="http://www.xmlrpc.org/spec" text="XML-RPC specification"/>. If
+    Ibex encounters a network, transport, or session-layer error, it will
+    throw a <t>String</t> object describing the error in a
+    human-readable format. Scripts should not rely on the contents of
+    this string having any special structure or significance.
+    
+    If an object with an associated non-empty stream is passed as an
+    argument to an XML-RPC method, it will be sent as a <base64/>
+    element. If a <base64/> element is found in the XML-RPC reply, it
+    will be returned as an object with a stream drawn from that byte sequence.
+    
+    Each object returned by <t>ibex.net.rpc.xml()</t> represents a
+    single HTTP connection.  The connection will be held open until
+    the object is garbage collected or the server closes the
+    connection.  If a second call is issued on the object before the
+    first one returns (usually from a seperate thread), the two calls
+    will be <link
+    url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.2.2"
+    text="pipelined"/>.  This can dramatically improve performance.
+    
+    Ibex supports HTTP Basic and Digest authentication. To use
+    authentication, pass <t>ibex.net.rpc.xml()</t> a URL in the form
+
+    <pre>
+       http[s]://user:password@hostname/
+    </pre>
+
+    Ibex will use Digest authentication if the server supports it;
+    otherwise it will use Basic authentication.  Please be aware that
+    many XML-RPC server implementations contain a <link
+    url="http://www.ibex.org/faq.html#auth" text="broken
+    implementation of Basic authentication"/>.
+    
+    </section>
+
+  <section title="SOAP">
+    
+    SOAP methods are invoked the same way as XML-RPC methods, but with three differences:
+    
+    <list type="ordered">
+
+        <t>ibex.net.rpc.soap()</t> is used instead of
+        <t>ibex.net.rpc.xml()</t>
+        
+        Instead of specifying just the URL of the service itself, you
+        must specify the URL, the SOAPAction argument, and the
+        namespace to use.
+        
+        The actual method invocation takes only one argument, which
+        must be an object. This is necessary since SOAP arguments are
+        specified by name, rather than ordering.
+
+    </list>
+    
+    SOAP faults are handled the same way as XML-RPC faults except that the
+    capitalization of the <t>faultstring</t> and <t>faultcode</t>
+    members is all lower-case, to match the SOAP spec. Here is a
+    SOAP example:
+    
+    <pre>
+    Press1 ++= function(v) {
+        ibex.thread = function() {
+            color = ibex.net.rpc.soap("http://soap.ibex.org/SOAP",
+                                     "GETTODAYSCOLOR",            
+                                     "http://ibex.org/namespace"  
+                                ).color.getTodaysColor( {
+                                    whichday : Friday
+                                } );
+        }
+    }
+    </pre>
+
+    As you can see, SOAP is much more verbose, yet does not offer
+    substantially improved functionality. We recommend that XML-RPC be
+    used whenever possible, and that SOAP be reserved for legacy
+    applications.
+    
+    The current Ibex SOAP stack does not support 'document style' or
+    multi-ref (<t>href</t>) data structures.
+    
+    </section>
+
+  <section title="Security">
+
+    Applications downloaded from the network (as opposed to those loaded
+    from the filesystem) may only make certain kinds of connections to
+    certain hosts.  See Appendix A for a detailed description of the
+    security policy.
+    
+    </section>
+
+  </section>
+<!-- ----------------------------------------------------------------------- -->
+<section title="Error Handling">
+
+    If the Ibex Core encounters an error while servicing a function call
+    originating in JavaScript, the core will throw a string consisting of
+    an error code followed by a colon, a space, and a descriptive message.
+    For example:
+    
+    <pre>
+    "ibex.net.dns.unknownhostexception: unable to resolve host foo.com"
+    </pre>
+
+    The code should be used to determine how the program should respond to
+    an error.  The codes are organized in a hierarchy, so the
+    string.startsWith() method can be used to determine if an error lies
+    within a particular subhierarchy.  The descriptive message portion of
+    the string may be shown to the user.
+    
+    <property name="ibex.assertion.failed">
+        an assertion failed
+        </property>
+    <property name="ibex.io">
+        General I/O exceptions
+        </property>
+    <property name="ibex.io.encoding">
+        Error translating between character encodings.
+        </property>
+    <property name="ibex.io.zip">
+        Attempted to access a corrupt zip archive.
+        </property>
+    <property name="ibex.io.eof">
+        End of file encountered unexpectedly
+        </property>
+    <property name="ibex.net.security.prohibitedHost">
+        A piece of untrusted Ibex code attempted to contact a
+        restricted host.  See <link appendix="Security Architecture and Considerations"/> for details.
+        </property>
+    <property name="ibex.net.dns.temporaryFailure">
+        An attempt to resolve a hostname failed but it is not known
+        for certain that the hostname is invalid.
+        </property>
+    <property name="ibex.net.dns.unknownHost">
+        An attempt to resolve a hostname failed because the hostname
+        was invalid.
+        </property>
+    <property name="ibex.net.socket.closed">
+        A socket was closed unexpectedly.
+        </property>
+    <property name="ibex.net.socket.connectionFailed">
+        A connection could not be made to the remote host.
+        </property>
+    <property name="ibex.net.url.malformed">
+        Tried to parse a malformed URL.
+        </property>
+    <property name="ibex.net.ssl">
+        General SSL protocol errors.
+        </property>
+    <property name="ibex.net.ssl.untrustedCertificate">
+        The server's certificate was not signed by a CA trusted by Ibex.
+        </property>
+    <property name="ibex.net.http.">
+        Thrown when an HTTP error code is returned during an
+            operation.  The three characters <t><i>xyz</i></t> will be
+            the three-digit HTTP status code.
+        </property>
+    <property name="ibex.net.xmlrpc.null">
+        The caller attempted to transmit the <t>null</t> value via XML-RPC.
+        </property>
+    <property name="ibex.net.xmlrpc.circular">
+        The caller attempted to transmit a circular data structure via XML-RPC.
+        </property>
+    <property name="ibex.net.xmlrpc.specialObject">
+        The caller attempted to transmit a "special" object via
+        XML-RPC (for example, a Box or the Ibex object).
+        </property>
+    <property name="ibex.null.put">
+        A JavaScript attempted to put to a property on the <t>null</t> value
+        </property>
+    <property name="ibex.null.get">
+        A JavaScript attempted to get from a property on the <t>null</t> value
+        </property>
+    <property name="ibex.null.call">
+        A JavaScript attempted to call the <t>null</t> value
+        </property>
+    
+    If an exception is thrown inside a trap, the exception will propagate
+    to the script that triggered the trap.
+    
+    If an uncaught exception is thrown while applying a template, or the
+    requested template could not be found, an error will be logged and the
+    box to which the template was being applied will be made invisible
+    (<t>visible = false</t>).  This ensures that half-applied widgets are
+    never shown to the user.
+    
+  </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Advanced Topics">
+
+  <section title="Re-routing events">
+
+    At any point in the Event Context, you can write to the <t>mouse</t>
+    property on any box.  The value written should be an object with two
+    properties, <t>x</t> and <t>y</t>.  For example:
+    
+    <pre>
+    _Press1 ++= function(p) {
+        mouse = { x: 32, y: 77 };
+    }
+    </pre>
+
+    The coordinates specified are relative to the box whose <t>mouse</t>
+    property is being written to.  There is no need to supply the
+    <t>inside</t> property; it is computed automatically.  Writing to
+    the <t>mouse</t> property causes Ibex to recompute the eventual
+    target box, and also alter the values returned by <t>mouse.x</t>,
+    <t>mouse.y</t>, and <t>mouse.inside</t> for any <i>descendants</i>
+    of the current box.  Writing to the <t>mouse</t> property also
+    automatically prevents the event from returning to the box's parents
+    -- it is equivalent to not cascading on the non-underscored event.
+    This ensures that child boxes cannot trick their parent boxes into
+    thinking that the mouse has moved.
+    
+    If you want the event to "skip over" the boxes between the trapee
+    and the target, or if you want to re-route an event to a box which
+    is not a descendant of the current box, simply write the value to
+    the proper key on the target box.
+    
+    <pre>
+    <ui:box>
+        _KeyPressed = function(k) { ibex.log.info("first"); }
+         KeyPressed = function(k) { ibex.log.info("sixth"); }
+        $recipient.target = $target;
+        <ui:box id="recipient">
+            _KeyPressed = function(k) {
+                ibex.log.info("second");
+                thisbox.target.KeyPressed = k;
+                // inhibit cascade; keep event from going to $excluded
+                return true;
+            }
+             KeyPressed = function(k) { ibex.log.info("fifth"); }
+            <ui:box id="excluded">
+                _KeyPressed = function(k) {
+                   ibex.log.info("this never happens");
+                }
+            </ui:box>
+        </ui:box>
+        <ui:box id="target"> 
+            _KeyPressed = function(k) { ibex.log.info("third"); }
+             KeyPressed = function(k) { ibex.log.info("fourth"); }
+        </ui:box>
+    </ui:box>
+    </pre>
+
+    </section>
+
+  <section title="Synthesizing Your Own Events">
+
+    You can create "fake events" by simply writing to the <t>mouse</t>
+    property and then writing a value to one of the underscored properties
+    on a box.  This will have exactly the same effect as if the use had
+    actually pressed a key, clicked a button, or moved the mouse -- they
+    are indistinguishable.
+    
+    </section>
+
+  <section title="Ibex self-emulation">
+
+    When the core first starts up, it clones the <t>ibex</t> object,
+    creates a stream for the initial .ibex, and then places a trap on the
+    cloned <t>ibex</t> object so that its empty-string property returns
+    the .ibex stream.  The cloned Ibex object is then passed as the third
+    (optional) argument to <t>ibex.apply()</t>, making it the default
+    <t>ibex</t> object for the scripts that are executed as part of the
+    template instantiation.
+    
+    <pre>
+    var new_ibex = ibex.clone(ibex);
+    var stream = ibex.bless(ibex.stream.url("http://..."));
+    new_ibex[""] ++= function() { return stream; }
+    ibex.apply(ibex.box, new_ibex..main, new_ibex);
+    </pre>
+
+    Note that we called <t>ibex.bless()</t> on the stream before tacking
+    it on to the new Ibex object.  The bless function returns a clone of
+    the object passed to it, with a few traps which are explained below.
+    Additionally, any sub-streams retrieved by accessing properties of the
+    blessed stream will also automatically be blessed (blessed streams are
+    <i>monadic</i>).
+    
+    Blessing a stream serves three purposes:
+    
+    <list type="unordered">
+        
+        Blessed clones always return the appropriate static block when
+        their empty property is accessed; this ensures that references
+        to the static blocks of other templates work properly.
+        
+        Blessed substreams can return their parent stream by accessing
+        a hidden property which is reserved for internal use by Ibex.
+        This ensures that Ibex can automatically add filename
+        extensions where needed, according to the following rules:
+
+        <list>
+            If the stream is a template to be applied, the string
+            "<t>.ibex</t>" is appended.
+        
+            If the stream is an image, the string "<t>.png</t>" is
+            appended.  If no stream is found, "<t>.jpeg</t>" and
+            "<t>.gif</t>" are tried, in that order.
+        
+            If the stream is an font, the string "<t>.ttf</t>" is
+            appended.
+        </list>
+        
+        Every call to <t>ibex.bless()</t> returns a different object
+        (which happens to be a clone of the object passed to it) with
+        a completely separate set of static blocks.
+
+    </list>
+
+    Ibex can self-emulate by using <t>ibex.clone()</t> on the Ibex object;
+    this technique is very similar to the use of ClassLoaders in
+    Java. This is useful for a number of applications, including
+    debuggers, IDEs, sandboxing untrusted code, remote-control, and
+    others.  For example:
+    
+    <pre>
+    var newLoadFunction = function(url) { /* ... */ };
+    var new_ibex = ibex.clone(ibex);
+    new_ibex.load ++= function() { return newLoadFunction; }
+    ibex.apply(ibex.box, .main, new_ibex);
+    </pre>
+  </section>
+</section>
+
+<!-- ----------------------------------------------------------------------- -->
+<appendix title="Security Architecture and Considerations">
+    
+    Due to the expense and hassle imposed by the commercial PKI code
+    signing architecture, and the fact that it <link
+    url="http://www.counterpane.com/pki-risks-ft.txt" text="doesn't
+    really provide any security anyways"/>, Ibex user interfaces are
+    distributed as unsigned, untrusted code. As such, they are handled
+    very carefully by the Ibex Core, and assumed to be potentially
+    malicious.
+    
+    Ibex's security architecture is divided into defenses against four
+    major classes of attacks:
+    
+  <heading title="Malicious UI attempts to acquire or alter data on the client"/>
+    
+    Ibex user interfaces are run in an extremely restrictive sandbox. The
+    environment does not provide primitives for accessing any data outside
+    the Ibex core except via XML-RPC and SOAP calls. There are no
+    facilities to allow Ibex user interfaces to access the client's
+    operating system or to interact with other applications on the same
+    host (unless they provide a public XML-RPC or SOAP interface).
+    An Ibex script may only access a file on the user's hard disk if the
+    user explicitly chooses that file from an "open file" or "save file"
+    dialog. There is one exception to this rule: if all templates
+    currently loaded in the Ibex core originated from the local
+    filesystem, those templates can load additional .ibexs from the local
+    filesystem.
+    
+    The Ibex Core is written in Java, so it is not possible for
+    scripts to perform buffer overflow attacks against the core
+    itself.
+    
+    Ibex applications may only read from the clipboard when the user
+    middle-clicks (X11 paste), presses control-V (Windows paste), or
+    presses alt-V (Macintosh paste; the command key is mapped to Ibex
+    "alt"). This ensures that Ibex applications are only granted access to
+    data that other applications have placed on the clipboard when the user
+    specifically indicates that that information should be made available
+    to the Ibex application.
+    
+  <heading title="Malicious UI attempts to use client to circumvent firewalls"/>
+    
+    Ibex user interfaces may only make XML-RPC or SOAP calls and load .ibex
+    archives via HTTP; they cannot execute arbitrary HTTP GET's or open
+    regular TCP sockets.
+    
+    Ibex will not allow a script to connect to a non-public IP address
+    (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16, as specified in <link
+    url="http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc1918.html" text="RFC
+    1918"/>). There is one exception -- if all templates currently loaded
+    in the core originated from the same IP address, those scripts may
+    make calls to that IP address regardless of whether or not it is
+    firewalled.  If Ibex does not have access to a DNS resolver (because it
+    is using a proxy which performs DNS lookups), Ibex will provide the
+    proxy with the appropriate <link
+    url="http://www.ibex.org/x-requestorigin.html"
+    text="X-RequestOrigin"/> header that the proxy needs in order
+    to maintain security.
+    
+    The only remaining possible attack is against a XML-RPC or SOAP
+    service running on a firewalled host with a public address. Assigning
+    such machines public IP addresses is a poor network security policy,
+    and doing so squanders scarce public IPv4 addresses. As such, the onus
+    is on the administrators of such machines to explicitly block access
+    to clients reporting a <t>User-Agent:</t> header beginning with the
+    four characters "<t>IBEX</t>".
+    
+  <heading title="Malicious UI attempts to trick user into divulging secret information"/>
+    
+    All top-level windows created by Ibex are <i>scarred</i> -- a stripe
+    and a lock is drawn across the corner of the window. There is no way
+    for a user interface to remove this scar. Ibex user interfaces may not
+    create windows smaller than the size of the scar.
+    
+  <heading title="Malicious network attempts to snoop or man-in-the-middle transactions"/>
+    
+    Ibex user interfaces may transmit network data using HTTPS (SSL 3.0)
+    for encryption. Ibex will attempt 128-bit encryption, but will
+    negotiate down to 40-bit if the server does not support strong
+    crypto. Ibex's SSL implementation is currently provided by <link
+    url="http://www.ibex.org/tinyssl" text="TinySSL"/> and <link
+    url="http://www.bouncycastle.org" text="The Legion of the Bouncy
+    Castle."/>
+    
+    All HTTPS connections must be authenticated by the server using a
+    certificate whose name matches the domain name of the HTTPS URL. The
+    certificate must be signed by a trusted root CA. Ibex trusts the same
+    93 root CAs whose certificates are included as "trusted" in Microsoft
+    Internet Explorer 5.5 SP2. This provides a minimal level of protection
+    against man-in-the-middle attacks; you should not trust this
+    connection with any data you would not normally trust an SSL-enabled
+    web browser with.
+    
+</appendix>
+
+<!-- ----------------------------------------------------------------------- -->
+<appendix title="ECMAscript compliance">
+    
+    Ibex's scripts are written in a modified subset of ECMA-262, revision 3
+    (aka JavaScript 1.5). The interpreter strays from the spec in a few
+    ways.
+    
+  <section title="Omissions">
+    
+    The following ECMA features are not supported:
+    
+    <list type="unordered">
+
+        The <t>undefined</t> value, <t>===</t>, and <t>!==</t>
+        
+        The <t>new</t> keyword (and ECMAScript object inheritance)
+        <t>eval</t>
+        
+        <t>getter</t> and <t>setter</t>
+        
+        The ECMA <t>this</t> keyword.
+        
+        The <t>String</t>, <t>Number</t>, and <t>Boolean</t>
+        classes.  Note that <t>string</t>, <t>number</t>, and
+        <t>boolean</t> values are supported, however.
+        
+        You may not <t>throw</t> the <t>null</t> value.
+
+    </list>
+    
+    Additionally, you must declare all root-scope variables (with
+    <t>var</t>) before using them; failure to do so will result in an
+    exception.  Box properties are pre-defined in the scope that scripts
+    are executed in.
+    
+    </section>
+
+  <section title="Extensions">
+    
+    <list type="unordered">
+    
+        The token <t>..</t> is equivalent to <t>[""]</t>.
+    
+        Trapping
+
+        Cloning
+    
+        Extended <t>catch</t> syntax.  The following code:
+        <pre>
+        } catch(e propname "foo.bar.baz") {
+           // ...
+        }
+        </pre>
+        Is equivalent to:
+        <pre>
+        } catch(e) {
+           if (e.propname != null and e.propname >= "foo.bar.baz" and
+               "foo.bar.baz/" > e.propname) {
+               // ...
+           }
+        }
+        </pre>
+        Multiple extended-catch blocks can appear at the end of a single try
+        block.  However, at most one non-extended catch block may appear, and
+        if it does appear, it must be the last one.
+    
+        Since Ibex ECMAscripts are wrapped in XML, the lexical token
+        "<t>lt</t>" is be interpreted as <t>&lt;</t>, the lexical
+        token "<t>gt</t>" is be interpreted as <t>&gt;</t>, and the
+        token "<t>and</t>" is interpreted as <t>&amp;&amp;</t>.
+        Thus these tokens cannot be used as variable names.
+    
+        The identifier <t>static</t> is a reserved word in
+        ECMAScript, but not in Ibex.
+    
+        Ibex defines an additional reserved word, "<t>assert</t>",
+        which will evaluate the expression which follows it, throwing
+        a <t>ibex.assertion.failed</t> exception if the expression
+        evaluates to <t>false</t>.
+    
+        To ensure that Ibex files appear the same in all text editors, tab
+        characters are not allowed in Ibex files.
+
+    </list>
+    
+    Some useful tutorials include:
+    
+    <list type="unordered">
+        
+        Netscape's <link
+        url="http://developer.netscape.com/docs/manuals/communicator/jsref/index.htm"
+        text=" JavaScript 1.2 Reference"/>. Although this document is
+        out of date, it is arguably the best guide available for free
+        on the Internet. The changes from JavaScript 1.2 (aka ECMA-262
+        r1) to 1.5 were minimal, and many of them were <link
+        url="ecmascriptcompliance" text="omitted"/> from Ibex.
+        
+        O'Reilly's <link
+        url="http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?isbn=0596000480"
+        text=" JavaScript: The Definitive Guide"/>, by David Flanagan
+        and Paula Ferguson. The latest edition of this book covers
+        JavaScript 1.5 (ECMA-262 r3).
+        
+        The official <link
+        url="http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM"
+        text="ECMA-262"/> specification. This is an extremely
+        technical document.
+
+    </list>
+    </section>
+</appendix>
+
+<!-- ----------------------------------------------------------------------- -->
+<appendix title="Logging and Command Line Invocation">
+    
+    <pre>
+    Usage: ibex [-lawp] [ url | file | directory ]
+        -l [level]      set logging level to { debug, info (default), warn, error, silent }
+        -l rpc          log all XML-RPC and SOAP conversations
+        -l user@host    email log to user@host
+        -l host:port    emit log to TCP socket
+        -l [file]       write log to a file on disk
+        -a              check assertions
+        -w <window-id>  reserved for libibex
+        -p              dump profiling information [not yet supported]
+    </pre>
+
+    If Ibex encounters a serious problem before it starts logging
+    information, or if it is unable to open the log file, it will abort
+    immediately with a critical abort, which will be displayed on the
+    console for POSIX-native cores and in a dialog box for JVM-based and
+    Win32-native cores.
+
+    Note that Microsoft Windows does not provide any mechanism for
+    redirecting standard input/output of an application which is not
+    compiled as a "console application".  Therefore, Ibex is compiled
+    as a "console application", and will open a console window when
+    invoked.  To inhibit this console window, provide a logging
+    destination (file, port, etc).
+    
+    The <t><i>source-location</i></t> parameter can be either the path
+    to an <t>.ibex</t> archive, the http url of an <t>.ibex</t>
+    archive, or the path to a directory comprising an unpacked
+    <t>.ibex</t> archive.
+    
+    The <t><i>initial-template</i></t> parameter is the stream name of
+    a template to be used as the initial template. If ommitted, it
+    defaults to <t>main</t>.
+    
+    The <t>-v</t> option causes Ibex to enable verbose logging; this will
+    cause it to log <i>lots</i> of information to the log file. This
+    option will also substantially decrease Ibex's performance.
+    
+  </appendix>
+
+<!-- ----------------------------------------------------------------------- -->
+    <!--
+<appendix title="Grammars">
+
+    <i>Grammar support is experimental in this release
+    and may not work properly.  It may change in incompatible ways or
+    disappear completely from future releases</i>
+    
+    Grammars are defined with a statement in the following form:
+    
+    <pre>
+    a ::= b { c }
+    </pre>
+    A grammar is really just another function; once defined you can't tell
+    it apart from an ordinary function.  A grammar takes one argument,
+    which can be a string or stream.  The argument is parsed and the
+    result of executing the code block 'c' is returned.
+    
+    The property 'a' is read; if the value is a grammar, a new production
+    rule (ie a new alternative, as with '<t>|</t>') is added to that grammar
+    (this is a destructive update).  This allows you to add productions to
+    pre-existing grammars (for example, adding a new type of expression to
+    a programming language by extending the 'expr' grammar).  If the old
+    value is not a grammar, the value is discarded and a new grammar
+    object is created.
+    
+    The value 'b' is a pattern, which may consist of seven simple
+    primitives:
+    
+    <list type="unordered">
+        string literals
+         
+        grouping parens <t>()</t>
+         
+        combinators:   <t> | + * ?</t>
+         
+        references to other grammars
+    </list>
+
+    The value 'c' and the braces surrounding it are an *optional* code
+    block, in which the following identifiers are bound:
+    
+    <list type="unordered">
+         
+       The identifier 'whole' is bound to the string matched by the
+       entire expression.  If the code block is omitted it behaves
+       as if it were "<t>{ return whole; }</t>".
+         
+       For every reference to another grammar which was matched in the
+       pattern, the *name used to reference that other grammar* will
+       be bound to the value returned by its code block.  Here's an
+       example of this important distinction:
+        
+       <pre>
+       var foo ::= 'a' | 'b';
+       var bar ::= foo;
+       var baz ::= 'c' | bar    {  /* foo is not defined here, but bar is */ };
+       </pre>
+        
+       On the last line, the identifier 'bar' serves two purposes: it
+       pulls in the definition of the pattern *and* acts as a binder
+       within the scope of the braces.
+        
+       If a reference is matched multiple times (either because it
+       appears multiple times in the pattern or because the * or +
+       operator was applied to it) then its name will be bound to an
+       array containing the matches.
+
+    </list>
+
+    Here is the metacircular definition of the grammar facility:
+    
+    <pre>
+         grammar ::= identifier '::=' pattern (';' | '{' code '}' ';'?)
+      identifier ::= ('a'..'z' | 'A'..'Z' | '_' | '$') (identifier | '0'..'9')*
+            char ::= '\0x0000'..'\0xffff'
+         literal ::= '\'' char+ '\''
+                   | '\'' char '\'' '..' '\'' char '\''
+         pattern ::= identifier
+                   | literal
+                   | '(' pattern ')'
+                   | pattern '+'
+                   | pattern '?'
+                   | pattern '*'
+                   | pattern pattern
+                   | pattern '|' pattern
+    </pre>
+    -->
+    
+<i>
+Copyright (C) 2004 Adam Megacz, verbatim redistribution permitted.
+Ibex is a trademark of Adam Megacz
+</i>
+    
+</ibex-doc>
\ No newline at end of file