[jboss-cvs] jboss-seam/doc/reference/en/modules ...

Norman Richards norman.richards at jboss.com
Sat May 26 22:55:14 EDT 2007


  User: nrichards
  Date: 07/05/26 22:55:14

  Modified:    doc/reference/en/modules  tutorial.xml
  Log:
  updates for 1.3
  
  Revision  Changes    Path
  1.83      +1809 -2208jboss-seam/doc/reference/en/modules/tutorial.xml
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: tutorial.xml
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/doc/reference/en/modules/tutorial.xml,v
  retrieving revision 1.82
  retrieving revision 1.83
  diff -u -b -r1.82 -r1.83
  --- tutorial.xml	22 Mar 2007 01:30:26 -0000	1.82
  +++ tutorial.xml	27 May 2007 02:55:14 -0000	1.83
  @@ -4,38 +4,29 @@
     <section id="try-examples">
       <title>Try the examples</title>
       
  -    <para>
  -      In this tutorial, we'll assume that you have downloaded JBoss AS 4.0.5 and installed the
  -      EJB 3.0 profile (using the JBoss AS installer). You should also have a copy of Seam
  -      downloaded and extracted to a work directory.
  -    </para>
  +        <para> In this tutorial, we'll assume that you have downloaded JBoss AS 4.2.0. You should also have a copy of
  +            Seam downloaded and extracted to a work directory. </para>
       
  -    <para>
  -      The directory structure of each example in Seam follows this pattern:
  -    </para>
  +        <para> The directory structure of each example in Seam follows this pattern: </para>
   
       <itemizedlist>
           <listitem>
  -          <para>
  -              Web pages, images and stylesheets may be found in
  +                <para> Web pages, images and stylesheets may be found in
                 <filename>examples/<replaceable>registration</replaceable>/view</filename>
              </para>
           </listitem>
           <listitem>
  -          <para>
  -              Resources such as deployment descriptors and data import scripts may be found in
  +                <para> Resources such as deployment descriptors and data import scripts may be found in
                 <filename>examples/<replaceable>registration</replaceable>/resources</filename>
              </para>
           </listitem>
           <listitem>
  -           <para>
  -              Java source code may be found in
  +                <para> Java source code may be found in
                 <filename>examples/<replaceable>registration</replaceable>/src</filename>
              </para>
           </listitem>
           <listitem>
  -           <para>
  -              The Ant build script is
  +                <para> The Ant build script is
                 <filename>examples/<replaceable>registration</replaceable>/build.xml</filename>
              </para>
           </listitem>
  @@ -44,68 +35,49 @@
       <section>
          <title>Running the examples on JBoss AS</title>
          
  -       <para>
  -           First, make sure you have Ant correctly installed, with <literal>$ANT_HOME</literal>
  -           and <literal>$JAVA_HOME</literal> set correctly. Next, make sure you set the
  -           location of your JBoss AS 4.0.5 installation in the <literal>build.properties</literal>
  -           file in the root folder of your Seam installation. If you haven't already done so, start 
  -           JBoss AS now by typing <literal>bin/run.sh</literal> or <literal>bin/run.bat</literal> 
  -           in the root directory of your JBoss installation.
  -       </para>
  -       
  -       <para>
  -            Now, build and deploy the example by typing <literal>ant deploy</literal> in the
  -            <filename>examples/<replaceable>registration</replaceable></filename> directory.
  -        </para>
  -        
  -        <para>
  -            Try it out by accessing 
  -            <ulink url="http://localhost:8080/seam-registration/"><literal>http://localhost:8080/seam-registration/</literal></ulink>
  -            with your web browser.
  -        </para>
  +            <para> First, make sure you have Ant correctly installed, with <literal>$ANT_HOME</literal> and
  +                    <literal>$JAVA_HOME</literal> set correctly. Next, make sure you set the location of your JBoss AS
  +                4.2.0 installation in the <literal>build.properties</literal> file in the root folder of your Seam
  +                installation. If you haven't already done so, start JBoss AS now by typing <literal>bin/run.sh</literal>
  +                or <literal>bin/run.bat</literal> in the root directory of your JBoss installation. </para>
  +
  +            <para> Now, build and deploy the example by typing <literal>ant deploy</literal> in the
  +                        <filename>examples/<replaceable>registration</replaceable></filename> directory. </para>
  +
  +            <para> Try it out by accessing <ulink url="http://localhost:8080/seam-registration/">
  +                    <literal>http://localhost:8080/seam-registration/</literal>
  +                </ulink> with your web browser. </para>
           
       </section>
           
       <section>
          <title>Running the examples on Tomcat</title>
          
  -       <para>
  -           First, make sure you have Ant correctly installed, with <literal>$ANT_HOME</literal>
  -           and <literal>$JAVA_HOME</literal> set correctly. Next, make sure you set the
  -           location of your Tomcat 5.5 installation in the <literal>build.properties</literal>
  -           file in the root folder of your Seam installation.
  -       </para>
  -       
  -       <para>
  -            Now, build and deploy the example by typing <literal>ant deploy.tomcat</literal> in the
  -            <filename>examples/<replaceable>registration</replaceable></filename> directory.
  -        </para>
  -        
  -        <para>
  -            Finally, start Tomcat.
  -        </para>
  +            <para> First, make sure you have Ant correctly installed, with <literal>$ANT_HOME</literal> and
  +                    <literal>$JAVA_HOME</literal> set correctly. Next, make sure you set the location of your Tomcat 6.0
  +                installation in the <literal>build.properties</literal> file in the root folder of your Seam
  +                installation. </para>
  +
  +            <para> Now, build and deploy the example by typing <literal>ant deploy.tomcat</literal> in the
  +                        <filename>examples/<replaceable>registration</replaceable></filename> directory. </para>
  +
  +            <para> Finally, start Tomcat. </para>
  +
  +            <para> Try it out by accessing <ulink url="http://localhost:8080/jboss-seam-registration/">
  +                    <literal>http://localhost:8080/jboss-seam-registration/</literal>
  +                </ulink> with your web browser. </para>
           
  -        <para>
  -            Try it out by accessing 
  -            <ulink url="http://localhost:8080/jboss-seam-registration/"><literal>http://localhost:8080/jboss-seam-registration/</literal></ulink>
  -            with your web browser.
  -        </para>
  -        
  -        <para>
  -            When you deploy the example to Tomcat, any EJB3 components will run inside the JBoss 
  -            Embeddable EJB3 container, a complete standalone EJB3 container environment.
  -        </para>
  +            <para> When you deploy the example to Tomcat, any EJB3 components will run inside the JBoss Embeddable EJB3
  +                container, a complete standalone EJB3 container environment. </para>
           
       </section>
           
       <section>
          <title>Running the example tests</title>
  -       <para>
  -           Most of the examples come with a suite of TestNG integration tests. The easiest way 
  -           to run the tests is to run <literal>ant testexample</literal> inside the
  -           <filename>examples/<replaceable>registration</replaceable></filename> directory.
  -           It is also possible to run the tests inside your IDE using the TestNG plugin.
  -       </para>
  +            <para> Most of the examples come with a suite of TestNG integration tests. The easiest way to run the tests
  +                is to run <literal>ant testexample</literal> inside the
  +                    <filename>examples/<replaceable>registration</replaceable></filename> directory. It is also possible
  +                to run the tests inside your IDE using the TestNG plugin. </para>
       </section>
              
     </section>
  @@ -113,21 +85,15 @@
     <section id="registration-example">
       <title>Your first Seam application: the registration example</title>
   
  -    <para>
  -        The registration example is a fairly trivial application that lets a new user store
  -        his username, real name and password in the database. The example isn't intended to
  -        show off all of the cool functionality of Seam. However, it demonstrates the use of
  -        an EJB3 session bean as a JSF action listener, and basic configuration of Seam.
  -    </para>
  +        <para> The registration example is a fairly trivial application that lets a new user store his username, real
  +            name and password in the database. The example isn't intended to show off all of the cool functionality of
  +            Seam. However, it demonstrates the use of an EJB3 session bean as a JSF action listener, and basic
  +            configuration of Seam. </para>
       
  -    <para>
  -        We'll go slowly, since we realize you might not yet be familiar with EJB 3.0.
  -    </para>
  +        <para> We'll go slowly, since we realize you might not yet be familiar with EJB 3.0. </para>
           
  -    <para>
  -        The start page displays a very basic form with three input fields. Try filling them
  -        in and then submitting the form. This will save a user object in the database.
  -    </para>
  +        <para> The start page displays a very basic form with three input fields. Try filling them in and then
  +            submitting the form. This will save a user object in the database. </para>
   
           <mediaobject>
             <imageobject role="fo">
  @@ -141,10 +107,7 @@
       <section>
         <title>Understanding the code</title>
         
  -      <para>
  -          The example is implemented with two JSP pages, one entity bean and one stateless
  -          session bean.
  -      </para>
  +            <para> The example is implemented with two JSP pages, one entity bean and one stateless session bean. </para>
   
           <mediaobject>
             <imageobject role="fo">
  @@ -155,18 +118,14 @@
             </imageobject>
           </mediaobject>
           
  -      <para>
  -          Let's take a look at the code, starting from the "bottom".
  -      </para>
  +            <para> Let's take a look at the code, starting from the "bottom". </para>
         
         <section>
           <title>The entity bean: <literal>User.java</literal></title>
   
  -        <para>
  -            We need an EJB entity bean for user data. This class defines <emphasis>persistence</emphasis>  
  -            and <emphasis>validation</emphasis> declaratively, via annotations. It also needs some extra
  -            annotations that define the class as a Seam component.
  -        </para>
  +                <para> We need an EJB entity bean for user data. This class defines <emphasis>persistence</emphasis> and
  +                        <emphasis>validation</emphasis> declaratively, via annotations. It also needs some extra
  +                    annotations that define the class as a Seam component. </para>
   
           <example>
               <programlistingco>
  @@ -237,85 +196,65 @@
   }]]></programlisting>
                   <calloutlist>
                       <callout arearefs="registration-entity-annotation">
  -                        <para>
  -                            The EJB3 standard <literal>@Entity</literal> annotation indicates that the
  -                            <literal>User</literal> class is an entity bean.
  -                        </para>
  +                                <para> The EJB3 standard <literal>@Entity</literal> annotation indicates that the
  +                                        <literal>User</literal> class is an entity bean. </para>
                       </callout>
                       <callout arearefs="registration-name-annotation">
  -                        <para>
  -                            A Seam component needs a <emphasis>component name</emphasis> specified by the 
  -                            <link linkend="name-annotation"><literal>@Name</literal></link> annotation. This 
  -                            name must be unique within the Seam application. When JSF asks Seam to resolve
  -                            a context variable with a name that is the same as a Seam component name, and
  -                            the context variable is currently undefined (null), Seam will instantiate that
  -                            component, and bind the new instance to the context variable. In this case,
  -                            Seam will instantiate a <literal>User</literal> the first time JSF encounters
  -                            a variable named <literal>user</literal>.
  -                        </para>
  +                                <para> A Seam component needs a <emphasis>component name</emphasis> specified by the
  +                                        <link linkend="name-annotation">
  +                                        <literal>@Name</literal>
  +                                    </link> annotation. This name must be unique within the Seam application. When JSF
  +                                    asks Seam to resolve a context variable with a name that is the same as a Seam
  +                                    component name, and the context variable is currently undefined (null), Seam will
  +                                    instantiate that component, and bind the new instance to the context variable. In
  +                                    this case, Seam will instantiate a <literal>User</literal> the first time JSF
  +                                    encounters a variable named <literal>user</literal>. </para>
                       </callout>
                       <callout arearefs="registration-scope-annotation">
  -                        <para>
  -                            Whenever Seam instantiates a component, it binds the new instance to a context
  +                                <para> Whenever Seam instantiates a component, it binds the new instance to a context
                               variable in the component's <emphasis>default context</emphasis>. The default 
  -                            context is specified using the 
  -                            <link linkend="scope-annotation"><literal>@Scope</literal></link> annotation. 
  -                            The <literal>User</literal> bean is a session scoped component.
  +                                    context is specified using the <link linkend="scope-annotation">
  +                                        <literal>@Scope</literal>
  +                                    </link> annotation. The <literal>User</literal> bean is a session scoped component.
                           </para>
                       </callout>
                       <callout arearefs="registration-table-annotation">
  -                        <para>
  -                            The EJB standard <literal>@Table</literal> annotation indicates that 
  -                            the <literal>User</literal> class is mapped to the <literal>users</literal>
  -                            table.
  +                                <para> The EJB standard <literal>@Table</literal> annotation indicates that the
  +                                        <literal>User</literal> class is mapped to the <literal>users</literal> table.
                           </para>
                       </callout>
                       <callout arearefs="registration-attributes">
                           <para>
  -                            <literal>name</literal>, <literal>password</literal> and
  -                            <literal>username</literal> are the persistent attributes of the 
  -                            entity bean. All of our persistent attributes define accessor
  -                            methods. These are needed when this component is used by JSF
  -                            in the render response and update model values phases.
  -                        </para>
  +                                    <literal>name</literal>, <literal>password</literal> and <literal>username</literal>
  +                                    are the persistent attributes of the entity bean. All of our persistent attributes
  +                                    define accessor methods. These are needed when this component is used by JSF in the
  +                                    render response and update model values phases. </para>
                       </callout>
                       <callout arearefs="registration-empty-constructor">
  -                        <para>
  -                            An empty constructor is both required by both the EJB specification 
  -                            and by Seam.
  +                                <para> An empty constructor is both required by both the EJB specification and by Seam.
                           </para>
                       </callout>
                       <callout arearefs="registration-notnull">
  -                        <para>
  -                            The <literal>@NotNull</literal> and <literal>@Length</literal> 
  -                            annotations are part of the Hibernate Validator framework. Seam 
  -                            integrates Hibernate Validator and lets you use it for data validation 
  -                            (even if you are not using Hibernate for persistence).
  -                        </para>
  +                                <para> The <literal>@NotNull</literal> and <literal>@Length</literal> annotations are
  +                                    part of the Hibernate Validator framework. Seam integrates Hibernate Validator and
  +                                    lets you use it for data validation (even if you are not using Hibernate for
  +                                    persistence). </para>
                       </callout>
                       <callout arearefs="registration-id-annotation">
  -                        <para>
  -                            The EJB standard <literal>@Id</literal> annotation indicates the 
  -                            primary key attribute of the entity bean.
  -                        </para>
  +                                <para> The EJB standard <literal>@Id</literal> annotation indicates the primary key
  +                                    attribute of the entity bean. </para>
                       </callout>
                   </calloutlist>
               </programlistingco>
  -            <para>
  -                The most important things to notice in this example are the <literal>@Name</literal>
  -                and <literal>@Scope</literal> annotations. These annotations establish that this class
  -                is a Seam component.
  -            </para>
  -            <para>
  -                We'll see below that the properties of our <literal>User</literal> class are bound 
  -                to directly to JSF components and are populated by JSF during the update model values
  -                phase. We don't need any tedious glue code to copy data back and forth between the 
  -                JSP pages and the entity bean domain model.
  -            </para>
  -            <para>
  -                However, entity beans shouldn't do transaction management or database access. So we 
  -                can't use this component as a JSF action listener. For that we need a session bean.
  -            </para>
  +                    <para> The most important things to notice in this example are the <literal>@Name</literal> and
  +                            <literal>@Scope</literal> annotations. These annotations establish that this class is a Seam
  +                        component. </para>
  +                    <para> We'll see below that the properties of our <literal>User</literal> class are bound to
  +                        directly to JSF components and are populated by JSF during the update model values phase. We
  +                        don't need any tedious glue code to copy data back and forth between the JSP pages and the
  +                        entity bean domain model. </para>
  +                    <para> However, entity beans shouldn't do transaction management or database access. So we can't use
  +                        this component as a JSF action listener. For that we need a session bean. </para>
           </example>
                   
         </section>
  @@ -323,19 +262,13 @@
         <section>
           <title>The stateless session bean class: <literal>RegisterAction.java</literal></title>
           
  -        <para>
  -            Most Seam application use session beans as JSF action listeners (you can use JavaBeans
  -            instead if you like). 
  -        </para>
  -        <para>
  -            We have exactly one JSF action in our application, and one session bean method attached 
  -            to it. In this case, we'll use a stateless session bean, since all the state associated 
  -            with our action is held by the <literal>User</literal> bean. 
  -        </para>
  +                <para> Most Seam application use session beans as JSF action listeners (you can use JavaBeans instead if
  +                    you like). </para>
  +                <para> We have exactly one JSF action in our application, and one session bean method attached to it. In
  +                    this case, we'll use a stateless session bean, since all the state associated with our action is
  +                    held by the <literal>User</literal> bean. </para>
           
  -        <para>
  -            This is the only really interesting code in the example!
  -        </para>
  +                <para> This is the only really interesting code in the example! </para>
           
           <example>
               <programlistingco>
  @@ -374,7 +307,7 @@
         {
            em.persist(user);
            log.info("Registered new user #{user.username}");
  -         return "/registered.jsp";
  +         return "/registered.jspx";
         }
         else
         {
  @@ -387,54 +320,42 @@
                       
               <calloutlist>
                   <callout arearefs="registration-stateless-annotation">
  -                    <para>
  -                        The EJB standard <literal>@Stateless</literal> annotation marks this class 
  -                        as stateless session bean.
  -                    </para>
  +                                <para> The EJB standard <literal>@Stateless</literal> annotation marks this class as
  +                                    stateless session bean. </para>
                   </callout>
                   <callout arearefs="registration-in-annotation">
  -                    <para>
  -                        The <link linkend="in-annotation"><literal>@In</literal></link> annotation 
  -                        marks an attribute of the bean as injected by Seam. In this case, the
  -                        attribute is injected from a context variable named <literal>user</literal>
  -                        (the instance variable name).
  -                    </para>
  +                                <para> The <link linkend="in-annotation">
  +                                        <literal>@In</literal>
  +                                    </link> annotation marks an attribute of the bean as injected by Seam. In this case,
  +                                    the attribute is injected from a context variable named <literal>user</literal> (the
  +                                    instance variable name). </para>
                   </callout>
                   <callout arearefs="registration-persistencecontext-annotation">
  -                    <para>
  -                        The EJB standard <literal>@PersistenceContext</literal> annotation is used to 
  -                        inject the EJB3 entity manager.
  -                    </para>
  +                                <para> The EJB standard <literal>@PersistenceContext</literal> annotation is used to
  +                                    inject the EJB3 entity manager. </para>
                   </callout>
                   <callout arearefs="registration-logger-annotation">
  -                    <para>
  -                        The Seam <literal>@Logger</literal> annotation is used to inject the component's
  -                        <literal>Log</literal> instance.
  -                    </para>
  +                                <para> The Seam <literal>@Logger</literal> annotation is used to inject the component's
  +                                        <literal>Log</literal> instance. </para>
                   </callout>
                   <callout arearefs="registration-action-listener">
  -                    <para>
  -                        The action listener method uses the standard EJB3 <literal>EntityManager</literal> 
  -                        API to interact with the database, and returns the JSF outcome. Note that, since
  -                        this is a sesson bean, a transaction is automatically begun when the 
  -                        <literal>register()</literal> method is called, and committed when it completes.
  -                    </para>
  +                                <para> The action listener method uses the standard EJB3
  +                                    <literal>EntityManager</literal> API to interact with the database, and returns the
  +                                    JSF outcome. Note that, since this is a sesson bean, a transaction is automatically
  +                                    begun when the <literal>register()</literal> method is called, and committed when it
  +                                    completes. </para>
                   </callout>
                   <callout arearefs="registration-query">
  -                    <para>
  -                        Notice that Seam lets you use a JSF EL expression inside EJB-QL. Under the covers,
  -                        this results in an ordinary JPA <literal>setParameter()</literal> call on the
  -                        standard JPA <literal>Query</literal> object. Nice, huh?
  -                    </para>
  +                                <para> Notice that Seam lets you use a JSF EL expression inside EJB-QL. Under the
  +                                    covers, this results in an ordinary JPA <literal>setParameter()</literal> call on
  +                                    the standard JPA <literal>Query</literal> object. Nice, huh? </para>
                   </callout>
                   <callout arearefs="registration-log">
  -                    <para>
  -                        The <literal>Log</literal> API lets us easily display templated log messages.
  +                                <para> The <literal>Log</literal> API lets us easily display templated log messages.
                       </para>
                   </callout>
                   <callout arearefs="registration-outcome">
  -                    <para>
  -                        JSF action listener methods return a string-valued outcome that determines what
  +                                <para> JSF action listener methods return a string-valued outcome that determines what
                           page will be displayed next. A null outcome (or a void action listener method)
                           redisplays the previous page. In plain JSF, it is normal to always use a JSF
                           <emphasis>navigation rule</emphasis> to determine the JSF view id from the 
  @@ -446,8 +367,7 @@
                       </para>
                   </callout>
                   <callout arearefs="registration-builtin">
  -                    <para>
  -                        Seam provides a number of <emphasis>built-in components</emphasis> to help solve
  +                                <para> Seam provides a number of <emphasis>built-in components</emphasis> to help solve
                           common problems. The <literal>FacesMessages</literal> component makes it easy to
                           display templated error or success messages. Built-in Seam components may be
                           obtained by injection, or by calling an <literal>instance()</literal> method.
  @@ -456,29 +376,22 @@
               </calloutlist>
               </programlistingco>
           
  -        <para>
  -            Note that we did not explicitly specify a <literal>@Scope</literal> this time. Each Seam 
  -            component type has a default scope if not explicitly specified. For stateless session beans,
  -            the default scope is the stateless context. Actually, <emphasis>all</emphasis> stateless
  -            session beans belong in the stateless context.
  -        </para>
  -        
  -        <para>
  -            Our session bean action listener performs the business and persistence logic for our
  -            mini-application. In more complex applications, we might need to layer the code and
  -            refactor persistence logic into a dedicated data access component. That's perfectly
  -            trivial to do. But notice that Seam does not force you into any particular strategy 
  -            for application layering.
  -        </para>
  -        
  -        <para>
  -            Furthermore, notice that our session bean has simultaneous access to context associated
  -            with the web request (the form values in the <literal>User</literal> object, for example), 
  -            and state held in transactional resources (the <literal>EntityManager</literal> object).
  -            This is a break from traditional J2EE architectures. Again, if you are more comfortable
  -            with the traditional J2EE layering, you can certainly implement that in a Seam application.
  -            But for many applications, it's simply not very useful.
  -        </para>
  +                    <para> Note that we did not explicitly specify a <literal>@Scope</literal> this time. Each Seam
  +                        component type has a default scope if not explicitly specified. For stateless session beans, the
  +                        default scope is the stateless context. Actually, <emphasis>all</emphasis> stateless session
  +                        beans belong in the stateless context. </para>
  +
  +                    <para> Our session bean action listener performs the business and persistence logic for our
  +                        mini-application. In more complex applications, we might need to layer the code and refactor
  +                        persistence logic into a dedicated data access component. That's perfectly trivial to do. But
  +                        notice that Seam does not force you into any particular strategy for application layering. </para>
  +
  +                    <para> Furthermore, notice that our session bean has simultaneous access to context associated with
  +                        the web request (the form values in the <literal>User</literal> object, for example), and state
  +                        held in transactional resources (the <literal>EntityManager</literal> object). This is a break
  +                        from traditional J2EE architectures. Again, if you are more comfortable with the traditional
  +                        J2EE layering, you can certainly implement that in a Seam application. But for many
  +                        applications, it's simply not very useful. </para>
   
           </example>        
         
  @@ -497,33 +410,25 @@
   }]]></programlisting>
           </example>
           
  -        <para>
  -            That's the end of the Java code. Now onto the deployment descriptors.
  -        </para>
  +                <para> That's the end of the Java code. Now onto the deployment descriptors. </para>
   
         </section>
         
         <section>
           <title>The Seam component deployment descriptor: <literal>components.xml</literal></title>
           
  -        <para>
  -            If you've used many Java frameworks before, you'll be used to having to declare
  -            all your component classes in some kind of XML file that gradually grows more and
  -            more unmanageable as your project matures. You'll be relieved to know that Seam
  -            does not require that application components be accompanied by XML. Most Seam
  -            applications require a very small amount of XML that does not grow very much as 
  -            the project gets bigger.
  -        </para>
  -        
  -        <para>
  -            Nevertheless, it is often useful to be able to provide for <emphasis>some</emphasis> 
  -            external configuration of <emphasis>some</emphasis> components (particularly the
  -            components built in to Seam). You have a couple of options here, but the most flexible
  -            option is to provide this configuration in a file called <literal>components.xml</literal>, 
  -            located in the <literal>WEB-INF</literal> directory. We'll use the 
  -            <literal>components.xml</literal> file to tell Seam how to find our EJB components
  -            in JNDI:
  -        </para>
  +                <para> If you've used many Java frameworks before, you'll be used to having to declare all your
  +                    component classes in some kind of XML file that gradually grows more and more unmanageable as your
  +                    project matures. You'll be relieved to know that Seam does not require that application components
  +                    be accompanied by XML. Most Seam applications require a very small amount of XML that does not grow
  +                    very much as the project gets bigger. </para>
  +
  +                <para> Nevertheless, it is often useful to be able to provide for <emphasis>some</emphasis> external
  +                    configuration of <emphasis>some</emphasis> components (particularly the components built in to
  +                    Seam). You have a couple of options here, but the most flexible option is to provide this
  +                    configuration in a file called <literal>components.xml</literal>, located in the
  +                    <literal>WEB-INF</literal> directory. We'll use the <literal>components.xml</literal> file to tell
  +                    Seam how to find our EJB components in JNDI: </para>
           
           <example>
             <programlisting><![CDATA[<components xmlns="http://jboss.com/products/seam/components"
  @@ -532,20 +437,16 @@
   </components>]]></programlisting>
           </example>
           
  -        <para>
  -            This code configures a property named <literal>jndiPattern</literal> of a built-in 
  -            Seam component named <literal>org.jboss.seam.core.init</literal>.
  -        </para>
  +                <para> This code configures a property named <literal>jndiPattern</literal> of a built-in Seam component
  +                    named <literal>org.jboss.seam.core.init</literal>. </para>
           
         </section>
         
         <section>
           <title>The web deployment description: <literal>web.xml</literal></title>
           
  -        <para>
  -            The presentation layer for our mini-application will be deployed in a WAR.
  -            So we'll need a web deployment descriptor.
  -        </para>
  +                <para> The presentation layer for our mini-application will be deployed in a WAR. So we'll need a web
  +                    deployment descriptor. </para>
                   
           <example>
             <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
  @@ -561,12 +462,10 @@
           <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
       </listener>
   
  -    <!-- MyFaces -->
  +    <!-- JSF -->
   
       <listener>
  -        <listener-class>
  -            org.apache.myfaces.webapp.StartupServletContextListener
  -        </listener-class>
  +        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
       </listener>
   
       <context-param>
  @@ -574,6 +473,11 @@
           <param-value>client</param-value>
       </context-param>
   
  +    <context-param>
  +        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
  +        <param-value>.jspx</param-value>
  +    </context-param>
  +              
       <servlet>
           <servlet-name>Faces Servlet</servlet-name>
           <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  @@ -586,23 +490,23 @@
           <url-pattern>*.seam</url-pattern>
       </servlet-mapping>
   
  +    <session-config>
  +        <session-timeout>10</session-timeout>
  +    </session-config>
  +
   </web-app>]]></programlisting>
           </example>
           
  -        <para>
  -            This <literal>web.xml</literal> file configures Seam and MyFaces. The configuration you
  -            see here is pretty much identical in all Seam applications. 
  -        </para>
  +                <para> This <literal>web.xml</literal> file configures Seam and JSF. The configuration you see here is
  +                    pretty much identical in all Seam applications. </para>
           
         </section>
         
         <section>
           <title>The JSF configration: <literal>faces-config.xml</literal></title>
           
  -        <para>
  -            All Seam applications use JSF views as the presentation layer. So we'll need
  -            <literal>faces-config.xml</literal>.
  -        </para>
  +                <para> All Seam applications use JSF views as the presentation layer. So we'll need
  +                        <literal>faces-config.xml</literal>. </para>
           
           <example id="registration-faces-config-xml">
             <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
  @@ -620,40 +524,30 @@
   </faces-config>]]></programlisting>
           </example>
           
  -        <para>
  -            The <literal>faces-config.xml</literal> file integrates Seam into JSF. Note that we don't
  -            need any JSF managed bean declarations! The managed beans are the Seam components. In Seam 
  -            applications, the <literal>faces-config.xml</literal> is used much less often than in plain 
  -            JSF.
  -        </para>
  -        
  -        <para>
  -            In fact, once you have all the basic descriptors set up, the <emphasis>only</emphasis>
  -            XML you need to write as you add new functionality to a Seam application is the navigation
  -            rules, and possibly jBPM process definitions. Seam takes the view that 
  -            <emphasis>process flow</emphasis> and <emphasis>configuration data</emphasis> are the only 
  -            things that truly belong in XML.
  -        </para>
  +                <para> The <literal>faces-config.xml</literal> file integrates Seam into JSF. Note that we don't need
  +                    any JSF managed bean declarations! The managed beans are the Seam components. In Seam applications,
  +                    the <literal>faces-config.xml</literal> is used much less often than in plain JSF. </para>
  +
  +                <para> In fact, once you have all the basic descriptors set up, the <emphasis>only</emphasis> XML you
  +                    need to write as you add new functionality to a Seam application is the navigation rules, and
  +                    possibly jBPM process definitions. Seam takes the view that <emphasis>process flow</emphasis> and
  +                        <emphasis>configuration data</emphasis> are the only things that truly belong in XML. </para>
           
  -        <para>
  -            In this simple example, we don't even need a navigation rule, since we decided to embed 
  -            the view id in our action code.
  -        </para>
  +                <para> In this simple example, we don't even need a navigation rule, since we decided to embed the view
  +                    id in our action code. </para>
           
         </section>
         
         <section>
           <title>The EJB deployment descriptor: <literal>ejb-jar.xml</literal></title>
           
  -        <para>
  -            The <literal>ejb-jar.xml</literal> file integrates Seam with EJB3, by
  -            attaching the <literal>SeamInterceptor</literal> to all session beans
  -            in the archive.
  -        </para>
  +                <para> The <literal>ejb-jar.xml</literal> file integrates Seam with EJB3, by attaching the
  +                        <literal>SeamInterceptor</literal> to all session beans in the archive. </para>
   
           <programlisting><![CDATA[<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  -         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
  +         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  +                             http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
            version="3.0">
            
      <interceptors>
  @@ -676,16 +570,15 @@
         <section>
           <title>The EJB persistence deployment descriptor: <literal>persistence.xml</literal></title>
           
  -        <para>
  -            The <literal>persistence.xml</literal> file tells the EJB persistence provider where
  -            to find the datasource, and contains some vendor-specific settings. In this case,
  -            enables automatic schema export at startup time.
  -        </para>
  +                <para> The <literal>persistence.xml</literal> file tells the EJB persistence provider where to find the
  +                    datasource, and contains some vendor-specific settings. In this case, enables automatic schema
  +                    export at startup time. </para>
   
           <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
   <persistence xmlns="http://java.sun.com/xml/ns/persistence" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  -             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
  +             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
  +                                 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
                version="1.0">
       <persistence-unit name="userDatabase">
         <provider>org.hibernate.ejb.HibernatePersistence</provider>
  @@ -701,12 +594,10 @@
         <section>
           <title>The view: <literal>register.jsp</literal> and <literal>registered.jsp</literal></title>
           
  -        <para>
  -            The view pages for a Seam application could be implemented using any technology that
  -            supports JSF. In this example we use JSP, since it is familiar to most developers
  -            and since we have minimal requirements here anyway. (But if you take our advice, you'll 
  -            use Facelets for your own applications.)
  -        </para>
  +                <para> The view pages for a Seam application could be implemented using any technology that supports
  +                    JSF. In this example we use JSP, since it is familiar to most developers and since we have minimal
  +                    requirements here anyway. (But if you take our advice, you'll use Facelets for your own
  +                    applications.) </para>
           
           <example id="registration-simpleform">
             <programlisting><![CDATA[<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
  @@ -743,11 +634,9 @@
   </html>]]></programlisting>
           </example>
           
  -        <para>
  -            The only thing here that is specific to Seam is the <literal>&lt;s:validateAll&gt;</literal>
  -            tag. This JSF component tells JSF to validate all the contained input fields against the 
  -            Hibernate Validator annotations specified on the entity bean.
  -        </para>
  +                <para> The only thing here that is specific to Seam is the
  +                    <literal>&lt;s:validateAll&gt;</literal> tag. This JSF component tells JSF to validate all
  +                    the contained input fields against the Hibernate Validator annotations specified on the entity bean. </para>
           
           <example id="registration-simplepage">
             <programlisting><![CDATA[<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
  @@ -766,26 +655,22 @@
           </example>        
           
           
  -        <para>
  -            This is a boring old JSP pages using standard JSF components. There is
  -            nothing specific to Seam here.
  -        </para>
  +                <para> This is a boring old JSP pages using standard JSF components. There is nothing specific to Seam
  +                    here. </para>
   
         </section>
   
         <section>
           <title>The EAR deployment descriptor: <literal>application.xml</literal></title>
           
  -        <para>
  -            Finally, since our application is deployed as an EAR, we need a deployment descriptor
  -            there, too.
  -        </para>
  +                <para> Finally, since our application is deployed as an EAR, we need a deployment descriptor there, too. </para>
           
           <example id="registration-application-xml">
             <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
   <application xmlns="http://java.sun.com/xml/ns/javaee" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  -             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"
  +             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  +                                 http://java.sun.com/xml/ns/javaee/application_5.xsd"
                version="5">
                
       <display-name>Seam Registration</display-name>
  @@ -803,70 +688,45 @@
           <java>jboss-seam.jar</java>
       </module>
       <module>
  -        <java>el-api.jar</java>
  -    </module>
  -    <module>
  -        <java>el-ri.jar</java>
  +        <java>jboss-el.jar</java>
       </module>
       
   </application>]]></programlisting>
           </example>
           
  -        <para>
  -            This deployment descriptor links modules in the enterprise archive and binds 
  -            the web application to the context root <literal>/seam-registration</literal>.
  -        </para>
  +                <para> This deployment descriptor links modules in the enterprise archive and binds the web application
  +                    to the context root <literal>/seam-registration</literal>. </para>
           
         </section>
                 
  -        <para>
  -            We've now seen <emphasis>all</emphasis> the files in the entire application!
  -        </para>
  +            <para> We've now seen <emphasis>all</emphasis> the files in the entire application! </para>
       
       </section>
       
       <section>
         <title>How it works</title>
   
  -      <para>
  -          When the form is submitted, JSF asks Seam to resolve the variable named
  -          <literal>user</literal>. Since there is no value already bound to that
  -          name (in any Seam context), Seam instantiates the <literal>user</literal>
  -          component, and returns the resulting <literal>User</literal> entity
  -          bean instance to JSF after storing it in the Seam session context. 
  -      </para>
  -      <para>
  -          The form input values are now validated against the Hibernate Validator
  -          constraints specified on the <literal>User</literal> entity. If the
  -          constraints are violated, JSF redisplays the page. Otherwise, JSF binds 
  -          the form input values to properties of the <literal>User</literal> entity 
  -          bean.
  -      </para>
  -      <para>
  -          Next, JSF asks Seam to resolve the variable named <literal>register</literal>.
  -          Seam finds the <literal>RegisterAction</literal> stateless session bean
  -          in the stateless context and returns it. JSF invokes the <literal>register()</literal>
  -          action listener method.
  -      </para>
  -      <para>
  -          Seam intercepts the method call and injects the <literal>User</literal> entity
  -          from the Seam session context, before continuing the invocation.
  -      </para>
  -      <para>
  -          The <literal>register()</literal> method checks if a user with the entered
  -          username already exists. If so, an error message is queued with the 
  -          <literal>FacesMessages</literal> component, and a null outcome is returned,
  -          causing a page redisplay. The <literal>FacesMessages</literal> component
  -          interpolates the JSF expression embedded in the message string and adds
  -          a JSF <literal>FacesMessage</literal> to the view.
  -      </para>
  -      <para>
  -          If no user with that username exists, the <literal>"/registered.jsp"</literal>
  -          outcome triggers a browser redirect to the <literal>registered.jsp</literal> page. 
  -          When JSF comes to render the page, it asks Seam to resolve the variable named 
  -          <literal>user</literal> and uses property values of the returned <literal>User</literal> 
  -          entity from Seam's session scope.
  -      </para>
  +            <para> When the form is submitted, JSF asks Seam to resolve the variable named <literal>user</literal>.
  +                Since there is no value already bound to that name (in any Seam context), Seam instantiates the
  +                    <literal>user</literal> component, and returns the resulting <literal>User</literal> entity bean
  +                instance to JSF after storing it in the Seam session context. </para>
  +            <para> The form input values are now validated against the Hibernate Validator constraints specified on the
  +                    <literal>User</literal> entity. If the constraints are violated, JSF redisplays the page. Otherwise,
  +                JSF binds the form input values to properties of the <literal>User</literal> entity bean. </para>
  +            <para> Next, JSF asks Seam to resolve the variable named <literal>register</literal>. Seam finds the
  +                    <literal>RegisterAction</literal> stateless session bean in the stateless context and returns it.
  +                JSF invokes the <literal>register()</literal> action listener method. </para>
  +            <para> Seam intercepts the method call and injects the <literal>User</literal> entity from the Seam session
  +                context, before continuing the invocation. </para>
  +            <para> The <literal>register()</literal> method checks if a user with the entered username already exists.
  +                If so, an error message is queued with the <literal>FacesMessages</literal> component, and a null
  +                outcome is returned, causing a page redisplay. The <literal>FacesMessages</literal> component
  +                interpolates the JSF expression embedded in the message string and adds a JSF
  +                <literal>FacesMessage</literal> to the view. </para>
  +            <para> If no user with that username exists, the <literal>"/registered.jspx"</literal> outcome triggers a
  +                browser redirect to the <literal>registered.jsp</literal> page. When JSF comes to render the page, it
  +                asks Seam to resolve the variable named <literal>user</literal> and uses property values of the returned
  +                    <literal>User</literal> entity from Seam's session scope. </para>
   
       </section>
   
  @@ -875,13 +735,10 @@
     <section id="messages">
       <title>Clickable lists in Seam: the messages example</title>
       
  -    <para>
  -        Clickable lists of database search results are such an important part of any 
  -        online application that Seam provides special functionality on top of JSF to
  -        make it easier to query data using EJB-QL or HQL and display it as a clickable 
  -        list using a JSF <literal>&lt;h:dataTable&gt;</literal>. The messages example 
  -        demonstrates this functionality.
  -    </para>  
  +        <para> Clickable lists of database search results are such an important part of any online application that Seam
  +            provides special functionality on top of JSF to make it easier to query data using EJB-QL or HQL and display
  +            it as a clickable list using a JSF <literal>&lt;h:dataTable&gt;</literal>. The messages example
  +            demonstrates this functionality. </para>
       
           <mediaobject>
             <imageobject role="fo">
  @@ -894,18 +751,14 @@
           
       <section>
          <title>Understanding the code</title>
  -       <para>
  -           The message list example has one entity bean, <literal>Message</literal>, 
  -           one session bean, <literal>MessageListBean</literal> and one JSP.
  -       </para>
  +            <para> The message list example has one entity bean, <literal>Message</literal>, one session bean,
  +                    <literal>MessageListBean</literal> and one JSP. </para>
          
          <section>
          <title>The entity bean: <literal>Message.java</literal></title>
          
  -       <para>
  -           The <literal>Message</literal> entity defines the title, text, date and time
  -           of a message, and a flag indicating whether the message has been read:
  -       </para>
  +                <para> The <literal>Message</literal> entity defines the title, text, date and time of a message, and a
  +                    flag indicating whether the message has been read: </para>
          
          <example>
             <programlisting><![CDATA[@Entity
  @@ -968,30 +821,19 @@
          <section>
          <title>The stateful session bean: <literal>MessageManagerBean.java</literal></title>
          
  -       <para>
  -           Just like in the previous example, we have a session bean,
  -           <literal>MessageManagerBean</literal>, which defines the action
  -           listener methods for the two buttons on our form. One of the 
  -           buttons selects a message from the list, and displays that
  -           message. The other button deletes a message. So far, this
  -           is not so different to the previous example.
  -       </para>
  -       
  -       <para>
  -           But <literal>MessageManagerBean</literal> is also responsible 
  -           for fetching the list of messages the first time we navigate
  -           to the message list page. There are various ways the user
  -           could navigate to the page, and not all of them are preceded
  -           by a JSF action&mdash;the user might have bookmarked the page,
  -           for example. So the job of fetching the message list takes
  -           place in a Seam <emphasis>factory method</emphasis>, instead
  -           of in an action listener method.
  -       </para>
  +                <para> Just like in the previous example, we have a session bean, <literal>MessageManagerBean</literal>,
  +                    which defines the action listener methods for the two buttons on our form. One of the buttons
  +                    selects a message from the list, and displays that message. The other button deletes a message. So
  +                    far, this is not so different to the previous example. </para>
  +
  +                <para> But <literal>MessageManagerBean</literal> is also responsible for fetching the list of messages
  +                    the first time we navigate to the message list page. There are various ways the user could navigate
  +                    to the page, and not all of them are preceded by a JSF action&mdash;the user might have
  +                    bookmarked the page, for example. So the job of fetching the message list takes place in a Seam
  +                        <emphasis>factory method</emphasis>, instead of in an action listener method. </para>
          
  -       <para>
  -           We want to cache the list of messages in memory between server
  -           requests, so we will make this a stateful session bean.
  -       </para>
  +                <para> We want to cache the list of messages in memory between server requests, so we will make this a
  +                    stateful session bean. </para>
          
          <example>
               <programlistingco>
  @@ -1001,9 +843,9 @@
                       <area id="messages-out" coords="11"/>
                       <area id="messages-persistencecontext" coords="14"/>
                       <area id="messages-factory" coords="17"/>
  -                    <area id="messages-select" coords="23"/>
  -                    <area id="messages-delete" coords="28"/>
  -                    <area id="messages-remove" coords="35"/>
  +                            <area id="messages-select" coords="24"/>
  +                            <area id="messages-delete" coords="29"/>
  +                            <area id="messages-remove" coords="36"/>
                   </areaspec>    
             <programlisting><![CDATA[@Stateful
   @Scope(SESSION)
  @@ -1024,7 +866,8 @@
      @Factory("messageList")
      public void findMessages()
      {
  -      messageList = em.createQuery("from Message msg order by msg.datetime desc").getResultList();
  +      messageList = em.createQuery("from Message msg order by msg.datetime desc")
  +                      .getResultList();
      }
      
      public void select()
  @@ -1045,91 +888,66 @@
   }]]></programlisting>
               <calloutlist>
                   <callout arearefs="messages-datamodel">
  -                    <para>
  -                        The <literal>@DataModel</literal> annotation exposes an attibute of 
  -                        type <literal>java.util.List</literal> to the JSF page as an instance 
  -                        of <literal>javax.faces.model.DataModel</literal>. This allows us to
  -                        use the list in a JSF <literal>&lt;h:dataTable&gt;</literal> with
  -                        clickable links for each row. In this case, the <literal>DataModel</literal>
  -                        is made available in a session context variable named 
  -                        <literal>messageList</literal>.
  -                    </para>
  +                                <para> The <literal>@DataModel</literal> annotation exposes an attibute of type
  +                                        <literal>java.util.List</literal> to the JSF page as an instance of
  +                                        <literal>javax.faces.model.DataModel</literal>. This allows us to use the list
  +                                    in a JSF <literal>&lt;h:dataTable&gt;</literal> with clickable links for
  +                                    each row. In this case, the <literal>DataModel</literal> is made available in a
  +                                    session context variable named <literal>messageList</literal>. </para>
                   </callout>
                   <callout arearefs="messages-datamodelselection">
  -                    <para>
  -                        The <literal>@DataModelSelection</literal> annotation tells Seam to
  -                        inject the <literal>List</literal> element that corresponded to the
  -                        clicked link.
  -                    </para>
  +                                <para> The <literal>@DataModelSelection</literal> annotation tells Seam to inject the
  +                                        <literal>List</literal> element that corresponded to the clicked link. </para>
                   </callout>
                   <callout arearefs="messages-out">
  -                    <para>
  -                        The <literal>@Out</literal> annotation then exposes the selected value
  -                        directly to the page. So ever time a row of the clickable list is
  -                        selected, the <literal>Message</literal> is injected to the attribute
  -                        of the stateful bean, and the subsequently <emphasis>outjected</emphasis>
  -                        to the event context variable named <literal>message</literal>.
  -                    </para>
  +                                <para> The <literal>@Out</literal> annotation then exposes the selected value directly
  +                                    to the page. So ever time a row of the clickable list is selected, the
  +                                        <literal>Message</literal> is injected to the attribute of the stateful bean,
  +                                    and the subsequently <emphasis>outjected</emphasis> to the event context variable
  +                                    named <literal>message</literal>. </para>
                   </callout>
                   <callout arearefs="messages-persistencecontext">
  -                    <para>
  -                        This stateful bean has an EJB3 <emphasis>extended persistence context</emphasis>.
  -                        The messages retrieved in the query remain in the managed state as long
  -                        as the bean exists, so any subsequent method calls to the stateful bean 
  -                        can update them without needing to make any explicit call to the
  -                        <literal>EntityManager</literal>.
  -                    </para>
  +                                <para> This stateful bean has an EJB3 <emphasis>extended persistence context</emphasis>.
  +                                    The messages retrieved in the query remain in the managed state as long as the bean
  +                                    exists, so any subsequent method calls to the stateful bean can update them without
  +                                    needing to make any explicit call to the <literal>EntityManager</literal>. </para>
                   </callout>
                   <callout arearefs="messages-factory">
  -                    <para>
  -                        The first time we navigate to the JSP page, there will be no value in
  -                        the <literal>messageList</literal> context variable. The <literal>@Factory</literal>
  +                                <para> The first time we navigate to the JSP page, there will be no value in the
  +                                        <literal>messageList</literal> context variable. The <literal>@Factory</literal>
                           annotation tells Seam to create an instance of <literal>MessageManagerBean</literal> 
  -                        and invoke the <literal>findMessages()</literal> method to initialize the 
  -                        value. We call <literal>findMessages()</literal> a <emphasis>factory 
  -                        method</emphasis> for <literal>messages</literal>.
  -                    </para>
  +                                    and invoke the <literal>findMessages()</literal> method to initialize the value. We
  +                                    call <literal>findMessages()</literal> a <emphasis>factory method</emphasis> for
  +                                        <literal>messages</literal>. </para>
                   </callout>
                   <callout arearefs="messages-select">
  -                    <para>
  -                        The <literal>select()</literal> action listener method marks the 
  -                        selected <literal>Message</literal> as read, and updates it in the
  -                        database.
  -                    </para>
  +                                <para> The <literal>select()</literal> action listener method marks the selected
  +                                        <literal>Message</literal> as read, and updates it in the database. </para>
                   </callout>
                   <callout arearefs="messages-delete">
  -                    <para>
  -                        The <literal>delete()</literal> action listener method removes the 
  -                        selected <literal>Message</literal> from the database.
  -                    </para>
  +                                <para> The <literal>delete()</literal> action listener method removes the selected
  +                                        <literal>Message</literal> from the database. </para>
                   </callout>
                   <callout arearefs="messages-remove">
  -                    <para>
  -                        All stateful session bean Seam components <emphasis>must</emphasis>
  -                        have a method marked <literal>@Remove @Destroy</literal> to ensure that
  -                        Seam will remove the stateful bean when the Seam context ends, and
  -                        clean up any server-side state.
  +                                <para> All stateful session bean Seam components <emphasis>must</emphasis> have a method
  +                                    marked <literal>@Remove @Destroy</literal> to ensure that Seam will remove the
  +                                    stateful bean when the Seam context ends, and clean up any server-side state.
                       </para>
                   </callout>
               </calloutlist>
             </programlistingco>
          </example>
          
  -       <para>
  -           Note that this is a session-scoped Seam component. It is associated 
  -           with the user login session, and all requests from a login session 
  -           share the same instance of the component. (In Seam applications, 
  -           we usually use session-scoped components sparingly.)
  -       </para>
  +                <para> Note that this is a session-scoped Seam component. It is associated with the user login session,
  +                    and all requests from a login session share the same instance of the component. (In Seam
  +                    applications, we usually use session-scoped components sparingly.) </para>
          
          </section>
          
          <section>
          <title>The session bean local interface: <literal>MessageManager.java</literal></title>
          
  -       <para>
  -           All session beans have a business interface, of course.
  -       </para>
  +                <para> All session beans have a business interface, of course. </para>
          
          <programlisting><![CDATA[@Local
   public interface MessageManager
  @@ -1140,26 +958,20 @@
      public void destroy();
   }]]></programlisting>
          
  -       <para>
  -           From now on, we won't show local interfaces in our code examples. 
  -       </para>
  +                <para> From now on, we won't show local interfaces in our code examples. </para>
          
  -       <para>
  -           Let's skip over <literal>components.xml</literal>, <literal>persistence.xml</literal>, 
  +                <para> Let's skip over <literal>components.xml</literal>, <literal>persistence.xml</literal>,
              <literal>web.xml</literal>, <literal>ejb-jar.xml</literal>, <literal>faces-config.xml</literal> 
  -           and <literal>application.xml</literal> since they are much the same as the previous 
  -           example, and go straight to the JSP.
  -       </para>
  +                    and <literal>application.xml</literal> since they are much the same as the previous example, and go
  +                    straight to the JSP. </para>
          
          </section>
          
          <section>
          <title>The view: <literal>messages.jsp</literal></title>
          
  -       <para>
  -           The JSP page is a straightforward use of the JSF <literal>&lt;h:dataTable&gt;</literal>
  -           component. Again, nothing specific to Seam.
  -       </para>
  +                <para> The JSP page is a straightforward use of the JSF <literal>&lt;h:dataTable&gt;</literal>
  +                    component. Again, nothing specific to Seam. </para>
          
          <example>
              <programlisting><![CDATA[<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
  @@ -1172,8 +984,10 @@
     <f:view>
      <h:form>
        <h2>Message List</h2>
  -     <h:outputText value="No messages to display" rendered="#{messageList.rowCount==0}"/>
  -     <h:dataTable var="msg" value="#{messageList}" rendered="#{messageList.rowCount>0}">
  +     <h:outputText value="No messages to display" 
  +                   rendered="#{messageList.rowCount==0}"/>
  +     <h:dataTable var="msg" value="#{messageList}" 
  +                  rendered="#{messageList.rowCount>0}">
           <h:column>
              <f:facet name="header">
                 <h:outputText value="Read"/>
  @@ -1213,42 +1027,32 @@
        <section>
            <title>How it works</title>
            
  -         <para>
  -             The first time we navigate to the <literal>messages.jsp</literal> page, whether
  -             by a JSF postback (faces request) or a direct browser GET request (non-faces
  -             request), the page will try to resolve the <literal>messageList</literal> context
  -             variable. Since this context variable is not initialized, Seam will call the
  -             factory method <literal>findMessages()</literal>, which performs a query against
  -             the database and results in a <literal>DataModel</literal> being outjected.
  -             This <literal>DataModel</literal> provides the row data needed for rendering
  -             the <literal>&lt;h:dataTable&gt;</literal>.
  -         </para>
  -         
  -         <para>
  -             When the user clicks the <literal>&lt;h:commandLink&gt;</literal>, JSF calls the 
  -             <literal>select()</literal> action listener. Seam intercepts this call and injects
  -             the selected row data into the <literal>message</literal> attribute of the
  -             <literal>messageManager</literal> component. The action listener fires, marking
  -             the selected <literal>Message</literal> as read. At the end of the call, Seam
  -             outjects the selected <literal>Message</literal> to the context variable named 
  -             <literal>message</literal>. Next, the EJB container commits the transaction, and 
  -             the change to the <literal>Message</literal> is flushed to the database. Finally,
  -             the page is re-rendered, redisplaying the message list, and displaying the selected
  -             message below it.
  -         </para>
  -         
  -         <para>
  -             If the user clicks the <literal>&lt;h:commandButton&gt;</literal>, JSF calls the 
  -             <literal>delete()</literal> action listener. Seam intercepts this call and injects
  -             the selected row data into the <literal>message</literal> attribute of the
  -             <literal>messageList</literal> component. The action listener fires, removing
  -             the selected <literal>Message</literal> from the list, and also calling
  -             <literal>remove()</literal> on the <literal>EntityManager</literal>. At the end 
  -             of the call, Seam refreshes the <literal>messageList</literal> context variable and
  -             clears the context variable named <literal>message</literal>. The EJB container 
  -             commits the transaction, and deletes the <literal>Message</literal> from the 
  -             database. Finally, the page is re-rendered, redisplaying the message list.
  -         </para>
  +            <para> The first time we navigate to the <literal>messages.jsp</literal> page, whether by a JSF postback
  +                (faces request) or a direct browser GET request (non-faces request), the page will try to resolve the
  +                    <literal>messageList</literal> context variable. Since this context variable is not initialized,
  +                Seam will call the factory method <literal>findMessages()</literal>, which performs a query against the
  +                database and results in a <literal>DataModel</literal> being outjected. This
  +                <literal>DataModel</literal> provides the row data needed for rendering the
  +                    <literal>&lt;h:dataTable&gt;</literal>. </para>
  +
  +            <para> When the user clicks the <literal>&lt;h:commandLink&gt;</literal>, JSF calls the
  +                    <literal>select()</literal> action listener. Seam intercepts this call and injects the selected row
  +                data into the <literal>message</literal> attribute of the <literal>messageManager</literal> component.
  +                The action listener fires, marking the selected <literal>Message</literal> as read. At the end of the
  +                call, Seam outjects the selected <literal>Message</literal> to the context variable named
  +                    <literal>message</literal>. Next, the EJB container commits the transaction, and the change to the
  +                    <literal>Message</literal> is flushed to the database. Finally, the page is re-rendered,
  +                redisplaying the message list, and displaying the selected message below it. </para>
  +
  +            <para> If the user clicks the <literal>&lt;h:commandButton&gt;</literal>, JSF calls the
  +                    <literal>delete()</literal> action listener. Seam intercepts this call and injects the selected row
  +                data into the <literal>message</literal> attribute of the <literal>messageList</literal> component. The
  +                action listener fires, removing the selected <literal>Message</literal> from the list, and also calling
  +                    <literal>remove()</literal> on the <literal>EntityManager</literal>. At the end of the call, Seam
  +                refreshes the <literal>messageList</literal> context variable and clears the context variable named
  +                    <literal>message</literal>. The EJB container commits the transaction, and deletes the
  +                    <literal>Message</literal> from the database. Finally, the page is re-rendered, redisplaying the
  +                message list. </para>
            
        </section>
        
  @@ -1257,12 +1061,9 @@
     <section id="todo">
       <title>Seam and jBPM: the todo list example</title>
       
  -    <para>
  -        jBPM provides sophisticated functionality for workflow and task management.
  -        To get a small taste of how jBPM integrates with Seam, we'll show you a
  -        simple "todo list" application. Since managing lists of tasks is such core 
  -        functionality for jBPM, there is hardly any Java code at all in this example.
  -    </para>
  +        <para> jBPM provides sophisticated functionality for workflow and task management. To get a small taste of how
  +            jBPM integrates with Seam, we'll show you a simple "todo list" application. Since managing lists of tasks is
  +            such core functionality for jBPM, there is hardly any Java code at all in this example. </para>
       
           <mediaobject>
             <imageobject role="fo">
  @@ -1275,12 +1076,9 @@
           
       <section>
           <title>Understanding the code</title>
  -        <para>
  -            The center of this example is the jBPM process definition. There are also
  -            two JSPs and two trivial JavaBeans (There was no reason to use session beans,
  -            since they do not access the database, or have any other transactional 
  -            behavior). Let's start with the process definition:
  -        </para>
  +            <para> The center of this example is the jBPM process definition. There are also two JSPs and two trivial
  +                JavaBeans (There was no reason to use session beans, since they do not access the database, or have any
  +                other transactional behavior). Let's start with the process definition: </para>
           
           <example>
               <programlistingco>
  @@ -1309,53 +1107,38 @@
   </process-definition>]]></programlisting>
               <calloutlist>
                   <callout arearefs="todo-startstate">
  -                    <para>
  -                        The <literal>&lt;start-state&gt;</literal> node represents the
  -                        logical start of the process. When the process starts, it
  -                        immediately transitions to the <literal>todo</literal> node.
  -                    </para>
  +                            <para> The <literal>&lt;start-state&gt;</literal> node represents the logical start
  +                                of the process. When the process starts, it immediately transitions to the
  +                                <literal>todo</literal> node. </para>
                   </callout>
                   <callout arearefs="todo-tasknode">
  -                    <para>
  -                        The <literal>&lt;task-node&gt;</literal> node represents a
  -                        <emphasis>wait state</emphasis>, where business process execution
  -                        pauses, waiting for one or more tasks to be performed.
  -                    </para>
  +                            <para> The <literal>&lt;task-node&gt;</literal> node represents a <emphasis>wait
  +                                    state</emphasis>, where business process execution pauses, waiting for one or more
  +                                tasks to be performed. </para>
                   </callout>
                   <callout arearefs="todo-task">
  -                    <para>
  -                        The <literal>&lt;task&gt;</literal> element defines a task
  -                        to be performed by a user. Since there is only one task
  -                        defined on this node, when it is complete, execution
  -                        resumes, and we transition to the end state. The task gets 
  -                        its description from a Seam component named 
  -                        <literal>todoList</literal> (one of the JavaBeans).
  -                    </para>
  +                            <para> The <literal>&lt;task&gt;</literal> element defines a task to be performed by
  +                                a user. Since there is only one task defined on this node, when it is complete,
  +                                execution resumes, and we transition to the end state. The task gets its description
  +                                from a Seam component named <literal>todoList</literal> (one of the JavaBeans). </para>
                   </callout>
                   <callout arearefs="todo-assignment">
  -                    <para>
  -                        Tasks need to be assigned to a user or group of users when 
  -                        they are created. In this case, the task is assigned to the 
  -                        current user, which we get from a built-in Seam component 
  -                        named <literal>actor</literal>. Any Seam component may be
  -                        used to perform task assignment.
  -                    </para>
  +                            <para> Tasks need to be assigned to a user or group of users when they are created. In this
  +                                case, the task is assigned to the current user, which we get from a built-in Seam
  +                                component named <literal>actor</literal>. Any Seam component may be used to perform task
  +                                assignment. </para>
                   </callout>
                   <callout arearefs="todo-endstate">
  -                    <para>
  -                        The <literal>&lt;end-state&gt;</literal> node defines the logical
  -                        end of the business process. When execution reaches this node,
  -                        the process instance is destroyed.
  +                            <para> The <literal>&lt;end-state&gt;</literal> node defines the logical end of the
  +                                business process. When execution reaches this node, the process instance is destroyed.
                       </para>
                   </callout>
              </calloutlist>
              </programlistingco>
           </example>
           
  -        <para>
  -            If we view this process definition using the process definition editor provided 
  -            by JBossIDE, this is what it looks like: 
  -        </para>
  +            <para> If we view this process definition using the process definition editor provided by JBossIDE, this is
  +                what it looks like: </para>
           
           <mediaobject>
             <imageobject role="fo">
  @@ -1366,19 +1149,13 @@
             </imageobject>
           </mediaobject>
           
  -        <para>
  -            This document defines our <emphasis>business process</emphasis> as a graph
  -            of nodes. This is the most trivial possible business process: there is one
  -            <emphasis>task</emphasis> to be performed, and when that task is complete,
  -            the business process ends.  
  -        </para>
  -        
  -        <para>
  -            The first JavaBean handles the login screen <literal>login.jsp</literal>. 
  -            Its job is just to initialize the jBPM actor id using the 
  -            <literal>actor</literal> component. (In a real application, it would also 
  -            need to authenticate the user.)
  -        </para>
  +            <para> This document defines our <emphasis>business process</emphasis> as a graph of nodes. This is the most
  +                trivial possible business process: there is one <emphasis>task</emphasis> to be performed, and when that
  +                task is complete, the business process ends. </para>
  +
  +            <para> The first JavaBean handles the login screen <literal>login.jsp</literal>. Its job is just to
  +                initialize the jBPM actor id using the <literal>actor</literal> component. (In a real application, it
  +                would also need to authenticate the user.) </para>
           
           <example>
           <programlisting><![CDATA[@Name("login")
  @@ -1405,14 +1182,10 @@
   }]]></programlisting>
           </example>
   
  -        <para>
  -            Here we see the use of <literal>@In</literal> to inject the built-in
  -            <literal>Actor</literal> component.
  -        </para>
  +            <para> Here we see the use of <literal>@In</literal> to inject the built-in <literal>Actor</literal>
  +                component. </para>
           
  -        <para>
  -            The JSP itself is trivial:
  -        </para>
  +            <para> The JSP itself is trivial: </para>
           
           <example>
           <programlisting><![CDATA[<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
  @@ -1436,10 +1209,7 @@
           
           </example>
           
  -        <para>
  -            The second JavaBean is responsible for starting business process instances,
  -            and ending tasks.
  -        </para>
  +            <para> The second JavaBean is responsible for starting business process instances, and ending tasks. </para>
           
           <example>
               <programlistingco>
  @@ -1471,38 +1241,27 @@
   }]]></programlisting>
               <calloutlist>
                   <callout arearefs="todo-description">
  -                    <para>
  -                        The description property accepts user input form the JSP page, and 
  -                        exposes it to the process definition, allowing the task description
  -                        to be set.
  -                    </para>
  +                            <para> The description property accepts user input form the JSP page, and exposes it to the
  +                                process definition, allowing the task description to be set. </para>
                   </callout>
                   <callout arearefs="todo-createprocess-annotation">
  -                    <para>
  -                        The Seam <literal>@CreateProcess</literal> annotation creates a new
  -                        jBPM process instance for the named process definition.
  -                    </para>
  +                            <para> The Seam <literal>@CreateProcess</literal> annotation creates a new jBPM process
  +                                instance for the named process definition. </para>
                   </callout>
                   <callout arearefs="todo-task-annotations">
  -                    <para>
  -                        The Seam <literal>@StartTask</literal> annotation starts work on
  -                        a task. The <literal>@EndTask</literal> ends the task, and allows
  -                        the business process execution to resume.
  -                    </para>
  +                            <para> The Seam <literal>@StartTask</literal> annotation starts work on a task. The
  +                                    <literal>@EndTask</literal> ends the task, and allows the business process execution
  +                                to resume. </para>
                   </callout>
              </calloutlist>
            </programlistingco>
          </example>        
          
  -       <para>
  -           In a more realistic example, <literal>@StartTask</literal> and <literal>@EndTask</literal>
  -           would not appear on the same method, because there is usually work to be done using the 
  -           application in order to complete the task.
  -       </para>
  +            <para> In a more realistic example, <literal>@StartTask</literal> and <literal>@EndTask</literal> would not
  +                appear on the same method, because there is usually work to be done using the application in order to
  +                complete the task. </para>
          
  -       <para>
  -           Finally, the meat of the application is in <literal>todo.jsp</literal>:
  -       </para>
  +            <para> Finally, the meat of the application is in <literal>todo.jsp</literal>: </para>
          
          <example>
          <programlisting><![CDATA[<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
  @@ -1517,8 +1276,10 @@
   <f:view>
      <h:form id="list">
         <div>
  -         <h:outputText value="There are no todo items." rendered="#{empty taskInstanceList}"/>
  -         <h:dataTable value="#{taskInstanceList}" var="task" rendered="#{not empty taskInstanceList}">
  +         <h:outputText value="There are no todo items." 
  +                       rendered="#{empty taskInstanceList}"/>
  +         <h:dataTable value="#{taskInstanceList}" var="task" 
  +                      rendered="#{not empty taskInstanceList}">
               <h:column>
                   <f:facet name="header">
                       <h:outputText value="Description"/>
  @@ -1570,32 +1331,26 @@
   </html>]]></programlisting>
          </example>
          
  -       <para>
  -           Let's take this one piece at a time.
  -       </para>
  +            <para> Let's take this one piece at a time. </para>
          
  -       <para>
  -           The page renders a list of tasks, which it gets from a built-in Seam component named
  -           <literal>taskInstanceList</literal>. The list is defined inside a JSF form.
  -       </para>
  +            <para> The page renders a list of tasks, which it gets from a built-in Seam component named
  +                    <literal>taskInstanceList</literal>. The list is defined inside a JSF form. </para>
          
          <programlisting><![CDATA[<h:form id="list">
      <div>
         <h:outputText value="There are no todo items." rendered="#{empty taskInstanceList}"/>
  -      <h:dataTable value="#{taskInstanceList}" var="task" rendered="#{not empty taskInstanceList}">
  +      <h:dataTable value="#{taskInstanceList}" var="task" 
  +                   rendered="#{not empty taskInstanceList}">
            ...
         </h:dataTable>
      </div>
   </h:form>]]></programlisting>
   
  -        <para>
  -            Each element of the list is an instance of the jBPM class <literal>TaskInstance</literal>.
  -            The following code simply displays the interesting properties of each task in the list. For the
  -            description, priority and due date, we use input controls, to allow the user to update
  -            these values.
  -        </para>
  +            <para> Each element of the list is an instance of the jBPM class <literal>TaskInstance</literal>. The
  +                following code simply displays the interesting properties of each task in the list. For the description,
  +                priority and due date, we use input controls, to allow the user to update these values. </para>
           
  -<programlisting><![CDATA[<h:column>
  +            <programlisting><![CDATA[<h:column>
       <f:facet name="header">
          <h:outputText value="Description"/>
       </f:facet>
  @@ -1625,33 +1380,23 @@
   </h:column>]]></programlisting>
   
   
  -        <para>
  -            This button ends the task by calling the action method annotated 
  -            <literal>@StartTask @EndTask</literal>. It passes the task id to
  -            Seam as a request parameter:
  -        </para>
  +            <para> This button ends the task by calling the action method annotated <literal>@StartTask
  +                @EndTask</literal>. It passes the task id to Seam as a request parameter: </para>
   
           <programlisting><![CDATA[<h:column>
       <s:button value="Done" action="#{todoList.done}" taskInstance="#{task}"/>
   </h:column>]]></programlisting>
   
  -        <para>
  -            (Note that this is using a Seam <literal>&lt;s:button&gt;</literal> JSF control
  -            from the <literal>seam-ui.jar</literal> package.)
  -        </para>
  +            <para> (Note that this is using a Seam <literal>&lt;s:button&gt;</literal> JSF control from the
  +                    <literal>seam-ui.jar</literal> package.) </para>
           
  -        <para>
  -            This button is used to update the properties of the tasks. When the form is
  -            submitted, Seam and jBPM will make any changes to the tasks persistent.
  -            There is no need for any action listener method:
  -        </para>
  +            <para> This button is used to update the properties of the tasks. When the form is submitted, Seam and jBPM
  +                will make any changes to the tasks persistent. There is no need for any action listener method: </para>
           
           <programlisting><![CDATA[<h:commandButton value="Update Items" action="update"/>]]></programlisting>
           
  -        <para>
  -            A second form on the page is used to create new items, by calling the
  -            action method annotated <literal>@CreateProcess</literal>.
  -        </para>
  +            <para> A second form on the page is used to create new items, by calling the action method annotated
  +                    <literal>@CreateProcess</literal>. </para>
          
           <programlisting><![CDATA[<h:form id="new">
       <div>
  @@ -1660,10 +1405,8 @@
       </div>
   </h:form>]]></programlisting>
           
  -        <para>
  -            There are several other files needed for the example, but they are just
  -            standard jBPM and Seam configuration and not very interesting.
  -        </para>
  +            <para> There are several other files needed for the example, but they are just standard jBPM and Seam
  +                configuration and not very interesting. </para>
       </section>
       
       <section>
  @@ -1676,20 +1419,14 @@
     <section id="numberguess">
         <title>Seam pageflow: the numberguess example</title>
         
  -      <para>
  -          For Seam applications with relatively freeform (ad hoc) navigation, JSF/Seam
  -          navigation rules are a perfectly good way to define the page flow.
  -          For applications with a more constrained style of navigation, especially
  -          for user interfaces which are more stateful, navigation rules make it
  -          difficult to really understand the flow of the system. To understand
  -          the flow, you need to piece it together from the view pages, the actions
  -          and the navigation rules.
  -      </para>
  +        <para> For Seam applications with relatively freeform (ad hoc) navigation, JSF/Seam navigation rules are a
  +            perfectly good way to define the page flow. For applications with a more constrained style of navigation,
  +            especially for user interfaces which are more stateful, navigation rules make it difficult to really
  +            understand the flow of the system. To understand the flow, you need to piece it together from the view
  +            pages, the actions and the navigation rules. </para>
         
  -      <para>
  -          Seam allows you to use a jPDL process definition to define pageflow. The
  -          simple number guessing example shows how this is done.
  -      </para>
  +        <para> Seam allows you to use a jPDL process definition to define pageflow. The simple number guessing example
  +            shows how this is done. </para>
         
           <mediaobject>
             <imageobject role="fo">
  @@ -1702,26 +1439,30 @@
           
         <section>
             <title>Understanding the code</title>
  -          <para>
  -              The example is implemented using one JavaBean, three JSP pages and
  -              a jPDL pageflow definition. Let's begin with the pageflow:
  -          </para>
  +            <para> The example is implemented using one JavaBean, three JSP pages and a jPDL pageflow definition. Let's
  +                begin with the pageflow: </para>
             
             <example>
               <programlistingco>
                   <areaspec>
  -                    <area id="numberguess-page" coords="7"/>
  -                    <area id="numberguess-transition" coords="8"/>
  -                    <area id="numberguess-action" coords="9"/>
  -                    <area id="numberguess-decision" coords="13"/>
  +                        <area id="numberguess-page" coords="8"/>
  +                        <area id="numberguess-transition" coords="10"/>
  +                        <area id="numberguess-action" coords="11"/>
  +                        <area id="numberguess-decision" coords="16"/>
                   </areaspec>    
  -              <programlisting><![CDATA[<pageflow-definition name="numberGuess">
  +                    <programlisting><![CDATA[<pageflow-definition 
  +        xmlns="http://jboss.com/products/seam/pageflow"
  +        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  +        xsi:schemaLocation="http://jboss.com/products/seam/pageflow 
  +                            http://jboss.com/products/seam/pageflow-1.3.xsd"
  +        name="numberGuess">
      
  -   <start-page name="displayGuess" view-id="/numberGuess.jsp">
  +   <start-page name="displayGuess" view-id="/numberGuess.jspx">
         <redirect/>
         <transition name="guess" to="evaluateGuess">
  -          <action expression="#{numberGuess.guess}" />
  +         <action expression="#{numberGuess.guess}"/>
         </transition>
  +      <transition name="giveup" to="giveup"/>
      </start-page>
      
      <decision name="evaluateGuess" expression="#{numberGuess.correctGuess}">
  @@ -1734,63 +1475,51 @@
         <transition name="false" to="displayGuess"/>
      </decision>
      
  -   <page name="win" view-id="/win.jsp">
  +   <page name="giveup" view-id="/giveup.jspx">
         <redirect/>
  -      <end-conversation />
  +      <transition name="yes" to="lose"/>
  +      <transition name="no" to="displayGuess"/>
      </page>
      
  -   <page name="lose" view-id="/lose.jsp">
  +   <page name="win" view-id="/win.jspx">
         <redirect/>
  -      <end-conversation />
  +      <end-conversation/>
  +   </page>
  +   
  +   <page name="lose" view-id="/lose.jspx">
  +      <redirect/>
  +      <end-conversation/>
      </page>
      
   </pageflow-definition>]]></programlisting>
               <calloutlist>
                   <callout arearefs="numberguess-page">
  -                    <para>
  -                        The <literal>&lt;page&gt;</literal> element defines
  -                        a wait state where the system displays a particular
  -                        JSF view and waits for user input. The 
  -                        <literal>view-id</literal> is the same JSF view id 
  -                        used in plain JSF navigation rules. The 
  -                        <literal>redirect</literal> attribute tells Seam to
  -                        use post-then-redirect when navigating to the page.
  -                        (This results in friendly browser URLs.)
  -                    </para>
  +                            <para> The <literal>&lt;page&gt;</literal> element defines a wait state where the
  +                                system displays a particular JSF view and waits for user input. The
  +                                <literal>view-id</literal> is the same JSF view id used in plain JSF navigation rules.
  +                                The <literal>redirect</literal> attribute tells Seam to use post-then-redirect when
  +                                navigating to the page. (This results in friendly browser URLs.) </para>
                   </callout>
                   <callout arearefs="numberguess-transition">
  -                    <para>
  -                        The <literal>&lt;transition&gt;</literal> element
  -                        names a JSF outcome. The transition is triggered
  -                        when a JSF action results in that outcome. Execution
  -                        will then proceed to the next node of the pageflow
  -                        graph, after invocation of any jBPM transition 
  -                        actions.
  -                    </para>
  +                            <para> The <literal>&lt;transition&gt;</literal> element names a JSF outcome. The
  +                                transition is triggered when a JSF action results in that outcome. Execution will then
  +                                proceed to the next node of the pageflow graph, after invocation of any jBPM transition
  +                                actions. </para>
                   </callout>
                   <callout arearefs="numberguess-action">
  -                    <para>
  -                        A transition <literal>&lt;action&gt;</literal> is just
  -                        like a JSF action, except that it occurs when a jBPM
  -                        transition occurs. The transition action can invoke 
  -                        any Seam component.
  -                    </para>
  +                            <para> A transition <literal>&lt;action&gt;</literal> is just like a JSF action,
  +                                except that it occurs when a jBPM transition occurs. The transition action can invoke
  +                                any Seam component. </para>
                   </callout>
                   <callout arearefs="numberguess-decision">
  -                    <para>
  -                        A <literal>&lt;decision&gt;</literal> node branches 
  -                        the pageflow, and determines the next node to execute
  -                        by evaluating a JSF EL expression.
  -                    </para>
  +                            <para> A <literal>&lt;decision&gt;</literal> node branches the pageflow, and
  +                                determines the next node to execute by evaluating a JSF EL expression. </para>
                   </callout>
               </calloutlist>
               </programlistingco>
             </example>
             
  -          <para>
  -              Here is what the pageflow looks like in the JBossIDE pageflow
  -              editor:
  -          </para>
  +            <para> Here is what the pageflow looks like in the JBossIDE pageflow editor: </para>
             
           <mediaobject>
             <imageobject role="fo">
  @@ -1801,90 +1530,129 @@
             </imageobject>
           </mediaobject>
           
  -          <para>
  -              Now that we have seen the pageflow, it is very, very easy to 
  -              understand the rest of the application!
  -          </para>
  +            <para> Now that we have seen the pageflow, it is very, very easy to understand the rest of the application! </para>
             
  -          <para>
  -              Here is the main page of the application, 
  -              <literal>numberGuess.jsp</literal>:
  -          </para>
  +            <para> Here is the main page of the application, <literal>numberGuess.jspx</literal>: </para>
             
             <example>
  -          <programlisting><![CDATA[<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
  -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
  -<html>
  -<head>
  -<title>Guess a number...</title>
  -</head>
  -<body>
  -<h1>Guess a number...</h1>
  -<f:view>
  -    <h:form>
  -        <h:outputText value="Higher!" rendered="#{numberGuess.randomNumber>numberGuess.currentGuess}" />
  -        <h:outputText value="Lower!" rendered="#{numberGuess.randomNumber<numberGuess.currentGuess}" />
  -        <br />
  -        I'm thinking of a number between <h:outputText value="#{numberGuess.smallest}" /> and 
  -        <h:outputText value="#{numberGuess.biggest}" />. You have 
  -        <h:outputText value="#{numberGuess.remainingGuesses}" /> guesses.
  -        <br />
  +                <programlisting><![CDATA[<<?xml version="1.0"?>
  +<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" 
  +          xmlns:h="http://java.sun.com/jsf/html"
  +          xmlns:f="http://java.sun.com/jsf/core"
  +          xmlns:s="http://jboss.com/products/seam/taglib"
  +          xmlns="http://www.w3.org/1999/xhtml"
  +          version="2.0">
  +  <jsp:output doctype-root-element="html" 
  +              doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
  +              doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
  +  <jsp:directive.page contentType="text/html"/>
  +  <html>
  +  <head>
  +    <title>Guess a number...</title>
  +    <link href="niceforms.css" rel="stylesheet" type="text/css" />
  +    <script language="javascript" type="text/javascript" src="niceforms.js" />
  +  </head>
  +  <body>
  +    <h1>Guess a number...</h1>
  +    <f:view>
  +	  <h:form styleClass="niceform">
  +	    
  +	    <div>
  +	    <h:messages globalOnly="true"/>
  +	    <h:outputText value="Higher!" 
  +	           rendered="#{numberGuess.randomNumber gt numberGuess.currentGuess}"/>
  +	    <h:outputText value="Lower!" 
  +	           rendered="#{numberGuess.randomNumber lt numberGuess.currentGuess}"/>
  +		</div>
  +		
  +		<div>
  +        I'm thinking of a number between 
  +        <h:outputText value="#{numberGuess.smallest}"/> and 
  +        <h:outputText value="#{numberGuess.biggest}"/>. You have 
  +        <h:outputText value="#{numberGuess.remainingGuesses}"/> guesses.
  +        </div>
  +        
  +        <div>
           Your guess: 
  -        <h:inputText value="#{numberGuess.currentGuess}" id="guess" required="true">
  -            <f:validateLongRange
  -                maximum="#{numberGuess.biggest}" 
  +        <h:inputText value="#{numberGuess.currentGuess}" id="inputGuess" 
  +                     required="true" size="3" 
  +                     rendered="#{(numberGuess.biggest-numberGuess.smallest) gt 20}">
  +          <f:validateLongRange maximum="#{numberGuess.biggest}" 
                   minimum="#{numberGuess.smallest}"/>
           </h:inputText>
  -        <h:commandButton type="submit" value="Guess" action="guess" />
  -        <br/>
  -        <h:message for="guess" style="color: red"/>
  +        <h:selectOneMenu value="#{numberGuess.currentGuess}" 
  +                         id="selectGuessMenu" required="true"
  +                         rendered="#{(numberGuess.biggest-numberGuess.smallest) le 20 and 
  +                                     (numberGuess.biggest-numberGuess.smallest) gt 4}">
  +          <s:selectItems value="#{numberGuess.possibilities}" var="i" label="#{i}"/>
  +        </h:selectOneMenu>
  +        <h:selectOneRadio value="#{numberGuess.currentGuess}" id="selectGuessRadio" 
  +                          required="true"
  +                          rendered="#{(numberGuess.biggest-numberGuess.smallest) le 4}">
  +          <s:selectItems value="#{numberGuess.possibilities}" var="i" label="#{i}"/>
  +        </h:selectOneRadio>
  +		<h:commandButton value="Guess" action="guess"/>
  +        <s:button value="Cheat" view="/confirm.jspx"/>
  +        <s:button value="Give up" action="giveup"/>
  +		</div>
  +		
  +		<div>
  +        <h:message for="inputGuess" style="color: red"/>
  +        </div>
  +        
       </h:form>
  -</f:view>
  -</body>
  -</html>]]></programlisting>
  +    </f:view>
  +  </body>
  +  </html>
  +</jsp:root>]]></programlisting>
             </example>
             
  -          <para>
  -              Notice how the command button names the <literal>guess</literal> transition
  -              instead of calling an action directly.
  -          </para>
  +            <para> Notice how the command button names the <literal>guess</literal> transition instead of calling an
  +                action directly. </para>
             
  -          <para>
  -              The <literal>win.jsp</literal> page is predictable:
  -          </para>
  +            <para> The <literal>win.jspx</literal> page is predictable: </para>
             
             <example>
  -          <programlisting><![CDATA[<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
  -<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
  -<html>
  -<head>
  -<title>You won!</title>
  -</head>
  -<body>
  -<h1>You won!</h1>
  -<f:view>
  +                <programlisting><![CDATA[<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" 
  +          xmlns:h="http://java.sun.com/jsf/html"
  +          xmlns:f="http://java.sun.com/jsf/core"
  +          xmlns="http://www.w3.org/1999/xhtml"
  +          version="2.0">
  +  <jsp:output doctype-root-element="html"
  +              doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
  +              doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
  +  <jsp:directive.page contentType="text/html"/>
  +  <html>
  +  <head>
  +    <title>You won!</title>
  +    <link href="niceforms.css" rel="stylesheet" type="text/css" />
  +  </head>
  +  <body>
  +    <h1>You won!</h1>
  +    <f:view>
       Yes, the answer was <h:outputText value="#{numberGuess.currentGuess}" />.
       It took you <h:outputText value="#{numberGuess.guessCount}" /> guesses.
  +      <h:outputText value="But you cheated, so it doesn't count!" 
  +                    rendered="#{numberGuess.cheat}"/>
       Would you like to <a href="numberGuess.seam">play again</a>?
     </f:view>
  -</body>
  -</html>]]></programlisting>
  +  </body>
  +  </html>
  +</jsp:root>
  +]]></programlisting>
             </example>
             
  -          <para>
  -              As is <literal>lose.jsp</literal> (which I can't be bothered copy/pasting).
  -              Finally, the JavaBean Seam component:
  -          </para>
  +            <para> As is <literal>lose.jspx</literal> (which I can't be bothered copy/pasting). Finally, the JavaBean
  +                Seam component: </para>
             
             <example>
               <programlistingco>
                   <areaspec>
  -                    <area id="numberguess-create" coords="12"/>
  -                    <area id="numberguess-begin" coords="13"/>
  +                        <area id="numberguess-create" coords="13"/>
                    </areaspec>
             <programlisting><![CDATA[@Name("numberGuess")
   @Scope(ScopeType.CONVERSATION)
  -public class NumberGuess {
  +public class NumberGuess implements Serializable {
      
      private int randomNumber;
      private Integer currentGuess;
  @@ -1892,9 +1660,9 @@
      private int smallest;
      private int guessCount;
      private int maxGuesses;
  +   private boolean cheated;
      
      @Create 
  -   @Begin(pageflow="numberGuess")
      public void begin()
      {
         randomNumber = new Random().nextInt(100);
  @@ -1966,34 +1734,62 @@
      public int getRandomNumber() {
         return randomNumber;
      }
  -}]]></programlisting>
  +
  +   public void cheated()
  +   {
  +      cheated = true;
  +   }
  +   
  +   public boolean isCheat() {
  +      return cheated;
  +   }
  +   
  +   public List<Integer> getPossibilities()
  +   {
  +      List<Integer> result = new ArrayList<Integer>();
  +      for(int i=smallest; i<=biggest; i++) result.add(i);
  +      return result;
  +   }
  +   
  +}
  +]]></programlisting>
               <calloutlist>
                   <callout arearefs="numberguess-create">
  -                    <para>
  -                        The first time a JSP page asks for a <literal>numberGuess</literal>
  -                        component, Seam will create a new one for it, and the 
  -                        <literal>@Create</literal> method will be invoked, allowing
  -                        the component to initialize itself.
  -                    </para>
  -                </callout>
  -                <callout arearefs="numberguess-begin">
  -                    <para>
  -                        The <literal>@Begin</literal> annotation starts a Seam
  -                        <emphasis>conversation</emphasis> (much more about that
  -                        later), and specifies the pageflow definition to use for
  -                        the conversation's page flow.
  -                    </para>
  +                            <para> The first time a JSP page asks for a <literal>numberGuess</literal> component, Seam
  +                                will create a new one for it, and the <literal>@Create</literal> method will be invoked,
  +                                allowing the component to initialize itself. </para>
                   </callout>
               </calloutlist>
               </programlistingco>
             </example>
             
  -          <para>
  -              As you can see, this Seam component is pure business logic! It
  -              doesn't need to know anything at all about the user interaction
  -              flow. This makes the component potentially more reuseable.
  +         
  +            <para>The <literal>pages.xml</literal> file starts a Seam
  +                <emphasis>conversation</emphasis> (much more about that later), and specifies the
  +                pageflow definition to use for the conversation's page flow. 
             </para>
             
  +            
  +            <example>
  +                <programlisting><![CDATA[
  +<!DOCTYPE pages PUBLIC
  +  "-//JBoss/Seam Pages Configuration DTD 1.3//EN"
  +  "http://jboss.com/products/seam/pages-1.3.dtd">
  +
  +<pages>
  +  <page view-id="/numberGuess.jspx">
  +    <begin-conversation join="true" pageflow="numberGuess"/>
  +  </page>
  +  <page view-id="/confirm.jspx">
  +    <begin-conversation nested="true" pageflow="cheat"/>
  +  </page>
  +</pages>      
  +]]></programlisting>                  
  +            </example>
  +            
  +               <para> As you can see, this Seam component is pure business logic! It doesn't need to know anything at all
  +                about the user interaction flow. This makes the component potentially more reuseable. </para>
  +            
         </section>
         
         <section>
  @@ -2009,10 +1805,8 @@
       <section>
         <title>Introduction</title>
         
  -      <para>
  -          The booking application is a complete hotel room reservation system
  -          incorporating the following features: 
  -      </para>
  +            <para> The booking application is a complete hotel room reservation system incorporating the following
  +                features: </para>
         
         <itemizedlist>
           <listitem>
  @@ -2056,80 +1850,56 @@
           </mediaobject>
         </screenshot>
         
  -      <para>
  -          The booking application uses JSF, EJB 3.0 and Seam, together with Facelets for the
  -          view. There is also a port of this application to JSF, Facelets, Seam, JavaBeans
  -          and Hibernate3.
  -      </para>
  +            <para> The booking application uses JSF, EJB 3.0 and Seam, together with Facelets for the view. There is
  +                also a port of this application to JSF, Facelets, Seam, JavaBeans and Hibernate3. </para>
   
  -      <para>
  -          One of the things you'll notice if you play with this application for long enough
  -          is that it is extremely <emphasis>robust</emphasis>. You can play with back buttons
  -          and browser refresh and opening multiple windows and entering nonsensical data as 
  -          much as you like and you will find it very difficult to make the application crash. 
  -          You might think that we spent weeks testing and fixing bugs to achive this. Actually, 
  -          this is not the case. Seam was designed to make it very straightforward to build
  -          robust web applications and a lot of robustness that you are probably used to having to
  -          code yourself comes naturally and automatically with Seam.
  -      </para>
  -      <para>
  -          As you browse the sourcecode of the example application, and learn how the application
  -          works, observe how the declarative state management and integrated validation has been
  -          used to achieve this robustness.
  -      </para>
  +            <para> One of the things you'll notice if you play with this application for long enough is that it is
  +                extremely <emphasis>robust</emphasis>. You can play with back buttons and browser refresh and opening
  +                multiple windows and entering nonsensical data as much as you like and you will find it very difficult
  +                to make the application crash. You might think that we spent weeks testing and fixing bugs to achive
  +                this. Actually, this is not the case. Seam was designed to make it very straightforward to build robust
  +                web applications and a lot of robustness that you are probably used to having to code yourself comes
  +                naturally and automatically with Seam. </para>
  +            <para> As you browse the sourcecode of the example application, and learn how the application works, observe
  +                how the declarative state management and integrated validation has been used to achieve this robustness. </para>
         
       </section>
       
       <section>
         <title>Overview of the booking example</title>
   
  -      <para>
  -          The project structure is identical to the previous one, to install and deploy this
  -          application, please refer to <xref linkend="try-examples"/>. Once you've successfully
  -          started the application, you can access it by pointing your browser to
  -          <ulink url="http://localhost:8080/seam-booking/"><literal>http://localhost:8080/seam-booking/</literal></ulink>
  +            <para> The project structure is identical to the previous one, to install and deploy this application,
  +                please refer to <xref linkend="try-examples"/>. Once you've successfully started the application, you
  +                can access it by pointing your browser to <ulink url="http://localhost:8080/seam-booking/">
  +                    <literal>http://localhost:8080/seam-booking/</literal>
  +                </ulink>
         </para>
   
  -      <para>
  -          Just nine classes (plus six session beans local interfaces) 
  -          where used to implement this application. 
  -          Six session bean action listeners contain all the business logic for the listed features.
  -      </para>
  +            <para> Just nine classes (plus six session beans local interfaces) where used to implement this application.
  +                Six session bean action listeners contain all the business logic for the listed features. </para>
         
         <itemizedlist>
             <listitem>
  -              <literal>BookingListAction</literal> retrieves existing bookings for the currently
  -              logged in user.
  -          </listitem>
  +                    <literal>BookingListAction</literal> retrieves existing bookings for the currently logged in user. </listitem>
             <listitem>
  -              <literal>ChangePasswordAction</literal> updates the password of the currently logged
  -              in user.
  -          </listitem>
  +                    <literal>ChangePasswordAction</literal> updates the password of the currently logged in user. </listitem>
             <listitem>
  -              <literal>HotelBookingAction</literal> implements the core functionality of the application:
  -              hotel room searching, selection, booking and booking confirmation. This functionality is
  -              implemented as a <emphasis>conversation</emphasis>, so this is the most interesting class
  -              in the application. 
  -          </listitem>
  +                    <literal>HotelBookingAction</literal> implements the core functionality of the application: hotel
  +                    room searching, selection, booking and booking confirmation. This functionality is implemented as a
  +                        <emphasis>conversation</emphasis>, so this is the most interesting class in the application. </listitem>
             <listitem>
  -              <literal>RegisterAction</literal> registers a new system user.
  -          </listitem>
  +                    <literal>RegisterAction</literal> registers a new system user. </listitem>
         </itemizedlist> 
                   
  -      <para>
  -          Three entity beans implement the application's persistent domain model.
  -      </para>
  +            <para> Three entity beans implement the application's persistent domain model. </para>
         
         <itemizedlist>
             <listitem>
  -              <literal>Hotel</literal> is an entity bean that represent a hotel
  -          </listitem>
  +                    <literal>Hotel</literal> is an entity bean that represent a hotel </listitem>
             <listitem>
  -              <literal>Booking</literal> is an entity bean that represents an existing booking
  -          </listitem>
  +                    <literal>Booking</literal> is an entity bean that represents an existing booking </listitem>
             <listitem>
  -              <literal>User</literal> is an entity bean to represents a user who can make 
  -              hotel bookings
  +                    <literal>User</literal> is an entity bean to represents a user who can make hotel bookings
             </listitem>
         </itemizedlist>
         
  @@ -2137,99 +1907,74 @@
       
       <section>
           <title>Understanding Seam conversations</title>
  -        <para>
  -            We encourage you browse the sourcecode at your pleasure. In this tutorial we'll concentrate
  -            upon one particular piece of functionality: hotel search, selection, booking and confirmation.
  -            From the point of view of the user, everything from selecting a hotel to confirming a booking 
  -            is one continuous unit of work, a <emphasis>conversation</emphasis>. Searching, however, is
  -            <emphasis>not</emphasis> part of the conversation. The user can select multiple hotels from 
  -            the same search results page, in different browser tabs.
  -        </para>
  -        <para>
  -            Most web application architectures have no first class construct to represent a conversation. 
  -            This causes enormous problems managing state associated with the conversation. Usually, Java 
  -            web applications use a combination of two techniques: first, some state is thrown into the 
  -            <literal>HttpSession</literal>; second, persistable state is flushed to the database after 
  -            every request, and reconstructed from the database at the beginning of each new request. 
  -        </para>
  -        <para>
  -            Since the database is the least scalable tier, this often results in an utterly unacceptable 
  -            lack of scalability. Added latency is also a problem, due to the extra traffic to and from the 
  -            database on every request. To reduce this redundant traffic, Java applications often introduce 
  -            a data (second-level) cache that keeps commonly accessed data between requests. This cache is 
  -            necessarily inefficient, because invalidation is based upon an LRU policy instead of being based 
  -            upon when the user has finished working with the data. Furthermore, because the cache is shared 
  -            between many concurrent transactions, we've introduced a whole raft of problem's associated with 
  -            keeping the cached state consistent with the database.
  -        </para>
  -        <para>
  -            Now consider the state held in the <literal>HttpSession</literal>. By very careful programming, 
  -            we might be able to control the size of the session data. This is a lot more difficult than it sounds, 
  +            <para> We encourage you browse the sourcecode at your pleasure. In this tutorial we'll concentrate upon one
  +                particular piece of functionality: hotel search, selection, booking and confirmation. From the point of
  +                view of the user, everything from selecting a hotel to confirming a booking is one continuous unit of
  +                work, a <emphasis>conversation</emphasis>. Searching, however, is <emphasis>not</emphasis> part of the
  +                conversation. The user can select multiple hotels from the same search results page, in different
  +                browser tabs. </para>
  +            <para> Most web application architectures have no first class construct to represent a conversation. This
  +                causes enormous problems managing state associated with the conversation. Usually, Java web applications
  +                use a combination of two techniques: first, some state is thrown into the
  +                <literal>HttpSession</literal>; second, persistable state is flushed to the database after every
  +                request, and reconstructed from the database at the beginning of each new request. </para>
  +            <para> Since the database is the least scalable tier, this often results in an utterly unacceptable lack of
  +                scalability. Added latency is also a problem, due to the extra traffic to and from the database on every
  +                request. To reduce this redundant traffic, Java applications often introduce a data (second-level) cache
  +                that keeps commonly accessed data between requests. This cache is necessarily inefficient, because
  +                invalidation is based upon an LRU policy instead of being based upon when the user has finished working
  +                with the data. Furthermore, because the cache is shared between many concurrent transactions, we've
  +                introduced a whole raft of problem's associated with keeping the cached state consistent with the
  +                database. </para>
  +            <para> Now consider the state held in the <literal>HttpSession</literal>. By very careful programming, we
  +                might be able to control the size of the session data. This is a lot more difficult than it sounds,
               since web browsers permit ad hoc non-linear navigation. But suppose we suddenly discover a system 
  -            requirement that says that a user is allowed to have <emphasis>mutiple concurrent conversations</emphasis>,
  -            halfway through the development of the system (this has happened to me). Developing mechanisms
  -            to isolate session state associated with different concurrent conversations, and incorporating
  -            failsafes to ensure that conversation state is destroyed when the user aborts one of the 
  -            conversations by closing a browser window or tab is not for the faint hearted (I've implemented 
  -            this stuff twice so far, once for a client application, once for Seam, but I'm famously
  -            psychotic).
  -        </para>
  -        <para>
  -            Now there is a better way.
  -        </para>
  -        <para>
  -            Seam introduces the <emphasis>conversation context</emphasis> as a first class construct. You
  -            can safely keep conversational state in this context, and be assured that it will have a 
  -            well-defined lifecycle. Even better, you won't need to be continually pushing data back and 
  -            forth between the application server and the database, since the conversation context is a
  -            natural cache of data that the user is currently working with.
  -        </para>
  -        <para>
  -            Usually, the components we keep in the conversation context are stateful session beans. (We 
  -            can also keep entity beans and JavaBeans in the conversation context.) There is an ancient
  -            canard in the Java community that stateful session beans are a scalability killer. This may
  -            have been true in 1998 when WebFoobar 1.0 was released. It is no longer true today.
  -            Application servers like JBoss 4.0 have extremely sophisticated mechanisms for stateful
  -            session bean state replication. (For example, the JBoss EJB3 container performs fine-grained
  -            replication, replicating only those bean attribute values which actually changed.) Note 
  -            that all the traditional technical arguments for why stateful beans are inefficient apply
  -            equally to the <literal>HttpSession</literal>, so the practice of shifting state from business 
  -            tier stateful session bean components to the web session to try and improve performance is 
  -            unbelievably misguided. It is certainly possible to write unscalable applications using 
  -            stateful session beans, by using stateful beans incorrectly, or by using them for the wrong 
  -            thing. But that doesn't mean you should <emphasis>never</emphasis> use them. Anyway, Seam 
  -            guides you toward a safe usage model. Welcome to 2005.
  -        </para>
  -        <para>
  -            OK, I'll stop ranting now, and get back to the tutorial.
  -        </para>
  +                requirement that says that a user is allowed to have <emphasis>mutiple concurrent
  +                conversations</emphasis>, halfway through the development of the system (this has happened to me).
  +                Developing mechanisms to isolate session state associated with different concurrent conversations, and
  +                incorporating failsafes to ensure that conversation state is destroyed when the user aborts one of the
  +                conversations by closing a browser window or tab is not for the faint hearted (I've implemented this
  +                stuff twice so far, once for a client application, once for Seam, but I'm famously psychotic). </para>
  +            <para> Now there is a better way. </para>
  +            <para> Seam introduces the <emphasis>conversation context</emphasis> as a first class construct. You can
  +                safely keep conversational state in this context, and be assured that it will have a well-defined
  +                lifecycle. Even better, you won't need to be continually pushing data back and forth between the
  +                application server and the database, since the conversation context is a natural cache of data that the
  +                user is currently working with. </para>
  +            <para> Usually, the components we keep in the conversation context are stateful session beans. (We can also
  +                keep entity beans and JavaBeans in the conversation context.) There is an ancient canard in the Java
  +                community that stateful session beans are a scalability killer. This may have been true in 1998 when
  +                WebFoobar 1.0 was released. It is no longer true today. Application servers like JBoss AS have extremely
  +                sophisticated mechanisms for stateful session bean state replication. (For example, the JBoss EJB3
  +                container performs fine-grained replication, replicating only those bean attribute values which actually
  +                changed.) Note that all the traditional technical arguments for why stateful beans are inefficient apply
  +                equally to the <literal>HttpSession</literal>, so the practice of shifting state from business tier
  +                stateful session bean components to the web session to try and improve performance is unbelievably
  +                misguided. It is certainly possible to write unscalable applications using stateful session beans, by
  +                using stateful beans incorrectly, or by using them for the wrong thing. But that doesn't mean you should
  +                    <emphasis>never</emphasis> use them. Anyway, Seam guides you toward a safe usage model. Welcome to
  +                2005. </para>
  +            <para> OK, I'll stop ranting now, and get back to the tutorial. </para>
  +
  +            <para> The booking example application shows how stateful components with different scopes can collaborate
  +                together to achieve complex behaviors. The main page of the booking application allows the user to
  +                search for hotels. The search results are kept in the Seam session scope. When the user navigates to one
  +                of these hotels, a conversation begins, and a conversation scoped component calls back to the session
  +                scoped component to retrieve the selected hotel. </para>
           
  -        <para>
  -            The booking example application shows how stateful components with different scopes can
  -            collaborate together to achieve complex behaviors. The main page of the booking application
  -            allows the user to search for hotels. The search results are kept in the Seam session scope.
  -            When the user navigates to one of these hotels, a conversation begins, and a conversation
  -            scoped component calls back to the session scoped component to retrieve the selected
  -            hotel. 
  -        </para>
  +            <para> The booking example also demonstrates the use of Ajax4JSF to implement rich client behavior without
  +                the use of handwritten JavaScript. </para>
           
  -        <para>
  -            The booking example also demonstrates the use of Ajax4JSF to implement rich client behavior
  -            without the use of handwritten JavaScript.
  -        </para>
  -        
  -        <para>
  -            The search functionality is implemented using a session-scope stateful session bean, 
  -            similar to the one we saw in the message list example above.
  -        </para>
  +            <para> The search functionality is implemented using a session-scope stateful session bean, similar to the
  +                one we saw in the message list example above. </para>
           
           <example>
              <programlistingco>
                   <areaspec>
                       <area id="booking-stateful-annotation" coords="1"/>
                       <area id="booking-restrict-annotation" coords="4"/>
  -                    <area id="booking-datamodel-annotation" coords="16"/>
  -                    <area id="booking-destroy-annotation" coords="66"/>
  +                        <area id="booking-datamodel-annotation" coords="15"/>
  +                        <area id="booking-destroy-annotation" coords="70"/>
                   </areaspec>    
               <programlisting><![CDATA[@Stateful
   @Name("hotelSearch")
  @@ -2248,25 +1993,24 @@
      @DataModel
      private List<Hotel> hotels;
      
  -   public String find()
  +   public void find()
      {
         page = 0;
         queryHotels();   
  -      return "main";
      }
  -
  -   public String nextPage()
  +   public void nextPage()
      {
         page++;
         queryHotels();
  -      return "main";
      }
         
      private void queryHotels()
      {
  -      String searchPattern = searchString==null ? "%" : '%' + searchString.toLowerCase().replace('*', '%') + '%';
  -      hotels = em.createQuery("select h from Hotel h where lower(h.name) like :search or lower(h.city) like :search or lower(h.zip) like :search or lower(h.address) like :search")
  -            .setParameter("search", searchPattern)
  +      hotels = 
  +          em.createQuery("select h from Hotel h where lower(h.name) like #{pattern} " + 
  +                         "or lower(h.city) like #{pattern} " + 
  +                         "or lower(h.zip) like #{pattern} " +
  +                         "or lower(h.address) like #{pattern}")
               .setMaxResults(pageSize)
               .setFirstResult( page * pageSize )
               .getResultList();
  @@ -2285,6 +2029,13 @@
         this.pageSize = pageSize;
      }
   
  +   @Factory(value="pattern", scope=ScopeType.EVENT)
  +   public String getSearchPattern()
  +   {
  +      return searchString==null ? 
  +            "%" : '%' + searchString.toLowerCase().replace('*', '%') + '%';
  +   }
  +   
      public String getSearchString()
      {
         return searchString;
  @@ -2297,79 +2048,73 @@
      
      @Destroy @Remove
      public void destroy() {}
  -
   }]]></programlisting>
               <calloutlist>
                   <callout arearefs="booking-stateful-annotation">
  -                    <para>
  -                        The EJB standard <literal>@Stateful</literal> annotation identifies
  -                        this class as a stateful session bean. Stateful session beans are
  -                        scoped to the conversation context by default.
  -                    </para>
  +                            <para> The EJB standard <literal>@Stateful</literal> annotation identifies this class as a
  +                                stateful session bean. Stateful session beans are scoped to the conversation context by
  +                                default. </para>
                   </callout>
                   <callout arearefs="booking-restrict-annotation">
  -                    <para>
  -                        The <literal>@Restrict</literal> annotation applies a security restriction to the
  +                            <para> The <literal>@Restrict</literal> annotation applies a security restriction to the
                           component. It restricts access to the component allowing only logged-in users. The
  -                        security chapter explains more about security in Seam.
  -                    </para>
  +                                security chapter explains more about security in Seam. </para>
                   </callout>
                   <callout arearefs="booking-datamodel-annotation">
  -                    <para>
  -                        The <link linkend="datamodel-annotation"><literal>@DataModel</literal></link> 
  -                        annotation exposes a <literal>List</literal> as a JSF <literal>ListDataModel</literal>.
  -                        This makes it easy to implement clickable lists for search screens. In this
  -                        case, the list of hotels is exposed to the page as a <literal>ListDataModel</literal>
  -                        in the conversation variable named <literal>hotels</literal>.
  -                    </para>
  +                            <para> The <link linkend="datamodel-annotation">
  +                                    <literal>@DataModel</literal>
  +                                </link> annotation exposes a <literal>List</literal> as a JSF
  +                                <literal>ListDataModel</literal>. This makes it easy to implement clickable lists for
  +                                search screens. In this case, the list of hotels is exposed to the page as a
  +                                    <literal>ListDataModel</literal> in the conversation variable named
  +                                <literal>hotels</literal>. </para>
                   </callout>
                   <callout arearefs="booking-destroy-annotation">
  -                    <para>
  -                        The EJB standard <literal>@Remove</literal> annotation specifies that a stateful
  -                        session bean should be removed and its state destroyed after invocation of the
  -                        annotated method. In Seam, all stateful session beans should define a method 
  -                        marked <literal>@Destroy @Remove</literal>. This is the EJB remove method that 
  -                        will be called when Seam destroys the session context. Actually, the
  -                        <link linkend="destroy-annotation"><literal>@Destroy</literal></link> 
  -                        annotation is of more general usefulness, since it can be used for any 
  -                        kind of cleanup that should happen when any Seam context ends. If you don't
  -                        have an <literal>@Destroy @Remove</literal> method, state will leak and you
  -                        will suffer performance problems.
  -                    </para>
  +                            <para> The EJB standard <literal>@Remove</literal> annotation specifies that a stateful
  +                                session bean should be removed and its state destroyed after invocation of the annotated
  +                                method. In Seam, all stateful session beans should define a method marked
  +                                    <literal>@Destroy @Remove</literal>. This is the EJB remove method that will be
  +                                called when Seam destroys the session context. Actually, the <link
  +                                    linkend="destroy-annotation">
  +                                    <literal>@Destroy</literal>
  +                                </link> annotation is of more general usefulness, since it can be used for any kind of
  +                                cleanup that should happen when any Seam context ends. If you don't have an
  +                                    <literal>@Destroy @Remove</literal> method, state will leak and you will suffer
  +                                performance problems. </para>
                   </callout>
               </calloutlist>
               </programlistingco>
           </example>
           
  -        <para>
  -            The main page of the application is a Facelets page. Let's look at the fragment which relates
  -            to searching for hotels:
  -        </para>
  +            <para> The main page of the application is a Facelets page. Let's look at the fragment which relates to
  +                searching for hotels: </para>
           
           <example>
               <programlistingco>
                   <areaspec>
  -                    <area id="booking-support-element" coords="11"/>
  -                    <area id="booking-status-element" coords="18"/>
  -                    <area id="booking-outputpanel-element" coords="35"/>
  -                    <area id="booking-link-element" coords="58"/>
  +                        <area id="booking-support-element" coords="14"/>
  +                        <area id="booking-status-element" coords="20"/>
  +                        <area id="booking-outputpanel-element" coords="37"/>
  +                        <area id="booking-link-element" coords="61"/>
                   </areaspec>
               <programlisting><![CDATA[<div class="section">
  -<h:form>
     
     <span class="errors">
       <h:messages globalOnly="true"/>
     </span>
       
     <h1>Search Hotels</h1>
  +
  +	<h:form id="searchCriteria">
     <fieldset> 
  -     <h:inputText value="#{hotelSearch.searchString}" style="width: 165px;">
  +	   <h:inputText id="searchString" value="#{hotelSearch.searchString}" 
  +                    style="width: 165px;">
           <a:support event="onkeyup" actionListener="#{hotelSearch.find}" 
                      reRender="searchResults" />
        </h:inputText>
        &#160;
  -     <a:commandButton value="Find Hotels" action="#{hotelSearch.find}" 
  -                      styleClass="button" reRender="searchResults"/>
  +	   <a:commandButton id="findHotels" value="Find Hotels" action="#{hotelSearch.find}" 
  +                        reRender="searchResults"/>
        &#160;
        <a:status>
           <f:facet name="start">
  @@ -2384,15 +2129,16 @@
           <f:selectItem itemLabel="20" itemValue="20"/>
        </h:selectOneMenu>
     </fieldset>
  +    </h:form>
       
  -</h:form>
   </div>
   
   <a:outputPanel id="searchResults">
     <div class="section">
     <h:outputText value="No Hotels Found" 
                   rendered="#{hotels != null and hotels.rowCount==0}"/>
  -  <h:dataTable value="#{hotels}" var="hot" rendered="#{hotels.rowCount>0}">
  +    <h:dataTable id="hotels" value="#{hotels}" var="hot" 
  +                 rendered="#{hotels.rowCount>0}">
       <h:column>
         <f:facet name="header">Name</f:facet>
         #{hot.name}
  @@ -2411,75 +2157,60 @@
       </h:column>
       <h:column>
         <f:facet name="header">Action</f:facet>
  -      <s:link value="View Hotel" action="#{hotelBooking.selectHotel(hot)}"/>
  +            <s:link id="viewHotel" value="View Hotel" 
  +                    action="#{hotelBooking.selectHotel(hot)}"/>
       </h:column>
     </h:dataTable>
     <s:link value="More results" action="#{hotelSearch.nextPage}" 
             rendered="#{hotelSearch.nextPageAvailable}"/>
     </div>
  -</a:outputPanel>]]></programlisting>
  +</a:outputPanel>    ]]></programlisting>
               <calloutlist>
                   <callout arearefs="booking-support-element">
  -                    <para>
  -                        The Ajax4JSF <literal>&lt;a:support&gt;</literal> tag allows a JSF action event
  -                        listener to be called by asynchronous <literal>XMLHttpRequest</literal> when
  -                        a JavaScript event like <literal>onkeyup</literal> occurs. Even better, the
  -                        <literal>reRender</literal> attribute lets us render a fragment of the JSF
  -                        page and perform a partial page update when the asynchronous response is
  -                        received.
  -                    </para>
  +                            <para> The Ajax4JSF <literal>&lt;a:support&gt;</literal> tag allows a JSF action
  +                                event listener to be called by asynchronous <literal>XMLHttpRequest</literal> when a
  +                                JavaScript event like <literal>onkeyup</literal> occurs. Even better, the
  +                                    <literal>reRender</literal> attribute lets us render a fragment of the JSF page and
  +                                perform a partial page update when the asynchronous response is received. </para>
                   </callout>
                   <callout arearefs="booking-status-element">
  -                    <para>
  -                        The Ajax4JSF <literal>&lt;a:status&gt;</literal> tag lets us display a cheesy
  -                        annimated image while we wait for asynchronous requests to return.
  -                    </para>
  +                            <para> The Ajax4JSF <literal>&lt;a:status&gt;</literal> tag lets us display a cheesy
  +                                annimated image while we wait for asynchronous requests to return. </para>
                   </callout>
                   <callout arearefs="booking-outputpanel-element">
  -                    <para>
  -                        The Ajax4JSF <literal>&lt;a:outputPanel&gt;</literal> tag defines a region of
  -                        the page which can be re-rendered by an asynchronous request.
  -                    </para>
  +                            <para> The Ajax4JSF <literal>&lt;a:outputPanel&gt;</literal> tag defines a region of
  +                                the page which can be re-rendered by an asynchronous request. </para>
                   </callout>
                   <callout arearefs="booking-link-element">
  -                    <para>
  -                        The Seam <literal>&lt;s:link&gt;</literal> tag lets us attach a JSF action 
  -                        listener to an ordinary (non-JavaScript) HTML link. The advantage of this
  -                        over the standard JSF <literal>&lt;h:commandLink&gt;</literal> is that it
  -                        preserves the operation of "open in new window" and "open in new tab". Also
  -                        notice that we use a method binding with a parameter: 
  -                        <literal>#{hotelBooking.selectHotel(hot)}</literal>. This is not possible
  -                        in the standard Unified EL, but Seam provides an extension to the EL that
  -                        lets you use parameters on any method binding expression.
  -                    </para>
  +                            <para> The Seam <literal>&lt;s:link&gt;</literal> tag lets us attach a JSF action
  +                                listener to an ordinary (non-JavaScript) HTML link. The advantage of this over the
  +                                standard JSF <literal>&lt;h:commandLink&gt;</literal> is that it preserves the
  +                                operation of "open in new window" and "open in new tab". Also notice that we use a
  +                                method binding with a parameter: <literal>#{hotelBooking.selectHotel(hot)}</literal>.
  +                                This is not possible in the standard Unified EL, but Seam provides an extension to the
  +                                EL that lets you use parameters on any method binding expression. </para>
                   </callout>
               </calloutlist>
               </programlistingco>
           </example>
           
  -        <para>
  -            This page displays the search results dynamically as we type, and lets us choose a hotel
  -            and pass it to the <literal>selectHotel()</literal> method of the 
  -            <literal>HotelBookingAction</literal>, which is where the <emphasis>really</emphasis>
  -            interesting stuff is going to happen.
  -        </para>
  -        
  -        <para>
  -            Now lets see how the booking example application uses a conversation-scoped stateful session
  -            bean to achieve a natural cache of persistent data related to the conversation. The following
  -            code example is pretty long. But if you think of it as a list of scripted actions that
  -            implement the various steps of the conversation, it's understandable. Read the class from top 
  -            to bottom, as if it were a story.
  -        </para>
  +            <para> This page displays the search results dynamically as we type, and lets us choose a hotel and pass it
  +                to the <literal>selectHotel()</literal> method of the <literal>HotelBookingAction</literal>, which is
  +                where the <emphasis>really</emphasis> interesting stuff is going to happen. </para>
  +
  +            <para> Now lets see how the booking example application uses a conversation-scoped stateful session bean to
  +                achieve a natural cache of persistent data related to the conversation. The following code example is
  +                pretty long. But if you think of it as a list of scripted actions that implement the various steps of
  +                the conversation, it's understandable. Read the class from top to bottom, as if it were a story. </para>
           
           <example>
               <programlistingco>
                   <areaspec>
                       <area id="booking-extendedpersistencecontext-annotation" coords="7"/>
  -                    <area id="booking-out-annotation" coords="10"/>
  -                    <area id="booking-begin-annotation" coords="29"/>
  -                    <area id="booking-end-annotation" coords="61"/>
  -                    <area id="booking-dest-annotation" coords="78"/>
  +                        <area id="booking-out-annotation" coords="17"/>
  +                        <area id="booking-begin-annotation" coords="31"/>
  +                        <area id="booking-end-annotation" coords="72"/>
  +                        <area id="booking-dest-annotation" coords="85"/>
                   </areaspec>    
               <programlisting><![CDATA[@Stateful
   @Name("hotelBooking")
  @@ -2509,169 +2240,155 @@
      @Logger 
      private Log log;
      
  +   private boolean bookingValid;
  +   
      @Begin
  -   public String selectHotel(Hotel selectedHotel)
  +   public void selectHotel(Hotel selectedHotel)
      {
         hotel = em.merge(selectedHotel);
  -      return "hotel";
      }
      
  -   public String bookHotel()
  +   public void bookHotel()
      {      
         booking = new Booking(hotel, user);
         Calendar calendar = Calendar.getInstance();
         booking.setCheckinDate( calendar.getTime() );
         calendar.add(Calendar.DAY_OF_MONTH, 1);
         booking.setCheckoutDate( calendar.getTime() );
  -      
  -      return "book";
      }
   
  -   public String setBookingDetails()
  +   public void setBookingDetails()
      {
  -      if (booking==null || hotel==null) return "main";
  -      if ( !booking.getCheckinDate().before( booking.getCheckoutDate() ) )
  +      Calendar calendar = Calendar.getInstance();
  +      calendar.add(Calendar.DAY_OF_MONTH, -1);
  +      if ( booking.getCheckinDate().before( calendar.getTime() ) )
         {
  -         facesMessages.add("Check out date must be later than check in date");
  -         return null;
  +         facesMessages.addToControl("checkinDate", "Check in date must be a future date");
  +         bookingValid=false;
  +      }
  +      else if ( !booking.getCheckinDate().before( booking.getCheckoutDate() ) )
  +      {
  +         facesMessages.addToControl("checkoutDate", 
  +                                    "Check out date must be later than check in date");
  +         bookingValid=false;
         }
         else
         {
  -         return "confirm";
  +         bookingValid=true;
         }
      }
   
  +   public boolean isBookingValid()
  +   {
  +      return bookingValid;
  +   }
  +   
      @End
  -   public String confirm()
  +   public void confirm()
      {
  -      if (booking==null || hotel==null) return "main";
         em.persist(booking);
  -      facesMessages.add("Thank you, #{user.name}, your confimation number for #{hotel.name} is #{booking.id}");
  +      facesMessages.add("Thank you, #{user.name}, your confimation number " + 
  +                        " for #{hotel.name} is #{booking.id}");
         log.info("New booking: #{booking.id} for #{user.username}");
  -      events.raiseEvent("bookingConfirmed");
  -      return "confirmed";
  +      events.raiseTransactionSuccessEvent("bookingConfirmed");
      }
      
      @End
  -   public String cancel()
  -   {
  -      return "main";
  -   }
  +   public void cancel() {}
      
      @Destroy @Remove
      public void destroy() {}
  -
  -}]]></programlisting>
  +]]></programlisting>
               <calloutlist>
                   <callout arearefs="booking-extendedpersistencecontext-annotation">
  -                    <para>
  -                        This bean uses an EJB3 <emphasis>extended persistence context</emphasis>, so that
  -                        any entity instances remain managed for the whole lifecycle of the stateful
  -                        session bean.
  +                            <para> This bean uses an EJB3 <emphasis>extended persistence context</emphasis>, so that any
  +                                entity instances remain managed for the whole lifecycle of the stateful session bean.
                       </para>
                   </callout>
                   <callout arearefs="booking-out-annotation">
  -                    <para>
  -                        The <link linkend="out-annotation"><literal>@Out</literal></link> annotation
  -                        declares that an attribute value is <emphasis>outjected</emphasis> to a
  -                        context variable after method invocations. In this case, the context variable
  -                        named <literal>hotel</literal> will be set to the value of the 
  -                        <literal>hotel</literal> instance variable after every action listener
  -                        invocation completes.
  -                    </para>
  +                            <para> The <link linkend="out-annotation">
  +                                    <literal>@Out</literal>
  +                                </link> annotation declares that an attribute value is <emphasis>outjected</emphasis> to
  +                                a context variable after method invocations. In this case, the context variable named
  +                                    <literal>hotel</literal> will be set to the value of the <literal>hotel</literal>
  +                                instance variable after every action listener invocation completes. </para>
                   </callout>
                   <callout arearefs="booking-begin-annotation">
  -                    <para>
  -                        The <link linkend="begin-annotation"><literal>@Begin</literal></link> annotation
  -                        specifies that the annotated method begins a 
  -                        <emphasis>long-running conversation</emphasis>, so the current conversation context
  -                        will not be destroyed at the end of the request. Instead, it will be reassociated
  -                        with every request from the current window, and destroyed either by timeout due to
  -                        conversation inactivity or invocation of a matching <literal>@End</literal> method.
  -                    </para>
  +                            <para> The <link linkend="begin-annotation">
  +                                    <literal>@Begin</literal>
  +                                </link> annotation specifies that the annotated method begins a <emphasis>long-running
  +                                    conversation</emphasis>, so the current conversation context will not be destroyed
  +                                at the end of the request. Instead, it will be reassociated with every request from the
  +                                current window, and destroyed either by timeout due to conversation inactivity or
  +                                invocation of a matching <literal>@End</literal> method. </para>
                   </callout>
                   <callout arearefs="booking-end-annotation">
  -                    <para>
  -                        The <link linkend="end-annotation"><literal>@End</literal></link> annotation
  -                        specifies that the annotated method ends the current long-running conversation, 
  -                        so the current conversation context will be destroyed at the end of the request.
  -                    </para>
  +                            <para> The <link linkend="end-annotation">
  +                                    <literal>@End</literal>
  +                                </link> annotation specifies that the annotated method ends the current long-running
  +                                conversation, so the current conversation context will be destroyed at the end of the
  +                                request. </para>
                   </callout>
                   <callout arearefs="booking-dest-annotation">
  -                    <para>
  -                        This EJB remove method will be called when Seam destroys the conversation context.
  -                        Don't ever forget to define this method!
  -                    </para>
  +                            <para> This EJB remove method will be called when Seam destroys the conversation context.
  +                                Don't ever forget to define this method! </para>
                   </callout>
               </calloutlist>
               </programlistingco>
           </example>
           
           <para>
  -            <literal>HotelBookingAction</literal> contains all the action listener methods that implement 
  -            selection, booking and booking confirmation, and holds state related to this work in its instance 
  -            variables. We think you'll agree that this code is much cleaner and simpler than getting and 
  -            setting <literal>HttpSession</literal> attributes.
  -        </para>
  -        
  -        <para>
  -            Even better, a user can have multiple isolated conversations per login session. Try it!
  -            Log in, run a search, and navigate to different hotel pages in multiple browser tabs. 
  -            You'll be able to work on creating two different hotel reservations at the same time. 
  -            If you leave any one conversation inactive for long enough, Seam will eventually time 
  -            out that conversation and destroy its state. If, after ending a conversation, you 
  -            backbutton to a page of that conversation and try to perform an action, Seam will
  -            detect that the conversation was already ended, and redirect you to the search page.
  -        </para>
  +                <literal>HotelBookingAction</literal> contains all the action listener methods that implement selection,
  +                booking and booking confirmation, and holds state related to this work in its instance variables. We
  +                think you'll agree that this code is much cleaner and simpler than getting and setting
  +                    <literal>HttpSession</literal> attributes. </para>
  +
  +            <para> Even better, a user can have multiple isolated conversations per login session. Try it! Log in, run a
  +                search, and navigate to different hotel pages in multiple browser tabs. You'll be able to work on
  +                creating two different hotel reservations at the same time. If you leave any one conversation inactive
  +                for long enough, Seam will eventually time out that conversation and destroy its state. If, after ending
  +                a conversation, you backbutton to a page of that conversation and try to perform an action, Seam will
  +                detect that the conversation was already ended, and redirect you to the search page. </para>
           
       </section>
       
       <section>
           <title>The Seam UI control library</title>
  -        <para>
  -            If you check inside the WAR file for the booking application, you'll find <literal>seam-ui.jar</literal>
  -            in the <literal>WEB-INF/lib</literal> directory. This package contains a number of JSF custom
  -            controls that integrate with Seam. The booking application uses the <literal>&lt;s:link&gt;</literal>
  -            control for navigation from the search screen to the hotel page:
  -        </para>
  -        
  -        <programlisting><![CDATA[<s:link value="View Hotel" action="#{hotelBooking.selectHotel}"/>]]></programlisting>
  -        
  -        <para>
  -            The use of <literal>&lt;s:link&gt;</literal> here allows us to attach an action listener
  -            to a HTML link without breaking the browser's "open in new window" feature. The standard
  -            JSF <literal>&lt;h:commandLink&gt;</literal> does not work with "open in new window".
  -            We'll see later that <literal>&lt;s:link&gt;</literal> also offers a number of other
  -            useful features, including conversation propagation rules.
  -        </para>
  -        
  -        <para>
  -            The booking application uses some other Seam and Ajax4JSF controls, especially on the 
  -            <literal>/book.xhtml</literal> page. We won't get into the details of those controls
  -            here, but if you want to understand this code, please refer to the chapter covering
  -            Seam's functionality for JSF form validation.
  -        </para>
  +            <para> If you check inside the WAR file for the booking application, you'll find
  +                <literal>seam-ui.jar</literal> in the <literal>WEB-INF/lib</literal> directory. This package contains a
  +                number of JSF custom controls that integrate with Seam. The booking application uses the
  +                    <literal>&lt;s:link&gt;</literal> control for navigation from the search screen to the hotel
  +                page: </para>
  +
  +            <programlisting><![CDATA[<s:link value="View Hotel" action="#{hotelBooking.selectHotel(hot)}"/>]]></programlisting>
  +
  +            <para> The use of <literal>&lt;s:link&gt;</literal> here allows us to attach an action listener to a
  +                HTML link without breaking the browser's "open in new window" feature. The standard JSF
  +                    <literal>&lt;h:commandLink&gt;</literal> does not work with "open in new window". We'll see
  +                later that <literal>&lt;s:link&gt;</literal> also offers a number of other useful features,
  +                including conversation propagation rules. </para>
  +
  +            <para> The booking application uses some other Seam and Ajax4JSF controls, especially on the
  +                    <literal>/book.xhtml</literal> page. We won't get into the details of those controls here, but if
  +                you want to understand this code, please refer to the chapter covering Seam's functionality for JSF form
  +                validation. </para>
       </section>
       
       <section>
           <title>The Seam Debug Page</title>
           
  -        <para>
  -            The WAR also includes <literal>seam-debug.jar</literal>. If this jar is deployed in 
  -            <literal>WEB-INF/lib</literal>, along with the Facelets, and if you set the following Seam 
  -            property in <literal>web.xml</literal> or <literal>seam.properties</literal>:
  -        </para>
  -
  -        <programlisting><![CDATA[<context-param>
  -    <param-name>org.jboss.seam.core.init.debug</param-name>
  -    <param-value>true</param-value>
  -</context-param>]]></programlisting>
  -    
  -        <para>
  -            Then the Seam debug page will be available. This page lets you browse and inspect the Seam 
  -            components in any of the Seam contexts associated with your current login session. Just
  -            point your browser at <ulink url="http://localhost:8080/seam-booking/debug.seam"><literal>http://localhost:8080/seam-booking/debug.seam</literal></ulink>.
  -        </para>
  +            <para> The WAR also includes <literal>seam-debug.jar</literal>.  The Seam debug page will be availabled 
  +                if this jar is deployed in
  +                    <literal>WEB-INF/lib</literal>, along with the Facelets, and if you set the debug property
  +                of the <literal>init</literal> component:</para>
  +            
  +            <programlisting><![CDATA[<core:init jndi-pattern="@jndiPattern@" debug="true"/>]]></programlisting>                            
  +
  +            <para>  This page lets you browse and inspect the Seam components
  +                in any of the Seam contexts associated with your current login session. Just point your browser at
  +                    <ulink url="http://localhost:8080/seam-booking/debug.seam">
  +                    <literal>http://localhost:8080/seam-booking/debug.seam</literal>
  +                </ulink>. </para>
           
           <mediaobject>
             <imageobject role="fo">
  @@ -2689,15 +2406,10 @@
     <section id="dvdstore">
         <title>A complete application featuring Seam and jBPM: the DVD Store example</title>
         
  -      <para>
  -          The DVD Store demo application shows the practical usage of jBPM for 
  -          both task management and pageflow.
  -      </para>
  +        <para> The DVD Store demo application shows the practical usage of jBPM for both task management and pageflow. </para>
         
  -      <para>
  -          The user screens take advantage of a jPDL pageflow to implement searching
  -          and shopping cart functionality.
  -      </para>
  +        <para> The user screens take advantage of a jPDL pageflow to implement searching and shopping cart
  +            functionality. </para>
   
         <screenshot>
           <screeninfo>DVD Store example</screeninfo>
  @@ -2711,11 +2423,8 @@
           </mediaobject>
         </screenshot>
         
  -      <para>
  -          The administration screens take use jBPM to manage the approval and
  -          shipping cycle for orders. The business process may even be changed 
  -          dynamically, by selecting a different process definition!
  -      </para>
  +        <para> The administration screens take use jBPM to manage the approval and shipping cycle for orders. The
  +            business process may even be changed dynamically, by selecting a different process definition! </para>
   
         <screenshot>
           <screeninfo>DVD Store example</screeninfo>
  @@ -2736,10 +2445,8 @@
     <section id="issues">
         <title>A complete application featuring Seam workspace management: the Issue Tracker example</title>
         
  -      <para>
  -          The Issue Tracker demo shows off Seam's workspace management functionality:
  -          the conversation switcher, conversation list and breadcrumbs.
  -      </para>
  +        <para> The Issue Tracker demo shows off Seam's workspace management functionality: the conversation switcher,
  +            conversation list and breadcrumbs. </para>
         
         <screenshot>
           <screeninfo>DVD Store example</screeninfo>
  @@ -2760,11 +2467,8 @@
     <section id="hibernate">
         <title>An example of Seam with Hibernate: the Hibernate Booking example</title>
         
  -      <para>
  -          The Hibernate Booking demo is a straight port of the Booking demo to an
  -          alternative architecture that uses Hibernate for persistence and JavaBeans
  -          instead of session beans.
  -      </para>
  +        <para> The Hibernate Booking demo is a straight port of the Booking demo to an alternative architecture that
  +            uses Hibernate for persistence and JavaBeans instead of session beans. </para>
         
         <para>TODO</para>
         <para>Look in the <literal>hibernate</literal> directory.</para>
  @@ -2773,16 +2477,12 @@
     <section id="blog">
         <title>A RESTful Seam application: the Blog example</title>
         
  -      <para>
  -          Seam makes it very easy to implement applications which keep state on the
  -          server-side. However, server-side state is not always appropriate, especially
  -          in for functionality that serves up <emphasis>content</emphasis>. For this
  -          kind of problem we often need to let the user bookmark pages and have a 
  -          relatively stateless server, so that any page can be accessed at any time,
  -          via the bookmark. The Blog example shows how to a implement RESTful 
  -          application using Seam. Every page of the application can be bookmarked,
  -          including the search results page.
  -      </para>
  +        <para> Seam makes it very easy to implement applications which keep state on the server-side. However,
  +            server-side state is not always appropriate, especially in for functionality that serves up
  +                <emphasis>content</emphasis>. For this kind of problem we often need to let the user bookmark pages and
  +            have a relatively stateless server, so that any page can be accessed at any time, via the bookmark. The Blog
  +            example shows how to a implement RESTful application using Seam. Every page of the application can be
  +            bookmarked, including the search results page. </para>
   
         <screenshot>
           <screeninfo>Blog example</screeninfo>
  @@ -2796,19 +2496,15 @@
           </mediaobject>
         </screenshot>
   
  -      <para>
  -          The Blog example demonstrates the use of "pull"-style MVC,  where instead of using
  -          action listener methods to retrieve data and prepare the data for the view, the view 
  -          pulls data from components as it is being rendered.
  -      </para>
  +        <para> The Blog example demonstrates the use of "pull"-style MVC, where instead of using action listener methods
  +            to retrieve data and prepare the data for the view, the view pulls data from components as it is being
  +            rendered. </para>
         
         <section>
             <title>Using "pull"-style MVC</title>
         
  -      <para>
  -          This snippet from the <literal>index.xhtml</literal> facelets page displays a 
  -          list of recent blog entries:
  -      </para>
  +            <para> This snippet from the <literal>index.xhtml</literal> facelets page displays a list of recent blog
  +                entries: </para>
         
         <example>
         <programlisting><![CDATA[<h:dataTable value="#{blog.recentBlogEntries}" var="blogEntry" rows="3">
  @@ -2828,7 +2524,8 @@
            <p>
               [Posted on 
               <h:outputText value="#{blogEntry.date}">
  -               <f:convertDateTime timeZone="#{blog.timeZone}" locale="#{blog.locale}" type="both"/>
  +               <f:convertDateTime timeZone="#{blog.timeZone}" 
  +                                  locale="#{blog.locale}" type="both"/>
               </h:outputText>]
               &#160;
               <h:outputLink value="entry.seam">[Link]
  @@ -2840,14 +2537,11 @@
   </h:dataTable>]]></programlisting>
         </example>
   
  -      <para>
  -          If we navigate to this page from a bookmark, how does the data used by the 
  -          <literal>&lt;h:dataTable&gt;</literal> actually get initialized? Well, what
  -          happens is that the <literal>Blog</literal> is retrieved 
  -          lazily&mdash;"pulled"&mdash;when needed, by a Seam component named
  -          <literal>blog</literal>. This is the opposite flow of control to what is 
  -          usual in traditional web action-based frameworks like Struts.
  -      </para>
  +            <para> If we navigate to this page from a bookmark, how does the data used by the
  +                    <literal>&lt;h:dataTable&gt;</literal> actually get initialized? Well, what happens is that
  +                the <literal>Blog</literal> is retrieved lazily&mdash;"pulled"&mdash;when needed, by a Seam
  +                component named <literal>blog</literal>. This is the opposite flow of control to what is usual in
  +                traditional web action-based frameworks like Struts. </para>
         
           <example>
               <programlistingco>
  @@ -2874,42 +2568,33 @@
   }]]></programlisting>
               <calloutlist>
                   <callout arearefs="blog-seampc">
  -                    <para>
  -                        This component uses a <emphasis>seam-managed persistence context</emphasis>.
  -                        Unlike the other examples we've seen, this persistence context is managed
  -                        by Seam, instead of by the EJB3 container. The persistence context spans
  -                        the entire web request, allowing us to avoid any exceptions that occur
  -                        when accessing unfetched associations in the view.
  +                            <para> This component uses a <emphasis>seam-managed persistence context</emphasis>. Unlike
  +                                the other examples we've seen, this persistence context is managed by Seam, instead of
  +                                by the EJB3 container. The persistence context spans the entire web request, allowing us
  +                                to avoid any exceptions that occur when accessing unfetched associations in the view.
                       </para>
                   </callout>
                   <callout arearefs="blog-unwrap">
  -                    <para>
  -                        The <literal>@Unwrap</literal> annotation tells Seam to provide the return
  -                        value of the method&mdash;the <literal>Blog</literal>&mdash;instead of the
  -                        actual <literal>BlogService</literal> component to clients. This is the 
  -                        Seam <emphasis>manager component pattern</emphasis>.
  -                    </para>
  +                            <para> The <literal>@Unwrap</literal> annotation tells Seam to provide the return value of
  +                                the method&mdash;the <literal>Blog</literal>&mdash;instead of the actual
  +                                    <literal>BlogService</literal> component to clients. This is the Seam
  +                                    <emphasis>manager component pattern</emphasis>. </para>
                   </callout>
               </calloutlist>
               </programlistingco>
           </example>
           
  -      <para>
  -          This is good so far, but what about bookmarking the result of form submissions, such
  -          as a search results page?
  -      </para>
  +            <para> This is good so far, but what about bookmarking the result of form submissions, such as a search
  +                results page? </para>
           
         </section>
         
         <section>
             <title>Bookmarkable search results page</title>
             
  -      <para>
  -          The blog example has a tiny form in the top right of each page that
  -          allows the user to search for blog entries. This is defined in a 
  -          file, <literal>menu.xhtml</literal>, included by the facelets 
  -          template, <literal>template.xhtml</literal>:
  -      </para>
  +            <para> The blog example has a tiny form in the top right of each page that allows the user to search for
  +                blog entries. This is defined in a file, <literal>menu.xhtml</literal>, included by the facelets
  +                template, <literal>template.xhtml</literal>: </para>
         
         <example>
         <programlisting><![CDATA[<div id="search">
  @@ -2920,12 +2605,10 @@
   </div>]]></programlisting>
         </example>
           
  -      <para>
  -          To implement a bookmarkable search results page, we need to perform a browser redirect
  -          after processing the search form submission. Because we used the JSF view id as the 
  -          action outcome, Seam automatically redirects to the view id when the form is submitted.
  -          Alternatively, we could have defined a navigation rule like this:
  -      </para>
  +            <para> To implement a bookmarkable search results page, we need to perform a browser redirect after
  +                processing the search form submission. Because we used the JSF view id as the action outcome, Seam
  +                automatically redirects to the view id when the form is submitted. Alternatively, we could have defined
  +                a navigation rule like this: </para>
         
         <example>
         <programlisting><![CDATA[<navigation-rule>
  @@ -2937,9 +2620,7 @@
   </navigation-rule>]]></programlisting>
         </example>
         
  -      <para>
  -          Then the form would have looked like this:
  -      </para>
  +            <para> Then the form would have looked like this: </para>
           
         <example>
         <programlisting><![CDATA[<div id="search">
  @@ -2950,13 +2631,11 @@
   </div>]]></programlisting>
         </example>
         
  -      <para>
  -          But when we redirect, we need to include the values submitted with the form as
  -          request parameters, to get a bookmarkable URL like 
  -          <literal>http://localhost:8080/seam-blog/search.seam?searchPattern=seam</literal>.
  -          JSF does not provide an easy way to do this, but Seam does. We use a Seam
  -          <emphasis>page parameter</emphasis>, defined in <literal>WEB-INF/pages.xml</literal>:
  -      </para>
  +            <para> But when we redirect, we need to include the values submitted with the form as request parameters, to
  +                get a bookmarkable URL like
  +                <literal>http://localhost:8080/seam-blog/search.seam?searchPattern=seam</literal>. JSF does not provide
  +                an easy way to do this, but Seam does. We use a Seam <emphasis>page parameter</emphasis>, defined in
  +                    <literal>WEB-INF/pages.xml</literal>: </para>
         
         <example>
         <programlisting><![CDATA[<pages>
  @@ -2967,16 +2646,11 @@
   </pages>]]></programlisting>
         </example>
         
  -      <para>
  -          This tells Seam to include the value of <literal>#{searchService.searchPattern}</literal>
  -          as a request parameter named <literal>searchPattern</literal> when redirecting to
  -          the page, and then re-apply the value of that parameter to the model before rendering
  -          the page.
  -      </para>
  +            <para> This tells Seam to include the value of <literal>#{searchService.searchPattern}</literal> as a
  +                request parameter named <literal>searchPattern</literal> when redirecting to the page, and then re-apply
  +                the value of that parameter to the model before rendering the page. </para>
               
  -      <para>
  -          The redirect takes us to the <literal>search.xhtml</literal> page:
  -      </para>
  +            <para> The redirect takes us to the <literal>search.xhtml</literal> page: </para>
         
         <example>
         <programlisting><![CDATA[<h:dataTable value="#{searchResults}" var="blogEntry">
  @@ -2995,9 +2669,7 @@
   </h:dataTable>]]></programlisting>
         </example>
         
  -      <para>
  -          Which again uses "pull"-style MVC to retrieve the actual search results:
  -      </para>
  +            <para> Which again uses "pull"-style MVC to retrieve the actual search results: </para>
         
         <example>
         <programlisting><![CDATA[@Name("searchService")
  @@ -3018,7 +2690,9 @@
         }
         else
         {
  -         return entityManager.createQuery("select be from BlogEntry be where lower(be.title) like :searchPattern or lower(be.body) like :searchPattern order by be.date desc")
  +         return entityManager.createQuery("select be from BlogEntry be "" + 
  +                      "where lower(be.title) like :searchPattern " + 
  +                      "lower(be.body) like :searchPattern order by be.date desc")
                  .setParameter( "searchPattern", getSqlSearchPattern() )
                  .setMaxResults(100)
                  .getResultList();
  @@ -3027,7 +2701,8 @@
   
      private String getSqlSearchPattern()
      {
  -      return searchPattern==null ? "" : '%' + searchPattern.toLowerCase().replace('*', '%').replace('?', '_') + '%';
  +      return searchPattern==null ? "" :
  +             '%' + searchPattern.toLowerCase().replace('*', '%').replace('?', '_') + '%';
      }
   
      public String getSearchPattern()
  @@ -3048,17 +2723,13 @@
         <section>
             <title>Using "push"-style MVC in a RESTful application</title>
         
  -      <para>
  -          Very occasionally, it makes more sense to use push-style MVC for processing RESTful pages,
  -          and so Seam provides the notion of a <emphasis>page action</emphasis>. The Blog example uses
  -          a page action for the blog entry page, <literal>entry.xhtml</literal>. Note that this is a
  -          little bit contrived, it would have been easier to use pull-style MVC here as well.
  -      </para>
  +            <para> Very occasionally, it makes more sense to use push-style MVC for processing RESTful pages, and so
  +                Seam provides the notion of a <emphasis>page action</emphasis>. The Blog example uses a page action for
  +                the blog entry page, <literal>entry.xhtml</literal>. Note that this is a little bit contrived, it would
  +                have been easier to use pull-style MVC here as well. </para>
         
  -      <para>
  -          The <literal>entryAction</literal> component works much like an action class in a traditional
  -          push-MVC action-oriented framework like Struts:
  -      </para>
  +            <para> The <literal>entryAction</literal> component works much like an action class in a traditional
  +                push-MVC action-oriented framework like Struts: </para>
         
         <example>
         <programlisting><![CDATA[@Name("entryAction")
  @@ -3080,9 +2751,7 @@
   }]]></programlisting>
         </example>
         
  -      <para>
  -          Page actions are also declared in <literal>pages.xml</literal>:
  -      </para>
  +            <para> Page actions are also declared in <literal>pages.xml</literal>: </para>
         
         <example>
         <programlisting><![CDATA[<pages>
  @@ -3099,19 +2768,15 @@
   </pages>]]></programlisting>
         </example>
         
  -      <para>
  -          Notice that the example is using page actions for some other functionality&mdash;the
  -          login challenge, and the pageview counter. Also notice the use of a parameter in
  -          the page action method binding. This is not a standard feature of JSF EL, but Seam
  -          lets you use it, not just for page actions, but also in JSF method bindings.
  -      </para>
  -      
  -      <para>
  -          When the <literal>entry.xhtml</literal> page is requested, Seam first binds the page parameter
  -          <literal>blogEntryId</literal> to the model, then runs the page action, which retrieves the 
  -          needed data&mdash;the <literal>blogEntry</literal>&mdash;and places it in the Seam event context. 
  -          Finally, the following is rendered:          
  -      </para>
  +            <para> Notice that the example is using page actions for some other functionality&mdash;the login
  +                challenge, and the pageview counter. Also notice the use of a parameter in the page action method
  +                binding. This is not a standard feature of JSF EL, but Seam lets you use it, not just for page actions,
  +                but also in JSF method bindings. </para>
  +
  +            <para> When the <literal>entry.xhtml</literal> page is requested, Seam first binds the page parameter
  +                    <literal>blogEntryId</literal> to the model, then runs the page action, which retrieves the needed
  +                data&mdash;the <literal>blogEntry</literal>&mdash;and places it in the Seam event context.
  +                Finally, the following is rendered: </para>
         
         <example>
         <programlisting><![CDATA[<div class="blogEntry">
  @@ -3122,17 +2787,16 @@
      <p>
         [Posted on&#160;
         <h:outputText value="#{blogEntry.date}">
  -         <f:convertDateTime timezone="#{blog.timeZone}" locale="#{blog.locale}" type="both"/>
  +         <f:convertDateTime timezone="#{blog.timeZone}" 
  +                            locale="#{blog.locale}" type="both"/>
         </h:outputText>]
      </p>
   </div>]]></programlisting>
         </example>
         
  -      <para>
  -          If the blog entry is not found in the database, the <literal>EntryNotFoundException</literal>
  -          exception is thrown. We want this exception to result in a 404 error, not a 505, so we
  -          annotate the exception class:
  -      </para>
  +            <para> If the blog entry is not found in the database, the <literal>EntryNotFoundException</literal>
  +                exception is thrown. We want this exception to result in a 404 error, not a 505, so we annotate the
  +                exception class: </para>
         
         <example>
         <programlisting><![CDATA[@ApplicationException(rollback=true)
  @@ -3146,9 +2810,7 @@
   }]]></programlisting>
         </example>
   
  -      <para>
  -          An alternative implementation of the example does not use the parameter in the method binding:
  -      </para>
  +            <para> An alternative implementation of the example does not use the parameter in the method binding: </para>
         
         <example>
         <programlisting><![CDATA[@Name("entryAction")
  @@ -3180,71 +2842,10 @@
   </pages>]]></programlisting>
         </example>
         
  -      <para>
  -          It is a matter of taste which implementation you prefer.
  -      </para>
  +            <para> It is a matter of taste which implementation you prefer. </para>
   
         </section>
               
     </section>
     
  -  <section>
  -      <title>Running the Seam examples in JBoss using the JSF 1.2 RI</title>
  -      <para>
  -          JBoss AS 4.0 ships with the Apache MyFaces implementation of JSF 1.1. After many months of 
  -          waiting, there is <emphasis>still</emphasis> no implementation of JSF 1.2 from MyFaces. 
  -          For this and other reasons, JBoss AS 4.2 will embed the JSF 1.2 Reference Implementation
  -          by default. Soon after the release of 4.2, we will migrate the Seam examples to JSF 1.2.
  -      </para>
  -      <para>
  -          For those who can't wait, Seam is already compatible with JSF 1.2, and it's easy to get
  -          the Seam examples running with JSF 1.2 in JBoss 4.0.5. Let's start with the famous booking
  -          example:
  -      </para>
  -      <itemizedlist>
  -          <listitem>
  -              <para>
  -                  copy <literal>jsf-api.jar</literal>, <literal>jsf-impl.jar</literal>, 
  -                  <literal>el-api.jar</literal>, <literal>el-ri.jar</literal> to
  -                  <literal>server/default/deploy/tomcat/jbossweb-tomcat55.sar/jsf-libs</literal>.
  -              </para>
  -          </listitem>
  -          <listitem>
  -              <para>
  -                  delete <literal>myfaces-api.jar</literal> and <literal>myfaces-impl.jar</literal> 
  -                  from <literal>server/default/deploy/tomcat/jbossweb-tomcat55.sar/jsf-libs</literal>.
  -              </para>
  -          </listitem>
  -          <listitem>
  -              <para>
  -                  edit <literal>server/default/deploy/tomcat/jbossweb-tomcat55.sar/conf/web.xml</literal>, 
  -                  replacing <literal>myfaces-impl.jar</literal> with <literal>jsf-impl.jar</literal>.
  -              </para>
  -          </listitem>
  -          <listitem>
  -              <para>
  -                  edit <literal>examples/booking/resources/WEB-INF/web.xml</literal>, deleting the MyFaces 
  -                  listener, uncommenting the RI listener
  -              </para>
  -          </listitem>
  -          <listitem>
  -              <para>
  -                  edit <literal>examples/booking/resources/WEB-INF/faces-config.xml</literal>, uncommenting 
  -                  the lines that install the <literal>SeamELResolver</literal> using the new JSF 1.2 XML
  -                  schema declaration.
  -              </para>
  -          </listitem>
  -          <listitem>
  -              <para>
  -                  edit <literal>examples/booking/resources/META-INF/application.xml</literal>, deleting the
  -                  lines that declare <literal>el-api.jar</literal> and <literal>el-impl.jar</literal> as Java
  -                  modules.
  -              </para>
  -          </listitem>
  -      </itemizedlist>
  -      <para>
  -          Restart JBoss, and type <literal>ant</literal> in the <literal>examples/booking</literal> directory.
  -      </para>
  -  </section>
  -
   </chapter>
  
  
  



More information about the jboss-cvs-commits mailing list