You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2012/12/06 18:42:18 UTC

[36/52] [partial] ISIS-188: moving framework/ subdirs up to parent

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/bdd/src/docbkx/guide/isis-bdd-integration.xml
----------------------------------------------------------------------
diff --git a/component/viewer/bdd/src/docbkx/guide/isis-bdd-integration.xml b/component/viewer/bdd/src/docbkx/guide/isis-bdd-integration.xml
new file mode 100644
index 0000000..299256b
--- /dev/null
+++ b/component/viewer/bdd/src/docbkx/guide/isis-bdd-integration.xml
@@ -0,0 +1,4170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"file:./src/docbkx/dtd-4.5/docbookx.dtd">
+<book>
+  <bookinfo>
+    <title><?eval ${docbkxGuideTitle}?></title>
+
+    <subtitle><?eval ${docbkxGuideSubTitle}?></subtitle>
+
+    <releaseinfo><?eval ${project.version}?></releaseinfo>
+
+    <authorgroup>
+      <author>
+        <firstname>Dan</firstname>
+
+        <surname>Haywood</surname>
+      </author>
+    </authorgroup>
+
+    <legalnotice>
+      <para>Permission is granted to make and distribute verbatim copies of
+      this manual provided that the copyright notice and this permission
+      notice are preserved on all copies.</para>
+    </legalnotice>
+  </bookinfo>
+
+  <!-- front matter -->
+
+  <toc></toc>
+
+  <preface id="preface">
+    <title>Preface</title>
+
+    <para>Behaviour-driven development is a means to drive the development of
+    an application through stories and scenarios. These are expressed in a
+    semi-formal textual form that can be understood (or indeed be written) by
+    the domain expert/business analyst, but which can then be used to directly
+    exercise the system under test as it is developed.</para>
+
+    <para>A number of frameworks exist to streamline this process. Generally
+    these require the developer to write glue code that acts as a bridge from
+    the textual specification and the system under test.</para>
+
+    <para>The <emphasis>BDD Viewer</emphasis> module for <emphasis>Apache
+    Isis</emphasis> aims to allow <acronym>BDD</acronym> stories/scenarios to
+    be written against the domain model of an Isis application, without the
+    developer having to write any glue code. It consists of a common library
+    that abstracts the interaction with the Isis metamodel, along with an
+    integration (that uses this common library) for one particular
+    <acronym>BDD</acronym> framework, namely <ulink
+    url="http://concordion.org">Concordion</ulink>. There is also outline
+    coverage of the <ulink url="http://fitnesse.org">FitNesse</ulink>
+    integration (part of <ulink
+    url="http://code.google.com/a/apache-extras.org/p/isis-extras">isis-extras</ulink>).</para>
+
+    <para>This user guide describes how to use the
+    <emphasis>Concordion</emphasis> integration, along with details of the
+    common library so that other <acronym>BDD</acronym> frameworks can be
+    integrated if required.</para>
+
+    <para><emphasis>Apache Isis</emphasis> is licensed under <ulink
+    url="http://www.apache.org/licenses/LICENSE-2.0.html">Apache Software
+    License v2</ulink>. However, although <emphasis>Concordion</emphasis>
+    itself licensed under Apache License v2, it in turn depends upon an XML
+    library called <ulink url="http://xom.nu">XOM</ulink>, which unfortunately
+    has an <ulink url="http://www.gnu.org/licenses/lgpl-2.1.html">LGPL
+    2.1</ulink> license. Apache projects are <ulink
+    url="http://www.apache.org/legal/resolved.html#category-x">not
+    allowed</ulink> to have dependencies on <acronym>LGPL</acronym> projects.
+    </para>
+
+    <para>The workaround that we have adopted is to exclude the
+    <acronym>XOM</acronym> dependency in Isis' own
+    <filename>pom.xml</filename> files, meaning that they are compliant with
+    Apache's licensing restrictions. However, any application code that uses
+    the <emphasis>BDD Viewer</emphasis> must explicitly add its own dependency
+    to the <acronym>XOM</acronym> library. You'll find that the
+    <filename>pom.xml</filename> files generated by the quickstart archetype
+    do indeed do this.</para>
+
+    <para>However, If you are unhappy to introduce this dependency to
+    <acronym>LGPL</acronym> in your own code, then you will not be able to use
+    the <emphasis>Concordion</emphasis> integration. </para>
+  </preface>
+
+  <!-- main content -->
+
+  <chapter>
+    <title>Introduction</title>
+
+    <abstract>
+      <para>An introduction to the idea of behaviour driven development, and
+      the components that make up <emphasis>Isis</emphasis>' integration with
+      <acronym>BDD</acronym> frameworks.</para>
+    </abstract>
+
+    <sect1>
+      <title>Behaviour-driven Development</title>
+
+      <para>Prior to agile development, requirements gathering for systems was
+      traditionally performed by business analysts discussing requirements
+      with the business, and expressing those requirements in documentation,
+      such as Word specs and perhaps spreadsheets. The acceptance criteria for
+      such requirements were often only sketched out, if at all; it would
+      normally fall to the system testers to write acceptance tests for the
+      requirements, through a mixture of consulting the original (by now
+      out-of-date) requirements documentation and (as often as not)
+      reverse-engineering the implementation.</para>
+
+      <para>Behaviour-driven development combines requirements capture and the
+      acceptance test criteria in a single form, through scenarios. As before,
+      these requirements are in a form that a non-technical domain expert from
+      the business can understand. What differs though is that these scenarios
+      can be used to directly exercise the system, and so also represent the
+      acceptance tests for the correct implementation of the requirement.
+      Moreover, the results of these tests are rendered in such a way that the
+      business can understand, and thus can help determine if the code is at
+      fault or the test. Once implemented, the acceptance tests also act as a
+      regression suite for the system.</para>
+
+      <para>Scenario tests tend to act against a complete system, or sometimes
+      at a subsystem-level. At any rate the tests must be at a granularity
+      that still makes sense to a non-technical businesss person. Compare this
+      to unit testing which exercises the behaviour / method of a single
+      class.</para>
+
+      <para>Another commonly-used name for scenario testing is "agile
+      acceptance testing". We've chosen to use the term "scenario testing"
+      though; it's a somewhat less clumsy term.</para>
+    </sect1>
+
+    <sect1 id="sec.CommonLibrary">
+      <title>Common Library</title>
+
+      <para><emphasis>Apache Isis</emphasis> integrates with
+      <acronym>BDD</acronym> frameworks through the services of a common
+      library. The main concepts that the common library exposes are:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>the <classname>Scenario</classname> class, which provides the
+          context for a single scenario of a story</para>
+        </listitem>
+
+        <listitem>
+          <para>the <classname>AliasRegistry</classname>, which allows a
+          user-friendly alias (eg "fredCustomer") to be assigned to any domain
+          object and to be referenced subsequently</para>
+        </listitem>
+
+        <listitem>
+          <para>the <classname>StoryCell</classname> interface, which is an
+          abstraction over a single element of data</para>
+
+          <para>The default implementation just wraps a
+          <classname>java.lang.String</classname>, but some frameworks might
+          provide alternative implementations. For example,
+          <emphasis>FitNesse</emphasis> has an implementation that maps to its
+          internal representation of a cell (<classname>fit.Parse</classname>
+          class).</para>
+        </listitem>
+
+        <listitem>
+          <para>the <classname>CellBinding</classname> interface, which binds
+          a column of a table to a property or to an alias</para>
+
+          <para>Many of the <acronym>BDD</acronym> frameworks (eg
+          <emphasis>Concordion</emphasis>, <emphasis>FitNesse</emphasis>)
+          encourage the use of tables as a means of succinctly capturing
+          scenario actions. This is reflected in the design of several of the
+          classes provided by the common library. The
+          <classname>CellBinding</classname> interface is used to wire the
+          values in the rows of the table to the properties specified in the
+          header.</para>
+
+          <para>Each <classname>CellBinding</classname> has a name (eg "on
+          object") and some alternative names (eg "using"). This is useful for
+          <acronym>BDD</acronym> frameworks (such as
+          <emphasis>FitNesse</emphasis>) where the provided text from the
+          scenario needs to be parsed in some way, matching up headings of
+          columns within a tabular structure. The relevant methods for
+          <acronym>BDD</acronym> framework integrations that must do this are
+          <methodname>#matches(...)</methodname>,
+          <methodname>#setHeadColumn(..)</methodname> and
+          <methodname>#createHeadColumn(..)</methodname>. Note though that not
+          every <acronym>BDD</acronym> framework integration needs this
+          particular feature; the <emphasis>Concordion</emphasis> integration
+          for example calls pre-canned methods so the matching is done simply
+          by parameter position to these method.</para>
+
+          <para>The other main method provided by
+          <classname>CellBinding</classname> is
+          <methodname>#captureCurrent(..)</methodname>. This is used (by all
+          framework integrations) to capture the current value for the column
+          which this binding represents. For example, for a column
+          representing a property name, it might hold the value
+          "firstName".</para>
+
+          <para>The library provides a default implementation of
+          <classname>CellBinding</classname>, though subclasses can override
+          if required. (For example, the <emphasis>FitNesse</emphasis>
+          integration has its own implementation to map to its data structures
+          representing cells in the FIT tables).</para>
+        </listitem>
+      </itemizedlist>
+
+      <para>One way of thinking of all these framework integrations is as a
+      replacement presentation layer, hitting the underlying domain model in
+      the same way that the regular <acronym>UI</acronym> would. (This is why
+      we call this module is called the <acronym>BDD</acronym><emphasis>
+      viewer</emphasis>).</para>
+
+      <para>In the following chapter (<xref
+      linkend="chp.IntroducingTheFramework" />), details are provided of how
+      the services of the common library are used by each of the supported
+      <acronym>BDD</acronym> framework integrations.</para>
+    </sect1>
+
+    <sect1>
+      <title>Concordion Integration</title>
+
+      <sect2>
+        <title>Introduction to Concordion</title>
+
+        <para><ulink url="http://concordion.org">Concordion</ulink> is a
+        framework to enable scenario testing. It is implemented as a <ulink
+        url="http://junit.org">JUnit4</ulink> test runner, with the test form
+        being written in <acronym>XHTML</acronym>. The domain expert /
+        business analyst authors new stories using an <acronym>XML</acronym>
+        editor; once executed as tests, the results are shown as the same
+        <acronym>XHTML</acronym> document, annotated to indicate which
+        assertions have succeeded, and which have failed. It also creates an
+        efficient feedback loop; a <emphasis>Concordion</emphasis> test will
+        "keep on going" even if it hits a failure. Thus the developer can
+        identify several issues and fix them in a single pass.</para>
+
+        <para><emphasis>Concordion</emphasis> works using a "convention over
+        configuration" approach, matching the <acronym>XHTML</acronym> text
+        file with a corresponding JUnit4 test run set up to run using
+        <emphasis>Concordion</emphasis>'s
+        <classname>ConcordionRunner</classname>, The developer then annotates
+        the <acronym>XHTML</acronym> using special (namespaced) attributes in
+        order identify the inputs to and expected results of the test. This is
+        used by the <classname>ConcordionRunner</classname> to call into
+        corresponding methods in the test.</para>
+
+        <para>For example:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>Suppose the analyst writes a scenario test called
+            <filename>CustomerPlacesOrderScenario.xhtml</filename>.</para>
+
+            <para>In the <acronym>XHTML</acronym> the analyst has identified
+            the details of the customer doing the ordering (customer ref 4321,
+            say), the product being ordered (product code 1234), the fact that
+            the customer initially has no orders, and that the customer has no
+            invoices outstanding. The test concludes with an assertion that
+            there is now an unfulfilled order for the customer, and that the
+            customer now has an invoice to be paid.</para>
+          </listitem>
+
+          <listitem>
+            <para>The developer in turn edits the <acronym>XHTML</acronym>,
+            identifying the customer and the product.</para>
+
+            <para>He then further edits the <acronym>XHTML</acronym> to call a
+            method in the JUnit4 test representing the placing of an order:
+            <methodname>placeOrder()</methodname>, say. And he finishes by
+            annotating the <acronym>XHTML</acronym> to make assertions about
+            the post conditions (unfulfilled order, new invoice to be paid
+            etc).</para>
+          </listitem>
+
+          <listitem>
+            <para>Then, the developer writes a JUnit4 test alongside the
+            <acronym>XHTML</acronym>; in this example it would be called
+            <filename>CustomerPlacesOrderScenario.java</filename>.
+            <emphasis>Concordion</emphasis> calls into this JUnit4 test as it
+            comes across the annotations in the <acronym>XHTML</acronym>, and
+            the JUnit4 test mediates with the system under test.</para>
+          </listitem>
+
+          <listitem>
+            <para>When the test runs, <emphasis>Concordion</emphasis>
+            generates a copy of the <acronym>XHTML</acronym> in an output
+            directory which can then made available for inspection by the
+            business analyst (eg published on a website).</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>The <emphasis>Concordion</emphasis> website has a good <ulink
+        url="http://concordion.org/Tutorial.html">tutorial</ulink> that
+        demonstrates all the above, and can be completed in 20~30
+        minutes.</para>
+
+        <para>One slight downside of using <emphasis>Concordion</emphasis> is
+        in having to write tests in <acronym>XHTML</acronym>. One editor that
+        we recommend (commercial, but also with a free version for personal
+        use) is <ulink url="http://xmlmind.net">XmlMind</ulink>. More detailed
+        guidance is provided in <xref linkend="apx.UsingXmlMind" />.</para>
+      </sect2>
+
+      <sect2 id="sec.HowTheIsisConcordionIntegrationWorks">
+        <title>How the Isis/Concordion Integration Works</title>
+
+        <para>Although you could test an <emphasis>Apache Isis</emphasis>
+        application using vanilla <emphasis>Concordion</emphasis>, this would
+        entail you having to write all the glue code yourself to interact with
+        the domain objects. You would also need to encode the rules that are
+        normally implemented by an <emphasis>Isis</emphasis> viewer, eg so
+        that a hidden action cannot be invoked, and an invalid value for a
+        property cannot be set.</para>
+
+        <para>The <emphasis>BDD viewer</emphasis> integration provided by
+        <emphasis>Apache Isis</emphasis> works by providing a superclass for
+        the JUnit4 test, called
+        <classname>AbstractIsisConcordionScenario</classname>. This exposes
+        methods to perform all the tasks necessary for exercising an
+        application. The precise features are outlined in <xref
+        linkend="chp.IntroducingTheFramework" />.</para>
+
+        <para>For each <acronym>XHTML</acronym> scenario test, the developer
+        writes subclasses the
+        <classname>AbstractIsisConcordionScenario</classname>, creating a name
+        matching the scenario test (ie as per regular
+        <emphasis>Concordion</emphasis>). He then annotates the original
+        <acronym>XHTML</acronym>, either calling directly into the inherited
+        methods, or writing small simple methods to delegate to these
+        inherited methods as required. The <emphasis>Concordion</emphasis>
+        website has some <ulink
+        url="http://concordion.org/Technique.html">hints and tips</ulink> to
+        help you find the right balance between these two approaches.</para>
+
+        <para>The <acronym>XHTML</acronym> script that you write should have
+        the following namespace declaration:</para>
+
+        <programlisting>&lt;html 
+    xmlns:concordion="http://www.concordion.org/2007/concordion" 
+    xmlns:isis="http://isis.apache.org/2010/concordion"&gt;
+    ...
+&lt;/html&gt;</programlisting>
+
+        <para>The <literal>concordion</literal> namespace is the usual
+        namespace required by <emphasis>Concordion</emphasis>. The
+        <literal>isis</literal> namespace is defined for a similar reason: to
+        allow certain commands provided by the Isis/Concordion integration to
+        be invoked. More on this in <xref
+        linkend="chp.UserInteraction" />.</para>
+      </sect2>
+
+      <sect2>
+        <title>Specifying the Output Directory</title>
+
+        <para>The directory for the generated output can be specified
+        either:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>by overriding the <methodname>outputDir()</methodname>
+            method in <classname>AbstractIsisConcordionScenario</classname>;
+            or</para>
+          </listitem>
+
+          <listitem>
+            <para>by setting the <varname>concordion.output.dir</varname>
+            system property</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>If not specified, then the output directory defaults to
+        <filename>/tmp/concordion</filename>.</para>
+      </sect2>
+
+      <sect2>
+        <title>Providing a CSS File</title>
+
+        <para>By default, Concordion will copy over the
+        <acronym>HTML</acronym> for every scenario into the output directory,
+        but it won't copy over any <acronym>CSS</acronym> resources. If you
+        want any <acronym>CSS</acronym> to be copied over, then:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>override the <methodname>customCssPackage()</methodname>
+            method in <classname>AbstractIsisConcordionScenario</classname> to
+            return any class in the package that holds the CSS file.</para>
+          </listitem>
+
+          <listitem>
+            <para>override the <methodname>customCss()</methodname> method to
+            specify the name of the <acronym>CSS</acronym> file to copy over.
+            If none is specified, then concordion.css is used.</para>
+          </listitem>
+        </itemizedlist>
+      </sect2>
+
+      <sect2>
+        <title>Configuring the Maven Surefire (test) plugin</title>
+
+        <para>The standard boilerplate to run <emphasis>Concordion</emphasis>
+        under <emphasis>Maven</emphasis> is as follows:</para>
+
+        <programlisting>&lt;plugins&gt;
+    &lt;plugin&gt;
+        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+        &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
+        &lt;version&gt;2.6&lt;/version&gt;
+        &lt;configuration&gt;
+            &lt;systemPropertyVariables&gt;
+                &lt;concordion.output.dir&gt;
+                    ${project.build.directory}/concordion
+                &lt;/concordion.output.dir&gt;
+            &lt;/systemPropertyVariables&gt;
+            &lt;includes&gt;
+                &lt;include&gt;**/*Scenario.java&lt;/include&gt;
+                &lt;include&gt;**/Scenario*.java&lt;/include&gt;
+            &lt;/includes&gt;
+        &lt;/configuration&gt;
+    &lt;/plugin&gt;
+&lt;/plugins&gt;y</programlisting>
+
+        <para>There are a couple of points worth noting here.</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>first, the <literal>systemPropertyVariables</literal>
+            element can be used to define the
+            <varname>concordion.output.dir</varname> system property, thereby
+            specifying the directory for the generated output</para>
+          </listitem>
+
+          <listitem>
+            <para>second, the <literal>includes</literal> element can be used
+            to only run classes with either a prefix or suffix
+            "<literal>Scenario</literal>". This allows common fixtures that
+            have been factored out to be ignored.</para>
+
+            <para>An alternative approach is to have a top-level "suite" page
+            that references all scenarios underneath (probably grouped into
+            stories). In this case the only test class that would be run
+            included is the top-level suite page. See <xref
+            linkend="sec.TopLevelSuitePage" /> for further discussion.</para>
+          </listitem>
+        </itemizedlist>
+      </sect2>
+    </sect1>
+
+    <sect1 id="sec.FitNesseIntegration">
+      <title>FitNesse Integration</title>
+
+      <para>Due to licensing restrictions, the <emphasis>FitNesse</emphasis>
+      integration is not part of <emphasis>Apache Isis</emphasis> proper.
+      However, it is available on the companion Apache Extras' <ulink
+      url="http://code.google.com/a/apache-extras.org/p/isis-extras/"><emphasis>isis-extras</emphasis></ulink>
+      site. Check that site for its release status (it is not guaranteed to be
+      in sync with <emphasis>Isis</emphasis> releases).</para>
+
+      <para>An outline of the <emphasis>FitNesse</emphasis> integration is
+      provided here, if only to help compare and contrast the means by which
+      two different frameworks integrate with the common library. We hope that
+      this will make it easier to integrate other <acronym>BDD</acronym>
+      frameworks in the future.</para>
+    </sect1>
+  </chapter>
+
+  <chapter id="chp.IntroducingTheFramework">
+    <title>Introducing the Framework</title>
+
+    <abstract>
+      <para>An introduction to the features provided by the framework. The
+      subsequent chapters provide more detailed coverage.</para>
+    </abstract>
+
+    <para>This chapter outlines the main features of the common library and
+    their support by the framework-specific integrations. The subsequent
+    chapters provide more detailed coverage.</para>
+
+    <para>Note that due to licensing restrictions the
+    <emphasis>FitNesse</emphasis> integration is not part of <emphasis>Apache
+    Isis</emphasis>. Nevertheless, an outline of the
+    <emphasis>FitNesse</emphasis> integration is provided here, if only to
+    help compare and contrast the means by which two different frameworks
+    integrate with the common library. We hope that this will make it easier
+    to integrate other <acronym>BDD</acronym> frameworks in the future.</para>
+
+    <sect1>
+      <title>Introduction</title>
+
+      <para>Broadly speaking, the framework provides the ability to bootstrap
+      and initialize an <emphasis>Isis</emphasis> application and allow the
+      domain services and objects within that application to be exercised in
+      the same way that a user would interact with the system through a
+      viewer.</para>
+
+      <para>The common library defines these abilities in terms of "fixture"
+      classes, each of which performs a single function. For example, there is
+      a fixture class to bootstrap <emphasis>Isis</emphasis>, another to setup
+      objects, and another to describe the actual interactions by the user
+      (check a property, invoke an action etc).</para>
+
+      <para>The fixture classes in the common library are oriented around a
+      tabular approach to specifying behaviour, making it easy to integrate
+      frameworks such as <emphasis>FitNesse</emphasis> that adopt a
+      table-oriented approach. Such an approach equally supports frameworks
+      such as <emphasis>Concordion</emphasis> that allow specifications to be
+      written both as tables and in free-form text. Admittedly, this does make
+      the implementation of framework integrations a little more complex than
+      it might otherwise have been ... but this is only a problem for the
+      framework integrator, not the business analyst actually writing the
+      scenarios.</para>
+    </sect1>
+
+    <sect1>
+      <title>Fixtures</title>
+
+      <para>The following chapters describe the fixtures available in detail.
+      In summary, they are:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>it bootstrap an instance of <emphasis>Apache Isis</emphasis>
+          system using the in-memory object store (see <xref
+          linkend="chp.BootstrapAndTeardown" />);</para>
+        </listitem>
+
+        <listitem>
+          <para>setting up the system state ready for the scenario (see <xref
+          linkend="chp.SetUp" />):</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>specify the date/time format</para>
+            </listitem>
+
+            <listitem>
+              <para>initialize the system with a set of services, picked up
+              from the <filename>isis.properties</filename> configuration
+              file</para>
+            </listitem>
+
+            <listitem>
+              <para>allow fixtures (domain objects) to be installed into the
+              object store</para>
+            </listitem>
+
+            <listitem>
+              <para>login a specific user</para>
+            </listitem>
+
+            <listitem>
+              <para>specify the date</para>
+            </listitem>
+          </itemizedlist>
+        </listitem>
+
+        <listitem>
+          <para>allow the user to interact with services and domain objects
+          (see <xref linkend="chp.UserInteraction" />):</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>asserting on the value of properties and the contents of
+              collections</para>
+            </listitem>
+
+            <listitem>
+              <para>setting the value of a property (if valid) and adding
+              to/removing from a collection (if valid)</para>
+            </listitem>
+
+            <listitem>
+              <para>invoking actions</para>
+            </listitem>
+
+            <listitem>
+              <para>asserting on the state of a class member (hidden, disabled
+              or enabled)</para>
+            </listitem>
+
+            <listitem>
+              <para>assert on the state of properties</para>
+            </listitem>
+          </itemizedlist>
+        </listitem>
+
+        <listitem>
+          <para>assert on the state of collections, either of an object, or
+          returned from an action (see <xref
+          linkend="chp.AssertingOnCollections" />);</para>
+        </listitem>
+
+        <listitem>
+          <para>tearing down the system at the end of the test (see <xref
+          linkend="chp.BootstrapAndTeardown" />)</para>
+        </listitem>
+      </itemizedlist>
+
+      <para>There are also fixtures to help with debugging (see <xref
+      linkend="chp.Debugging" />).</para>
+
+      <para>For each fixture, you'll find there's a discussion about the
+      capabilities provided by the common fixture, and then details as to the
+      support for that fixture by each of the <acronym>BDD</acronym> framework
+      integrations (<emphasis>Concordion</emphasis> and
+      <emphasis>FitNesse</emphasis>).</para>
+    </sect1>
+  </chapter>
+
+  <chapter id="chp.BootstrapAndTeardown">
+    <title>Bootstrapping &amp; Teardown</title>
+
+    <abstract>
+      <para>The fixtures provided for bootstrapping at the start of a
+      scenario, and tearing down at the end</para>
+    </abstract>
+
+    <para>In order to test an <emphasis>Apache Isis</emphasis> domain
+    application, a running instance of an <classname>IsisSystem</classname>
+    must be bootstrapped, with the appropriate configuration.</para>
+
+    <sect1>
+      <title>Scenario Context</title>
+
+      <para>The common library provides a context object which holds a
+      reference to a running <classname>IsisSystem</classname>. Moreover, it
+      tracks such things as the date/time that the scenario is running as, the
+      user that is logged-in, and managing the aliases of objects so that they
+      can be interacted with.</para>
+
+      <sect2>
+        <title>Common</title>
+
+        <para>An instance of the <classname>Scenario</classname> class
+        provides a context for the scenario. Framework integrations are
+        expected to instantiate this class, and then use it as the primary
+        means to interact with the system.</para>
+
+        <para>The <classname>Scenario</classname> class has a public no-arg
+        constructor. Instantiating the <classname>Scenario</classname> does
+        not do anything; it must also be bootstrapped (see <xref
+        linkend="sec.BootstrappingIsis" />).</para>
+      </sect2>
+
+      <sect2>
+        <title>Concordion</title>
+
+        <para>The <classname>AbstractIsisConcordionScenario</classname>
+        instantiates the <classname>Scenario</classname> object (from the
+        common library) automatically and binding it to a threadlocal. In
+        addition, <classname>AbstractIsisConcordionScenario</classname>
+        provides methods that can be invoked from within
+        <acronym>XHTML</acronym> (ie taking
+        <classname>String</classname>s).</para>
+
+        <para>Test cases should inherit from this abstract class, with the
+        <acronym>XHTML</acronym> typically calling to the inherited methods
+        directly. The developer may optionally add small helper methods to be
+        called from the <acronym>XHTML</acronym> instead; these can factor out
+        any boilerplate in the script.</para>
+      </sect2>
+
+      <sect2>
+        <title>FitNesse</title>
+
+        <para>Every <emphasis>FitNesse</emphasis> scenario must reference the
+        <classname>ScenarioFixture</classname> fixture which provides the
+        overall context for the framework. This instantiates a
+        <classname>Scenario</classname> object from the common library and
+        binding it to a thread-local.</para>
+
+        <para>Whereas other <emphasis>FitNesse</emphasis> fixtures are
+        instantiated once per table, the
+        <classname>ScenarioFixture</classname> is a <acronym>FIT</acronym>
+        <classname>DoFixture</classname> that exists for the duration of the
+        test page. It should typically be referenced in the test suite's setup
+        page, and should appear first within this setup:</para>
+
+        <informaltable>
+          <tgroup cols="1">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Scenario Fixture</classname></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+      </sect2>
+    </sect1>
+
+    <sect1 id="sec.BootstrappingIsis">
+      <title>Bootstrapping Isis</title>
+
+      <para>An <emphasis>Isis</emphasis> runtime can be bootstrapped with a
+      single call. This installs no-op implementations of some of the main
+      components, along with an in-memory object store.</para>
+
+      <sect2>
+        <title>Common</title>
+
+        <para>The <methodname>Scenario#bootstrapIsis(String configDirectory,
+        DeploymentType deploymentType)</methodname> is used to bootstrap the
+        <emphasis>Isis</emphasis> runtime:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>The specified config directory contains
+            <filename>isis.properties</filename> config file, from which the
+            services are registered. Any fixtures in that properties file are
+            ignored (the <acronym>BDD</acronym> integration requires that any
+            objects are created through the test scripts, see <xref
+            linkend="sec.SetUpObjects" /> and <xref
+            linkend="chp.UserInteraction" />).</para>
+          </listitem>
+
+          <listitem>
+            <para>The deployment type must be either EXPLORATION (meaning
+            exploration actions are enabled) or PROTOTYPE; no other values are
+            valid).</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Even if running in exploration mode, you must still logon (see
+        <xref linkend="sec.LogonAsSwitchUserTo" />) in order to indicate which
+        user account to run the scenario as.</para>
+      </sect2>
+
+      <sect2>
+        <title>Concordion</title>
+
+        <para>The <classname>AbstractIsisConcordionScenario</classname> class
+        provides two overloaded versions of
+        <methodname>bootstrapIsis(...)</methodname> method:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#bootstrapIsis(String configDirectory,
+            DeploymentType deploymentType)</methodname></para>
+
+            <para>Intended to be called from within an <methodname>@Before
+            setUp()</methodname> method, when there's no particular need to
+            document the bootstrapping process within the scenario;</para>
+          </listitem>
+        </itemizedlist>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#bootstrapIsis(String configDirectory, String
+            deploymentType):boolean</methodname></para>
+
+            <para>Intended to be called from the <acronym>XHTML</acronym>
+            page, allowing the scenario document the bootstrapping process.
+            For example, to bootstrap in exploration mode, use:</para>
+
+            <programlisting>&lt;p concordion:execute="#result=bootstrapIsis(#configDir,#deploymentType)"&gt;
+Isis system &lt;span concordion:assertTrue="#result"&gt;bootstrapped&lt;/span&gt; 
+from config directory &lt;span concordion:set="#configDir"&gt;../quickrun/config&lt;/span&gt;
+and running in &lt;span concordion:set="#deploymentType"&gt;exploration&lt;/span&gt; mode.
+&lt;/p&gt;</programlisting>
+
+            <para>The method always returns <literal>true</literal>, but any
+            runtime exception will propagate to the generated page.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Whichever method is used, they both delegate to the common
+        <methodname>Scenario#bootstrapIsis(...)</methodname> method.</para>
+      </sect2>
+
+      <sect2>
+        <title>FitNesse</title>
+
+        <para>The <classname>BootstrapIsisConfiguredFromInMode</classname>
+        fixture is used to bootstrap <emphasis>Isis</emphasis>. It takes the
+        form:</para>
+
+        <informaltable>
+          <tgroup cols="4">
+            <colspec colwidth="3*" />
+
+            <tbody>
+              <row>
+                <entry><classname>Bootstrap Isis Configured
+                From</classname></entry>
+
+                <entry><emphasis>config Directory</emphasis></entry>
+
+                <entry><methodname>In Mode</methodname></entry>
+
+                <entry><emphasis>deployment Type</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <para>This delegates to the common
+        <methodname>Scenario#bootstrapIsis(...)</methodname> method.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="sec.ShutdownIsis">
+      <title>Shutdown Isis</title>
+
+      <para>This fixture shuts down the <emphasis>Isis</emphasis> runtime,
+      releasing memory and so on. A good place to put this is in the test's
+      teardown.</para>
+
+      <sect2>
+        <title>Common</title>
+
+        <para>The <methodname>Scenario#shutdownIsis()</methodname> method is
+        used to shutdown <emphasis>Isis</emphasis> runtime.</para>
+      </sect2>
+
+      <sect2>
+        <title>Concordion</title>
+
+        <para>To shutdown <emphasis>Isis</emphasis> from within
+        <emphasis>Concordion</emphasis>, use the
+        <methodname>AbstractIsisConcordionScenario#shutdownIsis()</methodname>
+        method. This just delegates to the common library's
+        <classname>Scenario#shutdownIsis()</classname> method.</para>
+      </sect2>
+
+      <sect2>
+        <title>FitNesse</title>
+
+        <para>To shutdown Isis from FitNesse, use the
+        <classname>ShutdownIsis</classname> fixture:</para>
+
+        <informaltable>
+          <tgroup cols="1">
+            <colspec colwidth="3*" />
+
+            <tbody>
+              <row>
+                <entry><classname>Shutdown Isis</classname></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <para>This just delegates to the common library's
+        <methodname>Scenario#shutdownIsis()</methodname> method.</para>
+      </sect2>
+    </sect1>
+  </chapter>
+
+  <chapter id="chp.SetUp">
+    <title>Scenario Set Up</title>
+
+    <abstract>
+      <para>Once <emphasis>Isis</emphasis> has been bootstrapped, the
+      application state must be setup.</para>
+    </abstract>
+
+    <para>The setup fixtures are used to specify the initial state of the
+    running application for a particular scenario's. Specifically, this means
+    setting up the services that define the application, the effective date
+    and the effective user. It also allows the setup of arbitrary objects
+    (typically reference/static data objects; for transactional objects see
+    <xref linkend="chp.UserInteraction" />).</para>
+
+    <sect1 id="sec.LogonAsSwitchUserTo">
+      <title>Logging On / Switching User</title>
+
+      <para>Used to specify the currently logged-on user. Should always be
+      called near the top of the scenario, as part of the "given". Can also be
+      used for switching the current user later on in the scenario, eg to
+      check a workflow between different users.</para>
+
+      <sect2>
+        <title>Common</title>
+
+        <para>The common library provides two overloaded methods, depending on
+        whether the roles for the user need to be specified or not:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>Scenario#logonAsOrSwitchUserTo(String
+            userName)</methodname></para>
+
+            <para>Logs on / switch user to as a specific user.</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>Scenario#logonAsOrSwitchUserTo(String userName,
+            List&lt;String&gt; roleNames)</methodname></para>
+
+            <para>Logs on to a specific user, with specified roles. Part of
+            the initialization for a particular scenario's setup, and
+            typically referenced in the test suite or scenario's own setup
+            page.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>The username and roles are not validated against.</para>
+      </sect2>
+
+      <sect2>
+        <title>Concordion</title>
+
+        <para>The <emphasis>Concordion</emphasis> integration provides two
+        sets of overloaded methods in
+        <classname>AbstractIsisConcordionScenario</classname>:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#logonAs(String userName)</methodname> and
+            <methodname>#logonAs(String userName, String
+            roleListStr)</methodname></para>
+
+            <para>Intended to be called in the initial setup, as part of the
+            scenario's "given".</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#switchUserTo(String userName)</methodname> and
+            <methodname>#switchUserTo(String userName, String
+            roleListStr)</methodname></para>
+
+            <para>(Optional); intended to be called later on in the scenario,
+            eg, to test workflow.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Each of these is intended to be called from the
+        <acronym>XHTML</acronym>. For example:</para>
+
+        <programlisting>&lt;p concordion:execute="#result=logonAs(#userName)"&gt;&lt;span concordion:assertTrue="#result"&gt;logged on&lt;/span&gt; as &lt;span concordion:set="#userName"&gt;fsmith&lt;/span&gt;&lt;/p&gt;</programlisting>
+
+        <para>The role list, if specified, should be comma-separated (any
+        white space will be ignored).</para>
+      </sect2>
+
+      <sect2>
+        <title>FitNesse</title>
+
+        <para>The FitNesse integration provides two sets of overloaded
+        fixtures:</para>
+
+        <informaltable>
+          <tgroup cols="2">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Logon As</classname></entry>
+
+                <entry><emphasis>user name</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <informaltable>
+          <tgroup cols="4">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Logon As</classname></entry>
+
+                <entry><emphasis>user name</emphasis></entry>
+
+                <entry><classname>With Roles</classname></entry>
+
+                <entry><emphasis>role list</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <para>Intended to be called in the initial setup, as part of the
+        scenario's "given".</para>
+
+        <informaltable>
+          <tgroup cols="2">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Switch User To</classname></entry>
+
+                <entry><emphasis>user name</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <informaltable>
+          <tgroup cols="4">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Switch User To</classname></entry>
+
+                <entry><emphasis>user name</emphasis></entry>
+
+                <entry><classname>With Roles</classname></entry>
+
+                <entry><emphasis>role list</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <para>Optional; intended to be called later on in the scenario, eg, to
+        test workflow.</para>
+
+        <para>The role list, if specified, should be comma-separated (any
+        white space will be ignored).</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="sec.DateAndTimeFormat">
+      <title>Date and Time Format</title>
+
+      <para><acronym>BDD</acronym> tests often rely on exact dates and/or time
+      to be specified, but any such date/time must be specified in text form.
+      In order that tests do not fail when run with different locales, the
+      common library allows a date/time format to be specified.</para>
+
+      <para>This fixture is typically called only once in the scenario.</para>
+
+      <para><note>
+          <para>Date/time formats are based on the currently used locale. By
+          default, Isis will use the current locale. To change this, set the
+          relevant locale within <filename>isis.properties</filename>. For
+          example:</para>
+
+          <programlisting>isis.locale=de_DE</programlisting>
+        </note><note>
+          <para>Dates are always intepreted strictly as UTC dates. This means
+          that you shouldn't need to worry about the timezone in which the
+          tests are being run.</para>
+        </note></para>
+
+      <sect2>
+        <title>Common</title>
+
+        <para>The <classname>Scenario</classname> class provides two methods
+        to specify date and time formats:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#usingDateFormat(String)</methodname> is used to
+            specify the date format.</para>
+
+            <para>If not called, the format defaults to "dd-MMM-yyyy", eg
+            02-Aug-2010.</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#usingTimeFormat(String)</methodname> is used to
+            specify the time format.</para>
+
+            <para>If not called, the time format defaults to "hh:mm" (a 24
+            hour clock, eg 14:45 for 2.45pm)</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Typically the scenario will have both date and also time
+        specified (in <xref linkend="sec.SettingDateAndTime" />), but
+        assertions against domain objects will often care only about date, or
+        may occasionally care only about time. Therefore, whenever text
+        representing a date must be parsed, the following is used:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>parse against date+time (eg "dd-MMM-yyyy hh:mm")</para>
+          </listitem>
+
+          <listitem>
+            <para>if that fails, parse against just date (eg
+            "dd-MMM-yyyy")</para>
+          </listitem>
+
+          <listitem>
+            <para>if that fails, parse against just time (eg "hh:mm")</para>
+          </listitem>
+        </itemizedlist>
+      </sect2>
+
+      <sect2>
+        <title>Concordion</title>
+
+        <para>The <classname>AbstractIsisConcordionScenario</classname>
+        provides two corresponding methods:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#usingDateFormat(String)</methodname></para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#usingTimeFormat(String)</methodname></para>
+          </listitem>
+        </itemizedlist>
+
+        <para>For example:</para>
+
+        <programlisting>&lt;p concordion:execute="#result=timeIs(#dateTime)"&gt;The &lt;span concordion:assertTrue="#result"&gt;date/time&lt;/span&gt; is &lt;span concordion:set="#dateTime"&gt;2 mar 2007 09:20&lt;/span&gt;.&lt;/p&gt; </programlisting>
+
+        <para>These just delegate to the corresponding methods in the
+        <classname>Scenario</classname> class.</para>
+      </sect2>
+
+      <sect2>
+        <title>FitNesse</title>
+
+        <para>Not implemented at this time.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="sec.SettingDateAndTime">
+      <title>Setting Date and Time</title>
+
+      <para><acronym>BDD</acronym> scenarios often rely on an exact date and
+      time, and the date/time that a scenario is being run upon can be
+      specified using this fixture. For example, with the date/time set,
+      functionality that checks the a property is defaulted to "today" can
+      then be easily verified.</para>
+
+      <para>This fixture will typically be called only once in a scenario.
+      However, more advanced scenarios might require the date/time to be
+      called different places. For example, a scenario might raise an
+      <classname>Invoice</classname>, then move the clock forward by 30 days
+      to test functionality relating to the handling of
+      <classname>Invoice</classname>s unpaid for more than 28 days.</para>
+
+      <sect2>
+        <title>Common</title>
+
+        <para>The
+        <methodname>Scenario#dateAndTimeIs(String)</methodname>method allows
+        the scenario to specify the date and time. Note that a
+        <classname>String</classname> is passed in rather than a
+        <classname>java.util.Date</classname>, so that the scenario can parse
+        the date according to the date/time format (see <xref
+        linkend="sec.DateAndTimeFormat" />).</para>
+
+        <para>The fixture installs the <classname>FixtureClock</classname> as
+        the implementation of the <classname>Clock</classname> singleton (in
+        the applib). Every call to the <classname>Clock</classname> will
+        return the same date/time until the method is called again.</para>
+
+        <para>If this fixture is not called, then the default system clock is
+        used, which gets the time from the host computer. The
+        <methodname>Scenario#debugClock()</methodname> method (<xref
+        linkend="sec.DebugClock" />) can be used to verify the clock
+        state.</para>
+      </sect2>
+
+      <sect2>
+        <title>Concordion</title>
+
+        <para>The <emphasis>Concordion</emphasis> integration provides a
+        number of overloaded methods, all designed to be called from the
+        <acronym>XHTML</acronym>:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#dateIs(String
+            dateAndTimeStr)</methodname></para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#timeIs(String
+            dateAndTimeStr)</methodname></para>
+          </listitem>
+        </itemizedlist>
+
+        <para>For example:</para>
+
+        <programlisting>&lt;p concordion:execute="#result=timeIs(#dateTime)"&gt;
+  The &lt;span concordion:assertTrue="#result"&gt;date/time&lt;/span&gt; 
+  is &lt;span concordion:set="#dateTime"&gt;02-mar-2007 09:20&lt;/span&gt;.
+&lt;/p&gt; </programlisting>
+
+        <para>The overloaded forms are just for convenience; sometimes the
+        scenario will want to emphasis the date, other times the time.</para>
+      </sect2>
+
+      <sect2>
+        <title>FitNesse</title>
+
+        <para>The <emphasis>FitNesse</emphasis> integration provides four
+        versions (overloaded only so reads well in the page):</para>
+
+        <informaltable>
+          <tgroup cols="2">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Date Is</classname></entry>
+
+                <entry><emphasis>date and time</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <informaltable>
+          <tgroup cols="2">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Date Is Now</classname></entry>
+
+                <entry><emphasis>date and time</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <informaltable>
+          <tgroup cols="2">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Time Is</classname></entry>
+
+                <entry><emphasis>date and time</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <informaltable>
+          <tgroup cols="2">
+            <colspec />
+
+            <tbody>
+              <row>
+                <entry><classname>Time Is Now</classname></entry>
+
+                <entry><emphasis>date and time</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <para>In each case the date/time provided is parsed against the format
+        'dd MMM yyyy hh:mm'</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="sec.AliasServices">
+      <title>Aliasing Services</title>
+
+      <para>Specifies an alias to a service in order to invoke actions upon
+      it. Typically this will be done for most if not all of the registered
+      repositories. The class name (as defined in
+      <filename>isis.properties</filename>) is used as the key; the alias
+      defines a simple handle.</para>
+
+      <para>For example, a service
+      <classname>com.mycompany.customers.defaults.CustomerRepositoryDefault</classname>
+      can be mapped to "customers".</para>
+
+      <sect2>
+        <title>Common</title>
+
+        <para>The common library provides two methods:<itemizedlist>
+            <listitem>
+              <para><methodname>Scenario#getAliasRegistry()</methodname></para>
+            </listitem>
+
+            <listitem>
+              <para><methodname>AliasRegistry#aliasService(String aliasAs,
+              String serviceClassName)</methodname></para>
+            </listitem>
+          </itemizedlist></para>
+
+        <para>The <acronym>BDD</acronym> framework integration is expected to
+        obtain the <classname>AliasRegistry</classname> from the
+        <classname>Scenario</classname>, and then use the
+        <classname>AliasRegisty</classname> to register the alias.</para>
+      </sect2>
+
+      <sect2>
+        <title>Concordion</title>
+
+        <para>The <methodname>Concordion</methodname> integration provides a
+        corresponding method, <methodname>#aliasService(aliasAs, String
+        serviceClassName)</methodname>. This returns <literal>true</literal>
+        if the service was found, false otherwise. Call within a table to
+        alias multiple services, for example:<programlisting>&lt;table concordion:execute="#result=aliasService(#aliasAs, #className)"&gt;
+  &lt;tr&gt;
+    &lt;th concordion:set="#className"&gt;Class Name&lt;/th&gt;
+    &lt;th concordion:set="#aliasAs"&gt;aliasAs&lt;/th&gt;
+    &lt;th concordion:assertTrue="#result"/&gt;
+  &lt;/tr&gt;
+  &lt;tr&gt;
+    &lt;td&gt;com.mycompany.myapp.objstore.dflt.claim.ClaimRepositoryDefault&lt;/td&gt;
+    &lt;td&gt;claims&lt;/td&gt;
+    &lt;td&gt;ok&lt;/td&gt;
+  &lt;/tr&gt;
+  &lt;tr&gt;
+    &lt;td&gt;com.mycompany.myapp.objstore.dflt.employee.EmployeeRepositoryDefault&lt;/td&gt;
+    &lt;td&gt;employees&lt;/td&gt;
+    &lt;td&gt;ok&lt;/td&gt;
+  &lt;/tr&gt;
+&lt;/table&gt;</programlisting></para>
+      </sect2>
+
+      <sect2>
+        <title>FitNesse</title>
+
+        <para>The <emphasis>FitNesse</emphasis> integration provides an
+        implementation of a <classname>ColumnFixture</classname>, which is
+        used as follows:</para>
+
+        <para><informaltable>
+            <tgroup cols="2">
+              <colspec colname="_1" />
+
+              <colspec colname="_2" />
+
+              <tbody>
+                <row>
+                  <entry nameend="_2" namest="_1"><classname>Alias
+                  Services</classname></entry>
+                </row>
+
+                <row>
+                  <entry><classname>class name</classname></entry>
+
+                  <entry><classname>alias=</classname></entry>
+                </row>
+
+                <row>
+                  <entry><emphasis>com.mycompany.myapp.objstore.dflt.claim.ClaimRepositoryDefault</emphasis></entry>
+
+                  <entry><emphasis>claims</emphasis></entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </informaltable></para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="sec.SetUpObjects">
+      <title>Setting Up Objects</title>
+
+      <para>Virtually every scenario will require some initial objects to work
+      on, be it a <classname>Customer</classname>, an
+      <classname>Order</classname> or just some reference data. However, by
+      design the <acronym>BDD</acronym> viewer runs against an in-memory
+      object store, meaning that the application having been bootstrapped has
+      nothing in its persistent object store.</para>
+
+      <para>This fixture, therefore, is used to create objects, and persists
+      them to the object store. It is typically used for immutable
+      reference/standing data objects. It can also be to setup used for
+      transaction/operational data objects, though
+      <classname>UsingIsisViewerForSetup</classname>, <xref
+      linkend="chp.UserInteraction" />, is generallly to be preferred).</para>
+
+      <para>The <classname>DebugObjectStore</classname> fixture (<xref
+      linkend="sec.DebugObjectStore" />) can be used to check the state of
+      objects created. You can also use the RunViewer fixture (<xref
+      linkend="sec.RunViewer" />) to visually inspect the state of the system
+      using the DnD viewer.</para>
+
+      <sect2>
+        <title>Common</title>
+
+        <para>The common library support for setting up objects using the
+        <classname>SetUpObjectsPeer</classname> class. This represents the
+        context for creating a set of objects all of the same type, and is
+        usually called multiple times (eg corresponding to a table structure
+        in the scenario text itself).</para>
+
+        <para>The constructor for this class takes the following
+        arguments:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><classname>AliasRegistry</classname>
+            <varname>aliasRegistry</varname></para>
+
+            <para>the alias registry which is used to lookup aliases to
+            existing objects, and is populated with aliases for the new
+            created objects (if an alias binding is specified; see
+            below).</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>String</classname>
+            <varname>className</varname></para>
+
+            <para>This is the fully qualified class name of the object to be
+            instantiated</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>SetUpObjectsPeer.Mode</classname>
+            <varname>mode</varname></para>
+
+            <para>This is whether the object is to be persisted or not</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>CellBinding</classname>
+            <varname>aliasBinding</varname></para>
+
+            <para>This object represents a binding to a cell that will hold
+            the reference to each newly created object. It can be left
+            <literal>null</literal> if required.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Different methods are available for <acronym>BDD</acronym>
+        framework integrations to call. Typically the <acronym>BDD</acronym>
+        framework is expected to setup header information (the names of the
+        properties), and then process each row.</para>
+
+        <para>On the header of the table, the main method to call
+        is:<itemizedlist>
+            <listitem>
+              <para><methodname>#definePropertyOrAlias(String
+              propertyNameOrAlias, int colNum)</methodname></para>
+
+              <para>This associates each column with a property of the class,
+              or an alias for the object overall</para>
+            </listitem>
+          </itemizedlist></para>
+
+        <para>When processing each row, typically the main methods to call
+        are:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#addPropertyValueOrAlias(String
+            propertyOrAliasValue)</methodname></para>
+
+            <para>This provides the value of each property of the object to be
+            created, or the alias to know the object by once created. The
+            property value can either be an existing alias, else must be
+            parseable (nb: Isis' own value types itself perform the parsing,
+            so there's no additional work to be done here)</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#createObject()</methodname></para>
+
+            <para>This actually instantiates the object, either persistent or
+            non-persistent as specified in the constructor, and assigns it an
+            alias</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>That said, there are some other public methods that are
+        available for more complex integrations (notably:
+        <emphasis>FitNesse</emphasis>).</para>
+      </sect2>
+
+      <sect2>
+        <title>Concordion</title>
+
+        <para>The <emphasis>Concordion</emphasis> framework integration
+        provides:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#setUpObject(String className, String aliasAs,
+            String propertyName1, String propertyName2,
+            ...)</methodname></para>
+
+            <para>There are 10 overloaded versions of this method, to account
+            for setting up different types of objects that have up to 10
+            properties.</para>
+
+            <para>The method returns a string "ok" if has worked, otherwise it
+            returns exception text. This might seem a little odd, but allows a
+            meaningful message to be shown in the
+            <acronym>XHTML</acronym>.</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#setUpObjectVarArgs(String className, String
+            aliasAs, ...)</methodname></para>
+
+            <para>This (protected, not public) method is to cater for setting
+            up objects that require more than 10 properties to be setup. In
+            these cases, the developer should write their own method and call
+            into the <methodname>#setUpObjectsVarargs(...)</methodname> as
+            required.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Note that this method should be called from the
+        <acronym>XHTML</acronym> using <literal>isis:execute</literal>, not
+        with <literal>concordion:execute</literal>. The difference between the
+        two is that <literal>isis:execute</literal> is called on the header
+        row as well as each body row, whereas concordion:execute only calls
+        for each body row. The integration requires the header row to be
+        called in order to read the names of the properties to be used to
+        initialize the objects.</para>
+
+        <para>For example, here's how to setup a set of three
+        <classname>Employee</classname> objects:</para>
+
+        <programlisting>&lt;p&gt;With Employees (&lt;span concordion:set="#className"&gt;com.mycompany.myapp.dom.employee.Employee&lt;/span&gt;):
+&lt;/p&gt;
+&lt;table isis:execute="#result=setUpObject(#className, #aliasAs, #name, #approver)"&gt;
+  &lt;tr&gt;
+    &lt;th concordion:set="#name"&gt;Name&lt;/th&gt;
+    &lt;th concordion:set="#approver"&gt;Approver&lt;/th&gt;
+    &lt;th concordion:set="#aliasAs"&gt;aliasAs&lt;/th&gt;
+    &lt;th concordion:assertEquals="#result"/&gt;
+  &lt;/tr&gt;
+  &lt;tr&gt;
+    &lt;td&gt;Fred Smith&lt;/td&gt;
+    &lt;td&gt;&lt;/td&gt;
+    &lt;td&gt;Employee:Fred Smith&lt;/td&gt;
+    &lt;td&gt;ok&lt;/td&gt;
+  &lt;/tr&gt;
+  &lt;tr&gt;
+    &lt;td&gt;Tom Brown&lt;/td&gt;
+    &lt;td&gt;Employee:Fred Smith&lt;/td&gt;
+    &lt;td&gt;Employee:Tom Brown&lt;/td&gt;
+    &lt;td&gt;ok&lt;/td&gt;
+  &lt;/tr&gt;
+  &lt;tr&gt;
+    &lt;td&gt;Sam Jones&lt;/td&gt;
+    &lt;td&gt;Employee:Fred Smith&lt;/td&gt;
+    &lt;td&gt;Employee:Sam Jones&lt;/td&gt;
+    &lt;td&gt;ok&lt;/td&gt;
+  &lt;/tr&gt;
+&lt;/table&gt;</programlisting>
+
+        <para>In this example, we've chosen the convention that the alias is
+        "Employee:<emphasis>FirstName LastName</emphasis>". This is though
+        just a convention; the alias could be anything you want.</para>
+      </sect2>
+
+      <sect2>
+        <title>FitNesse</title>
+
+        <para>The <emphasis>FitNesse</emphasis> integration uses the "Set Up
+        Objects" table, called like so:</para>
+
+        <informaltable>
+          <tgroup cols="3">
+            <colspec colname="_1" />
+
+            <colspec colname="_2" />
+
+            <colspec colname="_3" />
+
+            <tbody>
+              <row>
+                <entry><classname>Set Up Objects</classname></entry>
+
+                <entry nameend="_3"
+                namest="_2"><emphasis>com.mycompany.myapp.dom.employee.Employee</emphasis></entry>
+              </row>
+
+              <row>
+                <entry><classname>Name</classname></entry>
+
+                <entry><classname>Approver</classname></entry>
+
+                <entry><classname>alias as</classname></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>Fred Smith</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><emphasis>Employee:Fred Smith</emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>Tom Brown</emphasis></entry>
+
+                <entry><emphasis>Employee:Fred Smith</emphasis></entry>
+
+                <entry><emphasis>Employee:Tom Brown</emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>Sam Jones</emphasis></entry>
+
+                <entry><emphasis>Employee:Fred Smith</emphasis></entry>
+
+                <entry><emphasis>Employee:Sam Jones</emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+      </sect2>
+    </sect1>
+  </chapter>
+
+  <chapter id="chp.UserInteraction">
+    <title>User Interaction</title>
+
+    <abstract>
+      <para>Fixtures to describe interactions with the domain objects,
+      mimicking the way in which an end-user using an Isis viewer would
+      interact.</para>
+    </abstract>
+
+    <para>The user interaction fixtures are the centrepiece of the
+    <acronym>BDD</acronym> framework, simulating the interaction with domain
+    objects as if through a viewer. Using this fixtures, the scenario can
+    interact with objects, check their state, and alias referenced or returned
+    objects for subsequent interactions</para>
+
+    <para>There is basically just one fixture used to describe user
+    interactions, namely "Using Isis Viewer". There is also a "For Setup"
+    version (ie "Using Isis Viewer For Setup") that disables checks for
+    visibility and usability, making it easier to reuse functionality for
+    setting up objects prior to a test scenario (the "given").</para>
+
+    <para>The <classname>DebugObjectStore</classname> fixture (<xref
+    linkend="sec.DebugObjectStore" />) can be used to check the state of
+    objects created.</para>
+
+    <sect1>
+      <title>Common</title>
+
+      <para>The common library provides the
+      <classname>UsingIsisViewerPeer</classname> class as a means by which the
+      <acronym>BDD</acronym> framework integration can interact with
+      <emphasis>Apache Isis</emphasis> runtime.</para>
+
+      <para>The <classname>UsingIsisViewerPeer</classname> class is generally
+      called from within a table format, with each row representing a specific
+      interaction with the domain object. For example, a row might invoke an
+      action, or could check that a class member is unavailable.</para>
+
+      <para>Some interactions can be used to create or assign aliases to
+      domain objects. For example, invoking a non-void action will return a
+      result. If the result is a domain object, then the alias can be used
+      directly subsequently in the scenario. If the result is a collection,
+      then typically it is the scenario will make an assertion on that
+      collection using "Check List" (see <xref linkend="sec.CheckList" />) or
+      alias an object out of that list using "Alias Items In List" (see <xref
+      linkend="sec.AliasItemsInList" />).</para>
+
+      <sect2>
+        <title>Constructor</title>
+
+        <para>Because <classname>UsingIsisViewerPeer</classname> is
+        table-oriented, it uses <classname>CellBinding</classname>s (see <xref
+        linkend="sec.CommonLibrary" />) to bind table headers to rows. The
+        constructor takes the following parameters:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><classname>AliasRegistry</classname></para>
+
+            <para>Used to access aliases for existing domain objects, and to
+            register aliases for newly created/found objects.</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>Perform.Mode</classname></para>
+
+            <para>Whether to actually perform the interactions or not</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>CellBinding</classname>s for each of the columns
+            of the table.</para>
+
+            <para>Cell bindings are discussed immediately below.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Each of the framework integrations is expected to instantiate
+        the <classname>UsingIsisViewerPeer</classname> at the beginning of the
+        table, and then call into the same instance for each row in the
+        table.</para>
+
+        <sect3>
+          <title>Cell Bindings</title>
+
+          <para>The <classname>CellBinding</classname>s passed into the
+          constructor correspond to the standard columns of the table.
+          Although all must be passed in, not all are needed for every
+          interaction; in these cases the value can be left blank. The
+          <classname>CellBinding</classname>s correspond to the following
+          column names:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>the "on object" column (can also use 'object', or 'on' if
+              parsing column name provided by scenario text)</para>
+
+              <para>The (alias of) the object to interact with. A value must
+              always be provided.</para>
+            </listitem>
+
+            <listitem>
+              <para>the "alias result as" column (can also use "result=",
+              "alias=", "alias as")</para>
+
+              <para>The alias to assign the result of any interaction.</para>
+            </listitem>
+
+            <listitem>
+              <para>the "perform" column (can also use "do", "interaction",
+              "interaction type")</para>
+
+              <para>the interaction to perform; discussed further below</para>
+            </listitem>
+
+            <listitem>
+              <para>the "on member" column (can also use "member", "using
+              member", using")</para>
+
+              <para>the property, collection or action to use</para>
+            </listitem>
+
+            <listitem>
+              <para>the "that it" column (can also use "that", "verb")</para>
+
+              <para>optional qualifier for interactions that make checks;
+              discussed below</para>
+            </listitem>
+
+            <listitem>
+              <para>the "with arguments" (can also "arguments", "parameters",
+              "with parameters", "for", "value", "for parameters", "value",
+              "reference")</para>
+
+              <para>the first argument, to the interaction, if any. It is
+              possible to perform interactions with multiple arguments (for
+              example, invoking an action); but the
+              <classname>UsingIsisViewerPeer</classname> needs to have a
+              binding for the first argument so that it can knows to interpret
+              any following columns as further arguments.</para>
+            </listitem>
+          </itemizedlist>
+
+          <para>The actual values that go into each of these columns are
+          listed below (<xref linkend="sec.SupportedInteractions" />).</para>
+        </sect3>
+
+        <sect3>
+          <title>The "Perform" Binding</title>
+
+          <para>Of all of the bindings discussed above, the "perform" binding
+          is the most critical because it determines the actual type of
+          interaction to be performed. The valid values that can be provided
+          for the "perform" binding are:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>check property / check collection / check add to
+              collection / check remove from collection / check action</para>
+
+              <para>These are combined with a value in the "that it" binding;
+              for example "check property XXX is hidden", or "check action XXX
+              is valid for (<emphasis>some argument list</emphasis>)"</para>
+            </listitem>
+
+            <listitem>
+              <para>get property / set property / clear property</para>
+
+              <para>Read from or write to a collection. If setting, a single
+              argument is required</para>
+            </listitem>
+
+            <listitem>
+              <para>get collection / add to collection / remove from
+              collection</para>
+
+              <para>Read or write from a collection. If writing, a single
+              argument is required</para>
+            </listitem>
+
+            <listitem>
+              <para>invoke action</para>
+
+              <para>Invoke action, with 0 to many arguments</para>
+            </listitem>
+
+            <listitem>
+              <para>get property default / get property choices / get action
+              parameter default / get action choices</para>
+
+              <para>To enable the testing of the
+              <methodname>choicesXxx()</methodname> and
+              <methodname>defaultXxx()</methodname> supporting methods</para>
+            </listitem>
+          </itemizedlist>
+
+          <para>Again, see the sections below (<xref
+          linkend="sec.SupportedInteractions" />) for specifics..</para>
+        </sect3>
+      </sect2>
+
+      <sect2>
+        <title>Capture Current</title>
+
+        <para>Once the bindings have been setup, the fixture peer should be
+        called for each row in the table. The
+        <classname>CellBinding</classname> class provides the
+        <methodname>#captureCurrent(...)</methodname> method to capture the
+        relevant value for each row (with the
+        <classname>CellBinding</classname>s obtained directory from the
+        <classname>Scenario</classname> class, eg
+        <methodname>Scenario#getOnObjectBinding()</methodname>).</para>
+
+        <para>For some framework integrations (eg
+        <methodname>Concordion</methodname>) this design introduces a little
+        more complexity than strictly necessary, because the knowledge is
+        already known as to which value relates to which binding. But for
+        other frameworks (eg FitNesse), the <classname>CellBinding</classname>
+        provides a useful abstraction that makes it easy to associate values
+        with each column.</para>
+      </sect2>
+
+      <sect2>
+        <title>Validate</title>
+
+        <para>Once the values for the current row have been captured, they can
+        be validated. The <classname>UsingIsisViewerPeer</classname> class
+        provides the following methods for this:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><methodname>#validateOnObject():
+            ObjectAdapter</methodname></para>
+
+            <para>Verifies that the current value of the "on object" binding
+            corresponds to a known alias</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#validateAliasAs(): String</methodname></para>
+
+            <para>Verifies that the current value of the "alias as" binding is
+            not already in use</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#validateOnMember():
+            ObjectMember</methodname></para>
+
+            <para>Verifies that the current value of the "on member" binding
+            corresponds to the name of a member (property name, collection
+            name or action name) of the type of the object being interacted
+            with (ie, as specified in the "on object" binding)</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>#validatePerform(): Perform</methodname></para>
+
+            <para>Verifies that the current value of the "perform" binding
+            corresponds to a known interaction type for the particular type of
+            member.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Again, see the sections below (<xref
+        linkend="sec.SupportedInteractions" />) for specifics.</para>
+      </sect2>
+
+      <sect2>
+        <title>Perform Command</title>
+
+        <para>Once all the validation has been performed, the command can
+        actually be performed. This is done with the
+        <classname>UsingIsisViewerPeer</classname>'s
+        <methodname>#performCommand(ObjectAdapter onObject, String aliasAs,
+        ObjectMember onMember, Perform perform, List&lt;ScenarioCell&gt;
+        args)</methodname> method.</para>
+      </sect2>
+    </sect1>
+
+    <sect1 id="sec.SupportedInteractions">
+      <title>Supported Interactions</title>
+
+      <para>The valid values for the various bindings when interacting with a
+      class members are summarized in the following sections.</para>
+
+      <para>Note:</para>
+
+      <itemizedlist>
+        <listitem>
+          <para>the <acronym>API</acronym> provided by the common library is
+          not type-safe; the values (as provided in
+          <classname>ScenarioCell</classname>) must match the values given
+          here. While it is tempting to refactor the common library to use
+          type safe enums, this would move the need to translate scenario text
+          into each and every <acronym>BDD</acronym> framework integration.
+          The <acronym>API</acronym> is probably correct as it is, even though
+          it is reliant on the exact string phrases that appear in the tables
+          above.</para>
+        </listitem>
+      </itemizedlist>
+
+      <sect2 id="sec.InteractingWithProperties">
+        <title>Interaction with Properties</title>
+
+        <para>The valid values for the various bindings when interacting with
+        a property are summarized below:</para>
+
+        <table>
+          <title>Supported Interactions for Properties</title>
+
+          <tgroup cols="6">
+            <colspec colname="_4" colnum="4" />
+
+            <colspec colname="_5" />
+
+            <colspec colname="_6" />
+
+            <thead>
+              <row>
+                <entry align="center">on object</entry>
+
+                <entry align="center">alias as</entry>
+
+                <entry align="center">perform</entry>
+
+                <entry align="center">using member</entry>
+
+                <entry align="center">that it</entry>
+
+                <entry align="center">value</entry>
+              </row>
+            </thead>
+
+            <tbody>
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is
+                hidden</classname><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is
+                visible</classname><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is
+                disabled</classname><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is
+                enabled</classname><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is
+                empty</classname><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is not
+                empty</classname><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry><classname>contains</classname></entry>
+
+                <entry><emphasis>value or object alias</emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry><classname>does not contain</classname></entry>
+
+                <entry><emphasis>value or object alias</emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check set property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry><classname>is valid for</classname></entry>
+
+                <entry><emphasis>value or object alias </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check set property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry><classname>is not valid for</classname></entry>
+
+                <entry><emphasis> value or object alias</emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check clear property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is
+                valid</classname><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check clear property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is not
+                valid</classname></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>set property</classname></entry>
+
+                <entry><emphasis>property name</emphasis></entry>
+
+                <entry><classname> </classname></entry>
+
+                <entry><emphasis>value or object alias </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>clear property</classname></entry>
+
+                <entry nameend="_6" namest="_4"><emphasis>property
+                name</emphasis><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis>alias for referenced object
+                </emphasis></entry>
+
+                <entry><classname>get property</classname></entry>
+
+                <entry nameend="_6" namest="_4"><emphasis>property
+                name</emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis>alias for default object </emphasis></entry>
+
+                <entry><classname>get property default</classname></entry>
+
+                <entry nameend="_6" namest="_4"><emphasis>property
+                name</emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis>alias for list of choices</emphasis></entry>
+
+                <entry><classname>get property choices</classname></entry>
+
+                <entry nameend="_6" namest="_4"><emphasis>property
+                name</emphasis><emphasis> </emphasis></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
+
+        <para>Obtaining a alias for the (value of) a property only makes sense
+        if the property is a reference type, not value type.</para>
+      </sect2>
+
+      <sect2 id="sec.InteractingWithCollections">
+        <title>Interacting with Collections</title>
+
+        <para>The valid values for the various bindings when interacting with
+        a collection are summarized below:</para>
+
+        <table>
+          <title>Supported Interactions for Collections</title>
+
+          <tgroup cols="6">
+            <colspec colname="_4" colnum="4" />
+
+            <colspec colname="_5" />
+
+            <colspec colname="_6" />
+
+            <thead>
+              <row>
+                <entry align="center">on object</entry>
+
+                <entry align="center">alias as</entry>
+
+                <entry align="center">perform</entry>
+
+                <entry align="center">using member</entry>
+
+                <entry align="center">that it</entry>
+
+                <entry align="center">reference</entry>
+              </row>
+            </thead>
+
+            <tbody>
+              <row>
+                <entry><emphasis>object alias</emphasis></entry>
+
+                <entry><emphasis> </emphasis></entry>
+
+                <entry><classname>check collection</classname></entry>
+
+                <entry><emphasis>collection name</emphasis></entry>
+
+                <entry nameend="_6" namest="_5"><classname>is
+                hidden</classname><emphasis> </emphasis></entry>
+              </row>
+
+              <row>
+                <entry><emphasis

<TRUNCATED>