You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by co...@apache.org on 2003/04/21 07:34:48 UTC

cvs commit: cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath Cart.xml Category.xml Checkout.xml ConfirmOrder.xml IncludeBottom.xml IncludeMyList.xml IncludeQuickHeader.xml IncludeTop.xml Item.xml NewAccountForm.xml NewOrderForm.xml Product.xml SearchProducts.xml ShippingForm.xml SignonForm.xml ViewOrder.xml index.xml

coliver     2003/04/20 22:34:48

  Modified:    src/scratchpad/webapp/samples/petstore sitemap.xmap
               src/scratchpad/webapp/samples/petstore/view/jexl Cart.xml
                        Category.xml Checkout.xml ConfirmOrder.xml
                        IncludeBottom.xml IncludeMyList.xml
                        IncludeQuickHeader.xml IncludeTop.xml Item.xml
                        NewAccountForm.xml NewOrderForm.xml Product.xml
                        SearchProducts.xml ShippingForm.xml SignonForm.xml
                        ViewOrder.xml index.xml
               src/scratchpad/webapp/samples/petstore/view/jxpath Cart.xml
                        Category.xml Checkout.xml ConfirmOrder.xml
                        IncludeBottom.xml IncludeMyList.xml
                        IncludeQuickHeader.xml IncludeTop.xml Item.xml
                        NewAccountForm.xml NewOrderForm.xml Product.xml
                        SearchProducts.xml ShippingForm.xml SignonForm.xml
                        ViewOrder.xml index.xml
  Added:       src/scratchpad/src/org/apache/cocoon/generation
                        JXTemplate.java
  Removed:     src/scratchpad/src/org/apache/cocoon/generation
                        JXPathTemplate.java JexlTemplate.java
               src/scratchpad/src/org/apache/cocoon/transformation
                        JXPathTransformer.java JexlTransformer.java
  Log:
  Blasted JXPathTransformer, JexlTransformer, JXPathTemplate, and JexlTemplate in favor of new JXTemplate generator which supports both JXPath and Jexl expression languages. Updated Petstore sample accordingly
  
  Revision  Changes    Path
  1.1                  cocoon-2.1/src/scratchpad/src/org/apache/cocoon/generation/JXTemplate.java
  
  Index: JXTemplate.java
  ===================================================================
  /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.generation;
  
  import java.beans.PropertyDescriptor;
  import java.io.CharArrayReader;
  import java.io.IOException;
  import java.io.StringReader;
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.Stack;
  
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.components.flow.WebContinuation;
  import org.apache.cocoon.components.source.SourceUtil;
  import org.apache.cocoon.environment.Environment;
  import org.apache.cocoon.environment.ObjectModelHelper;
  import org.apache.cocoon.environment.Request;
  import org.apache.cocoon.environment.Response;
  import org.apache.cocoon.environment.SourceResolver;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.apache.cocoon.xml.dom.DOMBuilder;
  import org.apache.cocoon.xml.dom.DOMStreamer;
  import org.apache.commons.jexl.ExpressionFactory;
  import org.apache.commons.jexl.JexlContext;
  import org.apache.commons.jexl.util.introspection.Info;
  import org.apache.commons.jexl.util.introspection.UberspectImpl;
  import org.apache.commons.jexl.util.introspection.VelMethod;
  import org.apache.commons.jexl.util.introspection.VelPropertyGet;
  import org.apache.commons.jexl.util.introspection.VelPropertySet;
  import org.apache.commons.jxpath.CompiledExpression;
  import org.apache.commons.jxpath.DynamicPropertyHandler;
  import org.apache.commons.jxpath.JXPathBeanInfo;
  import org.apache.commons.jxpath.JXPathContext;
  import org.apache.commons.jxpath.JXPathContextFactory;
  import org.apache.commons.jxpath.JXPathIntrospector;
  import org.apache.commons.jxpath.Pointer;
  import org.apache.commons.jxpath.Variables;
  import org.apache.excalibur.source.Source;
  import org.apache.excalibur.source.SourceException;
  import org.mozilla.javascript.Context;
  import org.mozilla.javascript.JavaScriptException;
  import org.mozilla.javascript.NativeArray;
  import org.mozilla.javascript.ScriptRuntime;
  import org.mozilla.javascript.Scriptable;
  import org.mozilla.javascript.ScriptableObject;
  import org.mozilla.javascript.Undefined;
  import org.mozilla.javascript.Wrapper;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.xml.sax.Attributes;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.Locator;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.ext.LexicalHandler;
  import org.xml.sax.helpers.AttributesImpl;
  import org.xml.sax.helpers.LocatorImpl;
  /**
   *  <p>(<em>JX</em> for <a href="http://jakarta.apache.org/commons/jxpath">Apache <em>JX</em>Path</a> and <a href="http://jakarta.apache.org/commons/jexl">Apache <em>J</em>e<em>x</em>l</a>)</p>
   *  <p>Provides a generic page template with embedded JSTL and XPath expression substitution
   *  to access data sent by Cocoon Flowscripts.</p>
   *  The embedded expression language allows a page author to access an 
   *  object using a simplified syntax such as
   *  <p><pre>
   *  &lt;site signOn="${accountForm.signOn}"&gt;
   *  </pre></p>
   * <p>Embedded JSTL expressions are contained in <code>${}</code>.</p>
   * <p>Embedded XPath expressions are contained in <code>#{}</code>.</p>
   * <p>Note that since this generator uses <a href="http://jakarta.apache.org/commons/jxpath">Apache JXPath</a> and <a href="http://jakarta.apache.org/commons/jexl">Apache Jexl</a>, the referenced 
   * objects may be Java Beans, DOM, JDOM, or JavaScript objects from a 
   * Flowscript. In addition the following implicit objects are available as
   * both XPath and JSTL variables:</p>
   * <p>
   * <dl>
   * <dt><code>request</code> (<code>org.apache.cocoon.environment.Request</code>)</dt>
   * <dd>The Cocoon current request</dd>
   *
   * <dt><code>response</code> (<code>org.apache.cocoon.environment.Response</code>)</dt>
   * <dd>The Cocoon response associated with the current request</dd>
   *
   * <dt><code>session</code> (<code>org.apache.cocoon.environment.Session</code>)</dt>
   * <dd>The Cocoon session associated with the current request</dd>
   *
   * <dt><code>context</code> (<code>org.apache.cocoon.environment.Context</code>)</dt>
   * <dd>The Cocoon context associated with the current request</dd>
   *
   * <dt><code>parameters</code> (<code>org.apache.avalon.framework.parameters.Parameters</code>)</dt>
   * <dd>Any parameters passed to the generator in the pipeline</dd>
   * </dl>
   * </p>
   *
   * The current Web Continuation from the Flowscript 
   * is also available as a variable named <code>continuation</code>. You would 
   * typically access its <code>id</code>:
   * <p><pre>
   *    &lt;form action="${continuation.id}"&gt;
   * </pre></p>
   * <p>You can also reach previous continuations by using the <code>getContinuation()</code> function:</p>
   * <p><pre>
   *     &lt;form action="${continuation.getContinuation(1).id}" >
   * </pre></p>
   * <p>
   * <p>The <code>template</code> tag defines a new template:</p><pre>
   *    &lt;template&gt;
   *        body
   *    &lt;/template&gt;
   * </pre></p>
   * <p>The <code>import</code> tag allows you to include another template within the current template. The content of the imported template is compiled and will be executed in place of the <code>import</code> tag:</p><pre>
   *    &lt;import uri="URI" [context="Expression"]/&gt;
   * </pre></p><p>The Cocoon source resolver is used to resolve <code>uri</code>. If <code>context</code> is present, then its value is used as the context for evaluating the imported template, otherwise the current context is used.</p>
   * <p>The <code>set</code> tag creates a local alias of an object. The <code>var</code> attribute specifies the name of a variable to assign the object to. The <code>value</code> attribute specifies the object (defaults to <code>body</code> if not present):</p><pre>
   *    &lt;set var="Name" [value="Value"]&gt;
   *        [body]
   *    &lt;/set&gt;
   * </pre></p><p>If used within a <code>macro</code> definition (see below) variables created by <code>set</code> are only visible within the body of the <code>macro</code>.</p>
   * <p>The <code>if</code> tag allows the conditional execution of its body 
   * according to value of a <code>test</code> attribute:</p>
   * <p><pre>
   *   &lt;if test="Expression"&gt;
   *       body
   *   &lt;/if&gt;
   * </pre></p>
   * <p>The <code>choose</code> tag performs conditional block execution by the 
   * embedded <code>when</code> sub tags. It renders the body of the first 
   * <code>when</code> tag whose <code>test</code> condition evaluates to true. 
   * If none of the <code>test</code> conditions of nested <code>when</code> tags
   * evaluate to <code>true</code>, then the body of an <code>otherwise</code> 
   * tag is evaluated, if present:</p>
   * <p><pre>
   *  &lt;choose&gt;
   *    &lt;when test="Expression"&gt;
   *       body
   *    &lt;/when&gt;
   *    &lt;otherwise&gt;
   *       body
   *    &lt;/otherwise&gt;
   *  &lt;/choose&gt;
   * </pre></p>
   * <p>The <code>out</code> tag evaluates an expression and outputs 
   * the result of the evaluation:</p>
   * <p><pre>
   * &lt;out value="Expression"/&gt;
   * </pre></p>
   * <p>The <code>forEach</code> tag allows you to iterate over a collection 
   * of objects:<p>
   * <p><pre>
   *   &lt;forEach [var="Name"] [items="Expression"] [begin="Number"] [end="Number"] [step="Number"]&gt;
   *     body
   *  &lt;/forEach&gt;
   * </pre></p>
   * <p>The <code>items</code> attribute specifies the list of items to iterate over. The <code>var</code> attribute specifies the name of a variable to hold the current item. The <code>begin</code> attribute specifies the element to start with 
   * (<code>0</code> = first item, <code>1</code> = second item, ...). 
   * If unspecified it defaults to <code>0</code>. The <code>end</code> 
   * attribute specifies the item to end with (<code>0</code> = first item, 
   * <code>1</code> = second item, ...). If unspecified it defaults to the last item in the list. Every <code>step</code> items are
   * processed (defaults to <code>1</code> if <code>step</code> is absent). Either <code>items</code> or both <code>begin</code> and <code>end</code> must be present.<p>
   *
   * <p>The <code>macro</code> tag allows you define a new custom tag.</p><p><pre>
   * &lt;macro name="Name" [targetNamespace="Namespace"]&gt;
   *   &lt;parameter name="Name" [optional="Boolean"] [default="Value"]/&gt;*
   *   body
   * &lt/macro&gt;
   * </pre></p>
   *<p> For example:</p><p><pre>
   * &lt;c:macro name="d"&gt;
   *   &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
   * &lt;/c:macro&gt;
   * </pre></p>
   * <p>The tag being defined in this example is <code>&lt;d&gt;</code> and it 
   * can be used like any other tag:</p><p><pre>
   *   &lt;d/&gt;
   * </pre></p>
   * <p>However, when this tag is used it will be replaced with a row containing a single empty data cell.</p>
   * <p> When such a tag is used, the attributes and content of the tag become available as variables in the body of the <code>macro</code>'s definition, for example:</p><p><pre>
   * &lt;c:macro name="tablerows"&gt;
   *   &lt;c:parameter name="list"/&gt;
   *   &lt;c:parameter name="color"/&gt;
   *   &lt;c:forEach var="item" items=${list}&gt;
   *     &lt;tr&gt;&lt;td bgcolor="${color}"&gt;${item}&lt;/td&gt;&lt;/tr&gt;
   *   &lt;/c:forEach&gt;
   * &lt;/c:macro&gt;
   * </pre></p>
   * <p>The <code>parameter</code> tags in the macro definition define formal parameters, which are replaced with the actual attribute values of the tag when it is used. The content of the tag is also available as a special variable <code>${body}</code>.</p><p>Assuming you had this code in your flowscript:</p>
   *    <code>var greatlakes = ["Superior", "Michigan", "Huron", "Erie", "Ontario"];</code></p><p><code> sendPage(uri, {greatlakes: greatlakes});</code>
   * </p><p>and a template like this:</p><p><pre>
   * &lt;table&gt;
   *    &lt;tablerows list="${greatlakes}" color="blue"/&gt;
   * &lt;/table&gt;
   * </pre></p>
   * <p>When the <code>tablerows</code> tag is used in this situation the following output would be generated:
   * </p>
   *<p><pre>
   * &lt;table&gt;
   *   &lt;tr&gt;&lt;td bgcolor="blue"&gt;Superior&lt;/td&gt;&lt;/tr&gt;
   *   &lt;tr&gt;&lt;td bgcolor="blue"&gt;Michigan&lt;/td&gt;&lt;/tr&gt;
   *   &lt;tr&gt;&lt;td bgcolor="blue"&gt;Huron&lt;/td&gt;&lt;/tr&gt;
   *   &lt;tr&gt;&lt;td bgcolor="blue"&gt;Erie&lt;/td&gt;&lt;/tr&gt;
   *   &lt;tr&gt;&lt;td bgcolor="blue"&gt;Ontario&lt;/td&gt;&lt;/tr&gt;
   * &lt;/table&gt;
   * </pre></p>
   */
  
  public class JXTemplate extends AbstractGenerator {
  
      private static final JXPathContextFactory 
          jxpathContextFactory = JXPathContextFactory.newInstance();
  
      private static final char[] EMPTY_CHARS = "".toCharArray();
  
      private static final Attributes EMPTY_ATTRS = new AttributesImpl();
  
      private static final Iterator EMPTY_ITER = new Iterator() {
              public boolean hasNext() {
                  return false;
              }
              public Object next() {
                  return null;
              }
              public void remove() {
              }
          };
  
      private static final Iterator NULL_ITER = new Iterator() {
              public boolean hasNext() {
                  return true;
              }
              public Object next() {
                  return null;
              }
              public void remove() {
              }
          };
  
      /**
       * Jexl Introspector that supports Rhino JavaScript objects
       * as well as Java Objects
       */
      static class JSIntrospector extends UberspectImpl {
          
          static class JSMethod implements VelMethod {
              
              Scriptable scope;
              String name;
              
              public JSMethod(Scriptable scope, String name) {
                  this.scope = scope;
                  this.name = name;
              }
              
              public Object invoke(Object thisArg, Object[] args)
                  throws Exception {
                  Context cx = Context.enter();
                  try {
                      Object result; 
                      Scriptable thisObj;
                      if (!(thisArg instanceof Scriptable)) {
                          thisObj = Context.toObject(thisArg, scope);
                      } else {
                          thisObj = (Scriptable)thisArg;
                      }
                      result = ScriptableObject.getProperty(thisObj, name);
                      Object[] newArgs = null;
                      if (args != null) {
                          newArgs = new Object[args.length];
                          for (int i = 0; i < args.length; i++) {
                              newArgs[i] = args[i];
                              if (args[i] != null && 
                                  !(args[i] instanceof Number) &&
                                  !(args[i] instanceof Boolean) &&
                                  !(args[i] instanceof String) &&
                                  !(args[i] instanceof Scriptable)) {
                                  newArgs[i] = Context.toObject(args[i], scope);
                              }
                          }
                      }
                      result = ScriptRuntime.call(cx, result, thisObj, 
                                                  newArgs, scope);
                      if (result == Undefined.instance ||
                          result == ScriptableObject.NOT_FOUND) {
                          result = null;
                      } else while (result instanceof Wrapper) {
                          result = ((Wrapper)result).unwrap();
                      }
                      return result;
                  } catch (JavaScriptException e) {
                      throw new java.lang.reflect.InvocationTargetException(e);
                  } finally {
                      Context.exit();
                  }
              }
              
              public boolean isCacheable() {
                  return false;
              }
              
              public String getMethodName() {
                  return name;
              }
              
              public Class getReturnType() {
                  return Object.class;
              }
              
          }
          
          static class JSPropertyGet implements VelPropertyGet {
              
              Scriptable scope;
              String name;
              
              public JSPropertyGet(Scriptable scope, String name) {
                  this.scope = scope;
                  this.name = name;
              }
              
              public Object invoke(Object thisArg) throws Exception {
                  Context.enter();
                  try {
                      Scriptable thisObj;
                      if (!(thisArg instanceof Scriptable)) {
                          thisObj = Context.toObject(thisArg, scope);
                      } else {
                          thisObj = (Scriptable)thisArg;
                      }
                      Object result = ScriptableObject.getProperty(thisObj, name);
                      if (result == Undefined.instance || 
                          result == ScriptableObject.NOT_FOUND) {
                          result = null;
                      } else while (result instanceof Wrapper) {
                          result = ((Wrapper)result).unwrap();
                      }
                      return result;
                  } finally {
                      Context.exit();
                  }
              }
              
              public boolean isCacheable() {
                  return false;
              }
              
              public String getMethodName() {
                  return name;
              }
              
          }
          
          static class JSPropertySet implements VelPropertySet {
              
              Scriptable scope;
              String name;
              
              public JSPropertySet(Scriptable scope, String name) {
                  this.scope = scope;
                  this.name = name;
              }
              
              public Object invoke(Object thisArg, Object rhs) throws Exception {
                  Context.enter();
                  try {
                      Scriptable thisObj;
                      Object arg = rhs;
                      if (!(thisArg instanceof Scriptable)) {
                          thisObj = Context.toObject(thisArg, scope);
                      } else {
                          thisObj = (Scriptable)thisArg;
                      }
                      if (arg != null && 
                          !(arg instanceof Number) &&
                          !(arg instanceof Boolean) &&
                          !(arg instanceof String) &&
                          !(arg instanceof Scriptable)) {
                          arg = Context.toObject(arg, scope);
                      }
                      ScriptableObject.putProperty(thisObj, name, arg);
                      return rhs;
                  } finally {
                      Context.exit();
                  }
              }
              
              public boolean isCacheable() {
                  return false;
              }
              
              public String getMethodName() {
                  return name;        
              }
          }
          
          static class NativeArrayIterator implements Iterator {
              
              NativeArray arr;
              int index;
              
              public NativeArrayIterator(NativeArray arr) {
                  this.arr = arr;
                  this.index = 0;
              }
              
              public boolean hasNext() {
                  return index < (int)arr.jsGet_length();
              }
              
              public Object next() {
                  Context.enter();
                  try {
                      Object result = arr.get(index++, arr);
                      if (result == Undefined.instance ||
                          result == ScriptableObject.NOT_FOUND) {
                          result = null;
                      } else while (result instanceof Wrapper) {
                          result = ((Wrapper)result).unwrap();
                      }
                      return result;
                  } finally {
                      Context.exit();
                  }
              }
              
              public void remove() {
                  arr.delete(index);
              }
          }
          
          static class ScriptableIterator implements Iterator {
              
              Scriptable scope;
              Object[] ids;
              int index;
              
              public ScriptableIterator(Scriptable scope) {
                  this.scope = scope;
                  this.ids = scope.getIds();
                  this.index = 0;
              }
              
              public boolean hasNext() {
                  return index < ids.length;
              }
              
              public Object next() {
                  Context.enter();
                  try {
                      Object result = 
                          ScriptableObject.getProperty(scope, 
                                                       ids[index++].toString());
                      if (result == Undefined.instance ||
                          result == ScriptableObject.NOT_FOUND) {
                          result = null;
                      } else while (result instanceof Wrapper) {
                          result = ((Wrapper)result).unwrap();
                      }
                      return result;
                  } finally {
                      Context.exit();
                  }
              }
              
              public void remove() {
                  Context.enter();
                  try {
                      scope.delete(ids[index].toString());
                  } finally {
                      Context.exit();
                  }
              }
          }
          
          public Iterator getIterator(Object obj, Info i)
              throws Exception {
              if (!(obj instanceof Scriptable)) {
                  return super.getIterator(obj, i);
              }
              if (obj instanceof NativeArray) {
                  return new NativeArrayIterator((NativeArray)obj);
              }
              return new ScriptableIterator((Scriptable)obj);
          }
          
          public VelMethod getMethod(Object obj, String methodName, 
                                     Object[] args, Info i)
              throws Exception {
              if (!(obj instanceof Scriptable)) {
                  return super.getMethod(obj, methodName, args, i);
              }
              return new JSMethod((Scriptable)obj, methodName);
          }
          
          public VelPropertyGet getPropertyGet(Object obj, String identifier, 
                                               Info i)
              throws Exception {
              if (!(obj instanceof Scriptable)) {
                  return super.getPropertyGet(obj, identifier, i);
              }
              return new JSPropertyGet((Scriptable)obj, identifier);
          }
          
          public VelPropertySet getPropertySet(Object obj, String identifier, 
                                               Object arg, Info i)
              throws Exception {
              if (!(obj instanceof Scriptable)) {
                  return super.getPropertySet(obj, identifier, arg, i);
              }
              return new JSPropertySet((Scriptable)obj, identifier);
          }
      }
  
      static class MyJexlContext 
          extends HashMap implements JexlContext {
          public Map getVars() {
              return this;
          }
          public void setVars(Map map) {
              putAll(map);
          }
          public Object get(Object key) {
              Object result = super.get(key);
              if (result != null) {
                  return result;
              }
              MyJexlContext c = closure;
              for (; c != null; c = c.closure) {
                  result = c.get(key);
                  if (result != null) {
                      return result;
                  }
              }
              return result;
          }
          MyJexlContext closure;
          MyJexlContext() {
          }
          MyJexlContext(MyJexlContext closure) {
              this.closure = closure;
          }
      }
  
      static class MyVariables implements Variables {
  
          Map localVariables = new HashMap();
  
          static final String[] VARIABLES = new String[] {
              "continuation",
              "flowContext",
              "request",
              "response",
              "context",
              "session",
              "parameters"
          };
  
          Object bean, kont, request, response,
              session, context, parameters;
  
          MyVariables(Object bean, WebContinuation kont,
                      Request request, Response response,
                      org.apache.cocoon.environment.Context context,
                      Parameters parameters) {
              this.bean = bean;
              this.kont = kont;
              this.request = request;
              this.session = request.getSession(false);
              this.response = response;
              this.context = context;
              this.parameters = parameters;
          }
  
          public boolean isDeclaredVariable(String varName) {
              for (int i = 0; i < VARIABLES.length; i++) {
                  if (varName.equals(VARIABLES[i])) {
                      return true;
                  }
              }
              return localVariables.containsKey(varName);
          }
          
          public Object getVariable(String varName) {
              if (varName.equals("continuation")) {
                  return kont;
              } else if (varName.equals("flowContext")) {
                  return bean;
              } else if (varName.equals("request")) {
                  return request;
              } else if (varName.equals("response")) {
                  return response;
              } else if (varName.equals("session")) {
                  return session;
              } else if (varName.equals("context")) {
                  return context;
              } else if (varName.equals("parameters")) {
                  return parameters;
              }
              return localVariables.get(varName);
          }
          
          public void declareVariable(String varName, Object value) {
              localVariables.put(varName, value);
          }
          
          public void undeclareVariable(String varName) {
              localVariables.remove(varName);
          }
      }
  
      static {
          // Hack: there's no _nice_ way to add my introspector to Jexl right now
          try {
              Field field = 
                  org.apache.commons.jexl.util.Introspector.class.getDeclaredField("uberSpect");
              field.setAccessible(true);
              field.set(null, new JSIntrospector());
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
  
      final static String NS = 
          "http://cocoon.apache.org/generation/jx/1.0";
  
      final static String TEMPLATE = "template";
      final static String FOR_EACH = "forEach";
      final static String IF = "if";
      final static String CHOOSE = "choose";
      final static String WHEN = "when";
      final static String OTHERWISE = "otherwise";
      final static String OUT = "out";
      final static String IMPORT = "import";
      final static String SET = "set";
      final static String MACRO = "macro";
      final static String PARAMETER = "parameter";
  
  
      /**
       * Compile a single Jexl expr (contained in ${}) or XPath expression
       * (contained in #{}) 
       */
  
      private Object compileExpr(String expr, String errorPrefix, 
                                 Locator location) throws SAXParseException {
          try {
              return compileExpr(expr);
          } catch (Exception exc) {
              throw new SAXParseException(errorPrefix + exc.getMessage(),
                                          location, exc);
          } catch (Error err) {
              throw new SAXParseException(errorPrefix + err.getMessage(),
                                          location, null);
          }
      }
  
      private Object compileExpr(String inStr) throws Exception {
          try {
              if (inStr == null) return null;
              StringReader in = new StringReader(inStr.trim());
              int ch;
              StringBuffer expr = new StringBuffer();
              boolean xpath = false;
              boolean inExpr = false;
              while ((ch = in.read()) != -1) {
                  char c = (char)ch;
                  if (inExpr) {
                      if (c == '\\') {
                          ch = in.read();
                          if (ch == -1) {
                              expr.append('\\');
                          } else {
                              expr.append((char)ch);
                          }
                      } else if (c == '}') {
                          String str = expr.toString();
                          return compile(str, xpath);
                      } else {
                          expr.append(c);
                      }
                  } else {
                      if (c == '$' || c == '#') {
                          ch = in.read();
                          if (ch == '{') {
                              inExpr = true;
                              xpath = c == '#';
                              continue;
                          }
                      }
                      // hack: invalid expression?
                      // just return the original and swallow exception
                      return inStr;
                  }
              }
          } catch (IOException ignored) {
              ignored.printStackTrace();
          }
          return inStr;
      }
  
      private Object compile(final String variable, boolean xpath) 
          throws Exception {
          if (xpath) {
              return JXPathContext.compile(variable);
          } else {
              return ExpressionFactory.createExpression(variable);
          }
      }
  
      private Object getValue(Object expr, JexlContext jexlContext,
                              JXPathContext jxpathContext) 
          throws Exception {
          if (expr instanceof CompiledExpression) {
              CompiledExpression e = (CompiledExpression)expr;
              return e.getValue(jxpathContext);
          } else if (expr instanceof org.apache.commons.jexl.Expression) {
              org.apache.commons.jexl.Expression e = 
                  (org.apache.commons.jexl.Expression)expr;
              return e.evaluate(jexlContext);
          }
          return expr;
      }
  
      private Object getNode(Object expr, JexlContext jexlContext,
                              JXPathContext jxpathContext) 
          throws Exception {
          if (expr instanceof CompiledExpression) {
              CompiledExpression e = (CompiledExpression)expr;
              return e.getPointer(jxpathContext, "").getNode();
          } else if (expr instanceof org.apache.commons.jexl.Expression) {
              org.apache.commons.jexl.Expression e = 
                  (org.apache.commons.jexl.Expression)expr;
              return e.evaluate(jexlContext);
          }
          return expr;
      }
  
      class Event {
          final Locator location;
          Event next;
          Event(Locator location) {
              this.location = new LocatorImpl(location);
          }
  
          public String locationString() {
              String result = "";
              String systemId = location.getSystemId();
              if (systemId != null) {
                  result += systemId + ", ";
              }
              result += "Line " + location.getLineNumber();
              int col = location.getColumnNumber();
              if (col > 0) {
                  result += "." + col;
              }
              return result;
          }
          
      }
  
      class TextEvent extends Event {
          TextEvent(Locator location, 
                    char[] chars, int start, int length) 
              throws SAXException {
              super(location);
              StringBuffer buf = new StringBuffer();
              CharArrayReader in = new CharArrayReader(chars, start, length);
              int ch;
              boolean inExpr = false;
              boolean xpath = false;
              try {
                  top: while ((ch = in.read()) != -1) {
                      char c = (char)ch;
                      processChar: while (true) {
                          if (inExpr) {
                              if (c == '\\') {
                                  ch = in.read();
                                  if (ch == -1) {
                                      buf.append('\\');
                                  } else {
                                      buf.append((char)ch);
                                  } 
                              } else if (c == '}') {
                                  String str = buf.toString();
                                  Object compiledExpression;
                                  try {
                                      if (xpath) {
                                          compiledExpression = 
                                              JXPathContext.compile(str);
                                      } else {
                                          compiledExpression = 
                                              ExpressionFactory.createExpression(str);
                                      }
                                  } catch (Exception exc) {
                                      throw new SAXParseException(exc.getMessage(),
                                                                  location,
                                                                  exc);
                                  }
                                  substitutions.add(compiledExpression);
                                  buf.setLength(0);
                                  inExpr = false;
                              } else {
                                  buf.append(c);
                              }
                          } else {
                              if (c == '\\') {
                                  ch = in.read();
                                  if (ch == -1) {
                                      buf.append('\\');
                                  } else {
                                      buf.append((char)ch);
                                  }
                              } else if (c == '$' || c == '#') {
                                  ch = in.read();
                                  if (ch == '{') {
                                      xpath = c == '#';
                                      inExpr = true;
                                      if (buf.length() > 0) {
                                          char[] charArray = 
                                              new char[buf.length()];
                                          
                                          buf.getChars(0, buf.length(),
                                                       charArray, 0);
                                          substitutions.add(charArray);
                                          buf.setLength(0);
                                      }
                                      continue top;
                                  } else {
                                      buf.append(c);
                                      if (ch != -1) {
                                          c = (char)ch;
                                          continue processChar;
                                      }
                                  }
                              } else {
                                  buf.append(c);
                              }
                          }
                          break;
                      }
                  }
              } catch (IOException ignored) {
                  // won't happen
                  ignored.printStackTrace();
              }
              if (buf.length() > 0) {
                  char[] charArray = 
                      new char[buf.length()];
                  buf.getChars(0, buf.length(), charArray, 0);
                  substitutions.add(charArray);
              } else if (substitutions.size() == 0) {
                  substitutions.add(EMPTY_CHARS);
              }
          }
          final List substitutions = new LinkedList();
      }
  
      class Characters extends TextEvent {
          Characters(Locator location, 
                     char[] chars, int start, int length) 
              throws SAXException {
              super(location, chars, start, length);
          }
  
      }
  
      class StartDocument extends Event {
          StartDocument(Locator location) {
              super(location);
          }
          long compileTime;
          EndDocument endDocument; // null if document fragment
      }
  
      class EndDocument extends Event {
          EndDocument(Locator location) {
              super(location);
          }
      }
  
      class EndElement extends Event {
          EndElement(Locator location, 
                     StartElement startElement) {
              super(location);
              this.startElement = startElement;
          }
          final StartElement startElement;
      }
  
      class EndPrefixMapping extends Event {
          EndPrefixMapping(Locator location, String prefix) {
              super(location);
              this.prefix = prefix;
          }
          final String prefix;
      }
      
      class IgnorableWhitespace extends TextEvent {
          IgnorableWhitespace(Locator location, 
                              char[] chars, int start, int length) 
              throws SAXException {
              super(location, chars, start, length);
          }
      }
  
      class ProcessingInstruction extends Event {
          ProcessingInstruction(Locator location,
                                String target, String data) {
              super(location);
              this.target = target;
              this.data = data;
          }
          final String target;
          final String data;
      }
  
      class SkippedEntity extends Event {
          SkippedEntity(Locator location, String name) {
              super(location);
              this.name = name;
          }
          final String name;
      }
  
      abstract class AttributeEvent {
          AttributeEvent(String namespaceURI, String localName, String raw,
                         String type) {
              this.namespaceURI = namespaceURI;
              this.localName = localName;
              this.raw = raw;
              this.type = type;
          }
          final String namespaceURI;
          final String localName;
          final String raw;
          final String type;
      }
      
      class CopyAttribute extends AttributeEvent {
          CopyAttribute(String namespaceURI, 
                        String localName,
                        String raw,
                        String type, String value) {
              super(namespaceURI, localName, raw, type);
              this.value = value;
          }
          final String value;
      }
      
      class Subst {
      }
      
      class Literal extends Subst {
          Literal(String val) {
              this.value = val;
          }
          final String value;
      }
      
      class Expression extends Subst {
          Expression(Object expr) {
              this.compiledExpression = expr;
          }
          final Object compiledExpression;
      }
  
      class SubstituteAttribute extends AttributeEvent {
          SubstituteAttribute(String namespaceURI,
                              String localName,
                              String raw,
                              String type, List substs) {
              super(namespaceURI, localName, raw, type);
              this.substitutions = substs;
          }
          final List substitutions;
      }
  
      class StartElement extends Event {
          StartElement(Locator location, String namespaceURI,
                       String localName, String raw,
                       Attributes attrs) 
              throws SAXException {
              super(location);
              this.namespaceURI = namespaceURI;
              this.localName = localName;
              this.raw = raw;
              this.qname = "{"+namespaceURI+"}"+localName;
              StringBuffer buf = new StringBuffer();
              for (int i = 0, len = attrs.getLength(); i < len; i++) {
                  String uri = attrs.getURI(i);
                  String local = attrs.getLocalName(i);
                  String qname = attrs.getQName(i);
                  String type = attrs.getType(i);
                  String value = attrs.getValue(i);
                  StringReader in = new StringReader(value);
                  int ch;
                  buf.setLength(0);
                  boolean inExpr = false;
                  List substEvents = new LinkedList();
                  boolean xpath = false;
                  try {
                      top: while ((ch = in.read()) != -1) {
                          char c = (char)ch;
                          processChar: while (true) {
                              if (inExpr) {
                                  if (c == '\\') {
                                      ch = in.read();
                                      if (ch == -1) {
                                          buf.append('\\');
                                      } else {
                                          buf.append((char)ch);
                                      }
                                  } else if (c == '}') {
                                      String str = buf.toString();
                                      Object compiledExpression;
                                      try {
                                          compiledExpression =
                                              compile(str, xpath);
                                      } catch (Exception exc) {
                                          throw new SAXParseException(exc.getMessage(),
                                                                      location,
                                                                      exc);
                                      } catch (Error err) {
                                          throw new SAXParseException(err.getMessage(),
                                                                      location,
                                                                      null);
                                          
                                      } 
                                      substEvents.add(new Expression(compiledExpression));
                                      buf.setLength(0);
                                      inExpr = false;
                                  } else {
                                      buf.append(c);
                                  }
                              } else {
                                  if (c == '\\') {
                                      ch = in.read();
                                      if (ch == -1) {
                                          buf.append('\\');
                                      } else {
                                          buf.append((char)ch);
                                      }
                                  } if (c == '$' || c == '#') {
                                      ch = in.read();
                                      if (ch == '{') {
                                          if (buf.length() > 0) {
                                              substEvents.add(new Literal(buf.toString()));
                                              buf.setLength(0);
                                          }
                                          inExpr = true;
                                          xpath = c == '#';
                                          continue top;
                                      } else {
                                          buf.append(c);
                                          if (ch != -1) {
                                              c = (char)ch;
                                              continue processChar;
                                          }
                                      }
                                  } else {
                                      buf.append(c);
                                  }
                              }
                              break;
                          } 
                      }
                  } catch (IOException ignored) {
                      ignored.printStackTrace();
                  }
                  if (buf.length() > 0) {
                      if (substEvents.size() == 0) {
                          attributeEvents.add(new CopyAttribute(uri,
                                                                local,
                                                                qname,
                                                                type,
                                                                value));
                      } else {
                          substEvents.add(new Literal(buf.toString()));
                          attributeEvents.add(new SubstituteAttribute(uri,
                                                                      local,
                                                                      qname,
                                                                      type,
                                                                      substEvents));
                      }
                  } else {
                      if (substEvents.size() > 0) {
                          attributeEvents.add(new SubstituteAttribute(uri,
                                                                      local,
                                                                      qname,
                                                                      type,
                                                                      substEvents));
                      } else {
                          attributeEvents.add(new CopyAttribute(uri, local,
                                                                qname, type,
                                                                 ""));
                      }
                  }
              }
              this.attributes = new AttributesImpl(attrs);
          }
          final String namespaceURI;
          final String localName;
          final String raw;
          final String qname;
          final List attributeEvents = new LinkedList();
          final Attributes attributes;
          EndElement endElement;
      }
  
      class StartForEach extends Event {
          StartForEach(Locator location, Object items, String var,
                       int begin, int end, int step) {
              super(location);
              this.items = items;
              this.var = var;
              this.begin = begin;
              this.end = end;
              this.step = step;
          }
          final Object items;
          final String var;
          final int begin;
          final int end;
          final int step;
          EndForEach endForEach;
      }
      
      class EndForEach extends Event {
          EndForEach(Locator location) {
              super(location);
          }
      }
  
      class StartIf extends Event {
          StartIf(Locator location, Object test) {
              super(location);
              this.test = test;
          }
          final Object test;
          EndIf endIf;
      }
  
      class EndIf extends Event {
          EndIf(Locator location) {
              super(location);
          }
      }
  
      class StartChoose extends Event {
          StartChoose(Locator location) {
              super(location);
          }
          StartWhen firstChoice;
          StartOtherwise otherwise;
          EndChoose endChoose;
      }
  
      class EndChoose extends Event {
          EndChoose(Locator location) {
              super(location);
          }
      }
  
      class StartWhen extends Event {
          StartWhen(Locator location, Object test) {
              super(location);
              this.test = test;
          }
          final Object test;
          StartWhen nextChoice;
          EndWhen endWhen;
      }
  
      class EndWhen extends Event {
          EndWhen(Locator location) {
              super(location);
          }
      }
  
      class StartOtherwise extends Event {
          StartOtherwise(Locator location) {
              super(location);
          }
          EndOtherwise endOtherwise;
      }
  
      class EndOtherwise extends Event {
          EndOtherwise(Locator location) {
              super(location);
          }
      }
  
      class StartPrefixMapping extends Event {
          StartPrefixMapping(Locator location, String prefix,
                             String uri) {
              super(location);
              this.prefix = prefix;
              this.uri = uri;
          }
          final String prefix;
          final String uri;
      }
  
      class Comment extends TextEvent {
          Comment(Locator location, char[] chars,
                  int start, int length)
              throws SAXException {
              super(location, chars, start, length);
          }
      }
  
      class EndCDATA extends Event {
          EndCDATA(Locator location) {
              super(location);
          }
      }
  
      class EndDTD extends Event {
          EndDTD(Locator location) {
              super(location);
          }
      }
  
      class EndEntity extends Event {
          EndEntity(Locator location, String name) {
              super(location);
              this.name = name;
          }
          final String name;
      }
  
      class StartCDATA extends Event {
          StartCDATA(Locator location) {
              super(location);
          }
      }
  
      class StartDTD extends Event {
          StartDTD(Locator location, String name, 
                   String publicId, String systemId) {
              super(location);
              this.name = name;
              this.publicId = publicId;
              this.systemId = systemId;
          }
          final String name;
          final String publicId;
          final String systemId;
      }
      
      class StartEntity extends Event {
          public StartEntity(Locator location, String name) {
              super(location);
              this.name = name;
          }
          final String name;
      }
  
      class StartOut extends Event {
          StartOut(Locator location, Object expr) {
              super(location);
              this.compiledExpression = expr;
          }
          final Object compiledExpression;
      }
  
      class EndOut extends Event {
          EndOut(Locator location) {
              super(location);
          }
      }
  
      class StartImport extends Event {
          StartImport(Locator location, AttributeEvent uri, 
                      Object select) {
              super(location);
              this.uri = uri;
              this.select = select;
          }
          final AttributeEvent uri;
          final Object select;
          EndImport endImport;
      }
  
      class EndImport extends Event {
          EndImport(Locator location) {
              super(location);
          }
      }
  
      class StartTemplate extends Event {
          StartTemplate(Locator location) {
              super(location);
          }
          EndTemplate endTemplate;
      }
  
      class EndTemplate extends Event {
          EndTemplate(Locator location) {
              super(location);
          }
      }
  
      class StartDefine extends Event {
          StartDefine(Locator location, String namespace, String name) {
              super(location);
              this.namespace = namespace;
              this.name = name;
              this.qname = "{"+namespace+"}"+name;
              this.parameters = new HashMap();
          }
          final String name;
          final String namespace;
          final String qname;
          final Map parameters;
          Event body;
          EndDefine endDefine;
          void finish(EndDefine endDef) throws SAXException {
              Event e = next;
              boolean params = true;
              while (e != null) {
                  if (e instanceof StartParameter) {
                      StartParameter startParam = (StartParameter)e;
                      if (!params) {
                          throw new SAXParseException("<parameter> not allowed here: \""+startParam.name +"\"", startParam.location, null);
                      }
                      Object prev = 
                          parameters.put(startParam.name, startParam);
                      if (prev != null) {
                          throw new SAXParseException("duplicate parameter: \""+startParam.name +"\"", location, null);
                      }
                  } else if (e instanceof IgnorableWhitespace) {
                  } else if (e instanceof EndParameter) {
                  } else if (e instanceof Characters) {
                      // fix me: check for whitespace
                  } else {
                      if (params) {
                          params = false;
                          System.out.println("body="+e);
                          body = e;
                      }
                  }
                  e = e.next;
              }
              this.endDefine = endDef;
              if (this.body == null) {
                  this.body = this.endDefine;
              }
          }
      }
  
      class EndDefine extends Event {
          EndDefine(Locator location) {
              super(location);
          }
      }
  
      class StartParameter extends Event {
          StartParameter(Locator location, String name, String optional,
                         String default_) {
              super(location);
              this.name = name;
              this.optional = optional;
              this.default_ = default_;
          }
          final String name;
          final String optional;
          final String default_;
          EndParameter endParameter;
      }
  
      class EndParameter extends Event {
          EndParameter(Locator location) {
              super(location);
          }
      }
  
      class StartSet extends Event {
          StartSet(Locator location, String var, Object value) {
              super(location);
              this.var = var;
              this.value = value;
          }
          final String var;
          final Object value;
          EndSet endSet;
      }
  
      class EndSet extends Event {
          EndSet(Locator location) {
              super(location);
          }
      }
  
  
      class Parser implements LexicalHandler, ContentHandler {
  
          StartDocument startEvent;
          Event lastEvent;
          Stack stack = new Stack();
          Locator locator;
          Locator charLocation;
          StringBuffer charBuf;
  
          StartDocument getStartEvent() {
              return startEvent;
          }
          
          private void addEvent(Event ev) throws SAXException {
              if (ev == null) {
                  throw new NullPointerException("null event");
              }
              if (charBuf != null) {
                  char[] chars = new char[charBuf.length()];
                  charBuf.getChars(0, charBuf.length(), chars, 0);
                  Characters charEvent = new Characters(charLocation,
                                                        chars, 0, chars.length);
                                                        
                  lastEvent.next = charEvent;
                  lastEvent = charEvent;
                  charLocation = null;
                  charBuf = null;
              }
              if (lastEvent == null) {
                  lastEvent = startEvent = new StartDocument(locator);
              }
              lastEvent.next = ev;
              lastEvent = ev;
          }
  
          public void characters(char[] ch, int start, int length) 
              throws SAXException {
              if (charBuf == null) {
                  charBuf = new StringBuffer();
                  charLocation = new LocatorImpl(locator);
              }
              charBuf.append(ch, start, length);
          }
  
          public void endDocument() throws SAXException {
              StartDocument startDoc = (StartDocument)stack.pop();
              EndDocument endDoc = new EndDocument(locator);
              startDoc.endDocument = endDoc;
              addEvent(endDoc);
          }
  
          public void endElement(String namespaceURI,
                                 String localName,
                                 String raw) 
              throws SAXException {
              Event start = (Event)stack.pop();
              Event newEvent = null;
              if (NS.equals(namespaceURI)) {
                  if (start instanceof StartForEach) {
                      StartForEach startForEach = 
                          (StartForEach)start;
                      newEvent = startForEach.endForEach = 
                          new EndForEach(locator);
                      
                  } else if (start instanceof StartIf) {
                      StartIf startIf = (StartIf)start;
                      newEvent = startIf.endIf = 
                          new EndIf(locator);
                  } else if (start instanceof StartWhen) {
                      StartWhen startWhen = (StartWhen)start;
                      StartChoose startChoose = (StartChoose)stack.peek();
                      if (startChoose.firstChoice != null) {
                          StartWhen w = startChoose.firstChoice;
                          while (w.nextChoice != null) {
                              w = w.nextChoice;
                          }
                          w.nextChoice = startWhen;
                      } else {
                          startChoose.firstChoice = startWhen;
                      }
                      newEvent = startWhen.endWhen = 
                          new EndWhen(locator);
                  } else if (start instanceof StartOtherwise) {
                      StartOtherwise startOtherwise = 
                          (StartOtherwise)start;
                      StartChoose startChoose = (StartChoose)stack.peek();
                      newEvent = startOtherwise.endOtherwise = 
                          new EndOtherwise(locator);
                      startChoose.otherwise = startOtherwise;
                  } else if (start instanceof StartOut) {
                      newEvent = new EndOut(locator);
                  } else if (start instanceof StartChoose) {
                      StartChoose startChoose = (StartChoose)start;
                      newEvent = 
                          startChoose.endChoose = new EndChoose(locator);
                  } else if (start instanceof StartImport) {
                      StartImport startImport = (StartImport)start;
                      newEvent = 
                          startImport.endImport = new EndImport(locator);
                  } else if (start instanceof StartTemplate) {
                      StartTemplate startTemplate = (StartTemplate)start;
                      newEvent =
                          startTemplate.endTemplate = new EndTemplate(locator);
                  } else if (start instanceof StartDefine) {
                      StartDefine startDefine = (StartDefine)start;
                      startDefine.finish(new EndDefine(locator));
                      newEvent = startDefine.endDefine;
                  } else if (start instanceof StartParameter) {
                      StartParameter startParameter = (StartParameter)start;
                      newEvent = 
                          startParameter.endParameter = new EndParameter(locator);
                  } else if (start instanceof StartSet) {
                      EndSet endSet = new EndSet(locator);
                      StartSet startSet = (StartSet)start;
                      newEvent = startSet.endSet = endSet;
                  } else {
                      throw new SAXParseException("unrecognized tag: " + localName, locator, null);
                  }
              } else {
                  StartElement startElement = (StartElement)start;
                  newEvent = startElement.endElement = 
                      new EndElement(locator, startElement);
              }
              addEvent(newEvent);
          }
          
          public void endPrefixMapping(String prefix) throws SAXException {
              EndPrefixMapping endPrefixMapping = 
                  new EndPrefixMapping(locator, prefix);
              addEvent(endPrefixMapping);
          }
  
          public void ignorableWhitespace(char[] ch, int start, int length) 
              throws SAXException {
              Event ev = new IgnorableWhitespace(locator, ch, start, length);
              addEvent(ev);
          }
  
          public void processingInstruction(String target, String data) 
              throws SAXException {
              Event pi = new ProcessingInstruction(locator, target, data);
              addEvent(pi);
          }
  
          public void setDocumentLocator(Locator locator) {
              this.locator = locator;
          }
  
          public void skippedEntity(String name) throws SAXException {
              addEvent(new SkippedEntity(locator, name));
          }
  
          public void startDocument() {
              startEvent = new StartDocument(locator);
              lastEvent = startEvent;
              stack.push(lastEvent);
          }
  
          public void startElement(String namespaceURI,
                                   String localName,
                                   String raw,
                                   Attributes attrs) 
              throws SAXException {
              Event newEvent = null;
              if (NS.equals(namespaceURI)) {
                  if (localName.equals(FOR_EACH)) {
                      String items = attrs.getValue("items");
                      String select = attrs.getValue("select");
                      String s = attrs.getValue("begin");
                      int begin = s == null ? -1 : Integer.parseInt(s);
                      s = attrs.getValue("end");
                      int end = s == null ? -1 : Integer.parseInt(s);
                      s = attrs.getValue("step");
                      int step = s == null ? 1 : Integer.parseInt(s);
                      if (step < 1) {
                          throw new SAXParseException("forEach: \"step\" must be a positive integer", locator, null);
                      }
                      String var = attrs.getValue("var");
                      if (items == null) {
                          if (select == null && (begin == -1 || end == -1)) {
                              throw new SAXParseException("forEach: \"select\", \"items\", or both \"begin\" and \"end\" must be specified", locator, null);
                          }
                      } else if (select != null) {
                          throw new SAXParseException("forEach: only one of \"select\" or \"items\" may be specified", locator, null);
                      }
                      begin = begin == -1 ? 0 : begin;
                      end = end == -1 ? Integer.MAX_VALUE: end;
                      Object expr;
                      expr = compileExpr(items == null ? select : items,
                                         null, locator);
                      StartForEach startForEach = 
                          new StartForEach(locator, expr, 
                                           var, begin, end, step);
                      newEvent = startForEach;
                  } else if (localName.equals(CHOOSE)) {
                      StartChoose startChoose = new StartChoose(locator);
                      newEvent = startChoose;
                  } else if (localName.equals(WHEN)) {
                      if (stack.size() == 0 ||
                          !(stack.peek() instanceof StartChoose)) {
                          throw new SAXParseException("<when> must be within <choose>", locator, null);
                      }
                      String test = attrs.getValue("test");
                      if (test == null) {
                          throw new SAXParseException("when: \"test\" is required", locator, null);
                      }
                      Object expr;
                      expr = compileExpr(test, "when: \"test\": ", locator);
                      StartWhen startWhen = new StartWhen(locator, expr);
                      newEvent = startWhen;
                  } else if (localName.equals(OUT)) {
                      String value = attrs.getValue("value");
                      if (value == null) {
                          throw new SAXParseException("out: \"value\" is required", locator, null);
                      }
                      Object expr = compileExpr(value, 
                                                "out: \"value\": ", 
                                                locator);
                      newEvent = new StartOut(locator, expr);
                  } else if (localName.equals(OTHERWISE)) {
                      if (stack.size() == 0 ||
                          !(stack.peek() instanceof StartChoose)) {
                          throw new SAXParseException("<otherwise> must be within <choose>", locator, null);
                      }
                      StartOtherwise startOtherwise = 
                          new StartOtherwise(locator);
                      newEvent = startOtherwise;
                  } else if (localName.equals(IF)) {
                      String test = attrs.getValue("test");
                      if (test == null) {
                          throw new SAXParseException("if: \"test\" is required", locator, null);
                      }
                      Object expr = compileExpr(test, "if: \"test\": ", locator);
                      StartIf startIf = 
                          new StartIf(locator, expr);
                      newEvent = startIf;
                  } else if (localName.equals(MACRO)) {
                      // <macro name="myTag" targetNamespace="myNamespace">
                      // <parameter name="paramName" required="Boolean" default="value"/>
                      // body
                      // </macro>
                      String namespace = attrs.getValue("targetNamespace");
                      if (namespace == null) {
                          namespace = "";
                      }
                      String name = attrs.getValue("name");
                      if (name == null) {
                          throw new SAXParseException("macro: \"name\" is required", locator, null);
                      }
                      StartDefine startDefine = 
                          new StartDefine(locator, namespace, name); 
                      newEvent = startDefine;
                  } else if (localName.equals(PARAMETER)) {
                      boolean syntaxErr = false;
                      if (stack.size() < 1 ||
                          !(stack.peek() instanceof StartDefine)) {
                          syntaxErr = true;
                      } else {
                          StartDefine startDefine = (StartDefine)stack.peek();
                          String name = attrs.getValue("name");
                          String optional = attrs.getValue("optional");
                          String default_ = attrs.getValue("default");
                          if (name == null) {
                              throw new SAXParseException("parameter: \"name\" is required", locator, null);
                          }
                          StartParameter startParameter = 
                              new StartParameter(locator, 
                                                 name, optional, default_);
                          newEvent = startParameter;
                      }
                      if (syntaxErr) {
                          throw new SAXParseException("<parameter> not allowed here", locator, null);
                      }
                  } else if (localName.equals(SET)) {
                      String var = attrs.getValue("var");
                      String value = attrs.getValue("value");
                      Object valueExpr = null;
                      if (value != null) {
                          valueExpr = compileExpr(value, "set: \"value\":",
                                                  locator);
                      } 
                      StartSet startSet = new StartSet(locator, var, valueExpr);
                      newEvent = startSet;
                  } else if (localName.equals(IMPORT)) {
                      // <import uri="${root}/foo/bar.xml" select="#{.}"/>
                      // Allow expression substitution in "uri" attribute
                      AttributeEvent uri = null;
                      StartElement startElement = 
                          new StartElement(locator, namespaceURI,
                                           localName, raw, attrs);
                      Iterator iter = startElement.attributeEvents.iterator();
                      while (iter.hasNext()) {
                          AttributeEvent e = (AttributeEvent)iter.next();
                          if (e.localName.equals("uri")) {
                              uri = e;
                              break;
                          }
                      }
                      if (uri == null) {
                          throw new SAXParseException("import: \"uri\" is required", locator, null);
                      }
                      // If "select" is present then its value will be used
                      // as the context object in the imported template
                      String select = attrs.getValue("context");
                      Object expr = null;
                      if (select != null) {
                          expr = compileExpr(select, "import: \"context\": ",
                                             locator);
                      }
                      StartImport startImport = 
                          new StartImport(locator, uri, expr);
                      newEvent = startImport;
                  } else if (localName.equals(TEMPLATE)) {
                      StartTemplate startTemplate =
                          new StartTemplate(locator);
                      newEvent = startTemplate;
                  } else {
                      throw new SAXParseException("unrecognized tag: " + localName, locator, null);
                  }
              } else {
                  StartElement startElem = 
                      new StartElement(locator, namespaceURI,
                                       localName, raw, attrs);
                  newEvent = startElem;
              }
              stack.push(newEvent);
              addEvent(newEvent);
          }
          
          public void startPrefixMapping(String prefix, String uri) 
              throws SAXException {
              addEvent(new StartPrefixMapping(locator, prefix, uri));
          }
  
          public void comment(char ch[], int start, int length) 
              throws SAXException {
              addEvent(new Comment(locator, ch, start, length));
          }
  
          public void endCDATA() throws SAXException {
              addEvent(new EndCDATA(locator));
          }
  
          public void endDTD() throws SAXException {
              addEvent(new EndDTD(locator));
          }
  
          public void endEntity(String name) throws SAXException {
              addEvent(new EndEntity(locator, name));
          }
  
          public void startCDATA() throws SAXException {
              addEvent(new StartCDATA(locator));
          }
  
          public void startDTD(String name, String publicId, String systemId) 
              throws SAXException {
              addEvent(new StartDTD(locator, name, publicId, systemId));
          }
          
          public void startEntity(String name) throws SAXException {
              addEvent(new StartEntity(locator, name));
          }
      }
  
      private XMLConsumer consumer;
      private JXPathContext jxpathContext;
      private MyJexlContext globalJexlContext;
      private Variables variables;
      private static Map cache = new HashMap();
      private Source inputSource;
      private Map definitions;
  
      public void recycle() {
          super.recycle();
          consumer = null;
          jxpathContext = null;
          globalJexlContext = null;
          variables = null;
          inputSource = null;
          definitions = null;
      }
  
      public void setup(SourceResolver resolver, Map objectModel,
                        String src, Parameters parameters)
          throws ProcessingException, SAXException, IOException {
  
          super.setup(resolver, objectModel, src, parameters);
          if (src != null) {
              try {
                  this.inputSource = resolver.resolveURI(src);
              } catch (SourceException se) {
                  throw SourceUtil.handle("Error during resolving of '" + src + "'.", se);
              }
          }
          long lastMod = inputSource.getLastModified();
          String uri = inputSource.getURI();
          synchronized (cache) {
              StartDocument startEvent = (StartDocument)cache.get(uri);
              if (startEvent != null &&
                  lastMod > startEvent.compileTime) {
                  cache.remove(uri);
              }
          }
          // FIX ME: When we decide proper way to pass "bean" and "kont"
          Object bean = ((Environment)resolver).getAttribute("bean-dict");
          WebContinuation kont =
              (WebContinuation)((Environment)resolver).getAttribute("kont");
          setContexts(bean, kont,
                      ObjectModelHelper.getRequest(objectModel),
                      ObjectModelHelper.getResponse(objectModel),
                      ObjectModelHelper.getContext(objectModel),
                      parameters);
          definitions = new HashMap();
      }
      
      private void fillContext(Object contextObject, Map map) {
          // Hack: I use jxpath to populate the context object's properties
          // in the jexl context
          final JXPathBeanInfo bi = 
              JXPathIntrospector.getBeanInfo(contextObject.getClass());
          if (bi.isDynamic()) {
              Class cl = bi.getDynamicPropertyHandlerClass();
              try {
                  DynamicPropertyHandler h = (DynamicPropertyHandler) cl.newInstance();
                  String[] result = h.getPropertyNames(contextObject);
                  for (int i = 0; i < result.length; i++) {
                      try {
                          map.put(result[i], h.getProperty(contextObject, result[i]));
                      } catch (Exception exc) {
                          exc.printStackTrace();
                      }
                  }
              } catch (Exception ignored) {
                  ignored.printStackTrace();
              }
          } else {
              PropertyDescriptor[] props =  bi.getPropertyDescriptors();
              for (int i = 0; i < props.length; i++) {
                  try {
                      Method read = props[i].getReadMethod();
                      if (read != null) {
                          map.put(props[i].getName(), 
                                  read.invoke(contextObject, null));
                      }
                  } catch (Exception ignored) {
                      ignored.printStackTrace();
                  }
              }
          }
      }
  
      private void setContexts(Object contextObject,
                               WebContinuation kont,
                               Request request,
                               Response response,
                               org.apache.cocoon.environment.Context app,
                               Parameters parameters) {
          if (variables == null) {
              variables = new MyVariables(contextObject,
                                          kont,
                                          request,
                                          response,
                                          app,
                                          parameters);
          }
          Map map;
          if (contextObject instanceof Map) {
              map = (Map)contextObject;
          } else {
              map = new HashMap();
              fillContext(contextObject, map);
          }
          jxpathContext = jxpathContextFactory.newContext(null, contextObject);
          jxpathContext.setVariables(variables);
          globalJexlContext = new MyJexlContext();
          globalJexlContext.setVars(map);
          map = globalJexlContext.getVars();
          map.put("flowContext", contextObject);
          map.put("continuation", kont);
          map.put("request", request);
          map.put("response", response);
          map.put("context", app);
          map.put("session", request.getSession(false));
      }
  
      public void setConsumer(XMLConsumer consumer) {
          this.consumer = consumer;
      }
  
      public void generate() 
          throws IOException, SAXException, ProcessingException {
          StartDocument startEvent;
          synchronized (cache) {
              startEvent = (StartDocument)cache.get(inputSource.getURI());
          }
          if (startEvent == null) {
              long compileTime = inputSource.getLastModified();
              Parser parser = new Parser();
              this.resolver.toSAX(this.inputSource, parser);
              startEvent = parser.getStartEvent();
              startEvent.compileTime = compileTime;
              synchronized (cache) {
                  cache.put(inputSource.getURI(), startEvent);
              }
          }
          execute(consumer,
                  globalJexlContext, jxpathContext, 
                  startEvent, null);
      }
  
      interface CharHandler {
          public void characters(char[] ch, int offset, int length)
              throws SAXException;
      }
  
      private void characters(JexlContext jexlContext,
                              JXPathContext jxpathContext, 
                              TextEvent event,
                              CharHandler handler) throws SAXException {
          Iterator iter = event.substitutions.iterator();
          while (iter.hasNext()) {
              Object subst = iter.next();
              char[] chars;
              if (subst instanceof char[]) {
                  chars = (char[])subst;
              } else {
                  Object expr = subst;
                  try {
                      Object val = getValue(expr, jexlContext, jxpathContext);
                      if (val != null) {
                          chars = val.toString().toCharArray();
                      } else {
                          chars = EMPTY_CHARS;
                      }
                  } catch (Exception e) {
                      throw new SAXParseException(e.getMessage(),
                                                  event.location,
                                                  e);
                  } catch (Error err) {
                      throw new SAXParseException(err.getMessage(),
                                                  event.location,
                                                  null);
                  }
              }
              handler.characters(chars, 0, chars.length);
          }
      }
  
      private void execute(final XMLConsumer consumer,
                           MyJexlContext jexlContext,
                           JXPathContext jxpathContext,
                           Event startEvent, Event endEvent) 
          throws SAXException {
          Event ev = startEvent;
          while (ev != endEvent) {
              consumer.setDocumentLocator(ev.location);
              if (ev instanceof Characters) {
                  TextEvent text = (TextEvent)ev;
                  Iterator iter = text.substitutions.iterator();
                  while (iter.hasNext()) {
                      Object subst = iter.next();
                      char[] chars;
                      if (subst instanceof char[]) {
                          chars = (char[])subst;
                      } else {
                          Object expr = subst;
                          try {
                              Object val = 
                                  getNode(expr, jexlContext, jxpathContext);
                              if (val instanceof Node) {
                                  DOMStreamer streamer =
                                      new DOMStreamer(consumer);
                                  streamer.stream((Node)val);
                                  continue;
                              }
                              if (val != null) {
                                  chars = val.toString().toCharArray();
                              } else {
                                  chars = EMPTY_CHARS;
                              }
                          } catch (Exception e) {
                              throw new SAXParseException(e.getMessage(),
                                                          ev.location,
                                                          e);
                          } catch (Error err) {
                              throw new SAXParseException(err.getMessage(),
                                                          ev.location,
                                                          null);
                          }
                      }
                      consumer.characters(chars, 0, chars.length);
                  }
              } else if (ev instanceof EndDocument) {
                  consumer.endDocument();
              } else if (ev instanceof EndElement) {
                  EndElement endElement = (EndElement)ev;
                  StartElement startElement = 
                      (StartElement)endElement.startElement;
                  consumer.endElement(startElement.namespaceURI,
                                      startElement.localName,
                                      startElement.raw);
              } else if (ev instanceof EndPrefixMapping) {
                  EndPrefixMapping endPrefixMapping = 
                      (EndPrefixMapping)ev;
                  consumer.endPrefixMapping(endPrefixMapping.prefix);
              } else if (ev instanceof IgnorableWhitespace) {
                  TextEvent text = (TextEvent)ev;
                  characters(jexlContext, 
                             jxpathContext, 
                             text, 
                             new CharHandler() {
                                 public void characters(char[] ch, int offset,
                                                        int len) 
                                     throws SAXException {
                                     consumer.ignorableWhitespace(ch, offset, len);
                                 }
                             });
              } else if (ev instanceof ProcessingInstruction) {
                  ProcessingInstruction pi = (ProcessingInstruction)ev;
                  consumer.processingInstruction(pi.target, pi.data);
              } else if (ev instanceof SkippedEntity) {
                  SkippedEntity skippedEntity = (SkippedEntity)ev;
                  consumer.skippedEntity(skippedEntity.name);
              } else if (ev instanceof StartDocument) {
                  StartDocument startDoc = (StartDocument)ev;
                  if (startDoc.endDocument != null) {
                      // if this isn't a document fragment
                      consumer.startDocument();
                  }
              } else if (ev instanceof StartIf) {
                  StartIf startIf = (StartIf)ev;
                  Object val;
                  try {
                      val = getValue(startIf.test, jexlContext, jxpathContext);
                  } catch (Exception e) {
                      throw new SAXParseException(e.getMessage(),
                                                  ev.location,
                                                  e);
                  } catch (Error err) {
                      throw new SAXParseException(err.getMessage(),
                                                  ev.location,
                                                  null);
                  }
                  boolean result = false;
                  if (val instanceof Boolean) {
                      result = ((Boolean)val).booleanValue();
                  }
                  if (!result) {
                      ev = startIf.endIf.next;
                      continue;
                  }
              } else if (ev instanceof StartForEach) {
                  StartForEach startForEach = (StartForEach)ev;
                  final Object items = startForEach.items;
                  Iterator iter = null;
                  boolean xpath = false;
                  try {
                      if (items == null) {
                          iter = NULL_ITER;
                      } else if (items instanceof CompiledExpression) {
                          CompiledExpression compiledExpression = 
                              (CompiledExpression)items;
                          iter = 
                              compiledExpression.iteratePointers(jxpathContext);
                          xpath = true;
                      } else if (items instanceof org.apache.commons.jexl.Expression) {
                          org.apache.commons.jexl.Expression e = 
                              (org.apache.commons.jexl.Expression)items;
                          Object result = e.evaluate(jexlContext);
                          if (result != null) {
                              iter =
                                  org.apache.commons.jexl.util.Introspector.getUberspect().getIterator(result, new Info(ev.location.getSystemId(),
                                                                                                                        ev.location.getLineNumber(),
                                                                                                                        ev.location.getColumnNumber()));
  
                          }
                          if (iter == null) {
                              iter = EMPTY_ITER;
                          }
                      } else {
                          // literal value
                          iter = new Iterator() {
  
                                  Object val = items;
  
                                  public boolean hasNext() {
                                      return val != null;
                                  }
  
                                  public Object next() {
                                      Object res = val;
                                      val = null;
                                      return res;
                                  }
  
                                  public void remove() {
                                  }
                              };
                      }
                  } catch (Exception exc) {
                      throw new SAXParseException(exc.getMessage(),
                                                  ev.location,
                                                  exc);
                  } catch (Error err) {
                      throw new SAXParseException(err.getMessage(),
                                                  ev.location,
                                                  null);
                  }
                  int i;
                  int begin = startForEach.begin;
                  int end = startForEach.end;
                  int step = startForEach.step;
                  MyJexlContext localJexlContext = 
                      new MyJexlContext(jexlContext);
                  for (i = 0; i < begin && iter.hasNext(); i++) {
                      iter.next();
                  }
                  for (; i <= end && iter.hasNext(); i++) {
                      Object value;
                      if (xpath) {
                          Pointer ptr = (Pointer)iter.next();
                          try {
                              value = ptr.getNode();
                          } catch (Exception exc) {
                              throw new SAXParseException(exc.getMessage(),
                                                          ev.location,
                                                          exc);
                          }
                      } else {
                          value = iter.next();
                      }
                      JXPathContext localJXPathContext = 
                          jxpathContextFactory.newContext(null, value);
                      localJXPathContext.setVariables(variables);
                      if (startForEach.var != null) {
                          localJexlContext.put(startForEach.var, value);
                      }
                      execute(consumer,
                              localJexlContext,
                              localJXPathContext,
                              startForEach.next,
                              startForEach.endForEach);
                      for (int skip = step-1; 
                           skip > 0 && iter.hasNext(); --skip) {
                          iter.next();
                      }
                  }
                  ev = startForEach.endForEach.next;
                  continue;
              } else if (ev instanceof StartChoose) {
                  StartChoose startChoose = (StartChoose)ev;
                  StartWhen startWhen = startChoose.firstChoice; 
                  for (;startWhen != null; startWhen = startWhen.nextChoice) {
                      Object val;
                      try {
                          val = getValue(startWhen.test, jexlContext,
                                         jxpathContext);
                      } catch (Exception e) {
                          throw new SAXParseException(e.getMessage(),
                                                      ev.location,
                                                      e);
                      }
                      boolean result = false;
                      if (val instanceof Boolean) {
                          result = ((Boolean)val).booleanValue();
                      }
                      if (result) {
                          execute(consumer,
                                  jexlContext, jxpathContext,
                                  startWhen.next, startWhen.endWhen);
                          break;
                      }
                  }
                  if (startWhen == null) {
                      if (startChoose.otherwise != null) {
                          execute(consumer,
                                  jexlContext, jxpathContext,
                                  startChoose.otherwise.next,
                                  startChoose.otherwise.endOtherwise);
                      }
                  }
                  ev = startChoose.endChoose.next;
                  continue;
              } else if (ev instanceof StartSet) {
                  StartSet startSet = (StartSet)ev;
                  Object value = null;
                  if (startSet.value != null) {
                      try {
                          value = getNode(startSet.value,
                                          jexlContext, jxpathContext);
                      } catch (Exception exc) {
                          throw new SAXParseException(exc.getMessage(),
                                                      ev.location,
                                                      exc);
                      }
                  } else {
                      DOMBuilder builder = new DOMBuilder();
                      builder.startDocument();
                      builder.startElement(NS,
                                           "set",
                                           "set",
                                           EMPTY_ATTRS);
                      execute(builder, jexlContext, jxpathContext,
                              startSet.next, 
                              startSet.endSet);
                      builder.endElement(NS,
                                         "set",
                                         "set");
                      builder.endDocument();
                      Node node = builder.getDocument().getDocumentElement();
                      NodeList nodeList = node.getChildNodes();
                      int len = nodeList.getLength(); 
                      List children = new ArrayList(len);
                      for (int i = 0; i < len; i++) {
                          children.add(nodeList.item(i));
                      }
                      value = children;
                  }
                  jxpathContext.getVariables().declareVariable(startSet.var, 
                                                               value);
                  jexlContext.put(startSet.var, value);
                  ev = startSet.endSet.next;
                  continue;
              } else if (ev instanceof StartElement) {
                  StartElement startElement = (StartElement)ev;
                  StartDefine def = 
                      (StartDefine)definitions.get(startElement.qname);
                  if (def != null) {
                      Map attributeMap = new HashMap();
                      Iterator i = startElement.attributeEvents.iterator();
                      while (i.hasNext()) {
                          String attributeName;
                          Object attributeValue;
                          AttributeEvent attrEvent = (AttributeEvent)
                              i.next();
                          attributeName = attrEvent.localName;
                          if (attrEvent instanceof CopyAttribute) {
                              CopyAttribute copy =
                                  (CopyAttribute)attrEvent;
                              attributeValue = copy.value;
                          } else if (attrEvent instanceof 
                                     SubstituteAttribute) {
                              SubstituteAttribute substEvent =
                                  (SubstituteAttribute)attrEvent;
                              if (substEvent.substitutions.size() == 1 &&
                                  substEvent.substitutions.get(0) instanceof 
                                  Expression) {
                                  Expression expr = (Expression)
                                      substEvent.substitutions.get(0);
                                  Object val;
                                  try {
                                      val = 
                                          getValue(expr.compiledExpression,
                                                   jexlContext,
                                                   jxpathContext);
                                  } catch (Exception e) {
                                      throw new SAXParseException(e.getMessage(),
                                                                  ev.location,
                                                                  e);
                                  }
                                  attributeValue = val;
                              } else {
                                  StringBuffer buf = new StringBuffer();
                                  Iterator ii = substEvent.substitutions.iterator();
                                  while (ii.hasNext()) {
                                      Subst subst = (Subst)ii.next();
                                      if (subst instanceof Literal) {
                                          Literal lit = (Literal)subst;
                                          buf.append(lit.value);
                                      } else if (subst instanceof Expression) {
                                          Expression expr = (Expression)subst;
                                          Object val;
                                          try {
                                              val = 
                                                  getValue(expr.compiledExpression,
                                                           jexlContext,
                                                           jxpathContext);
                                          } catch (Exception e) {
                                              throw new SAXParseException(e.getMessage(),
                                                                          ev.location,
                                                                          e);
                                          }
                                          if (val == null) {
                                              val = "";
                                          }
                                          buf.append(val.toString());
                                      }
                                  }
                                  attributeValue = buf.toString();
                              }
                          } else {
                              throw new Error("this shouldn't have happened");
                          }
                          attributeMap.put(attributeName, attributeValue);
                      }
                      DOMBuilder builder = new DOMBuilder();
                      builder.startDocument();
                      builder.startElement(startElement.namespaceURI,
                                           startElement.localName,
                                           startElement.raw,
                                           EMPTY_ATTRS);
                      execute(builder, jexlContext, jxpathContext,
                              startElement.next, 
                              startElement.endElement);
                      builder.endElement(startElement.namespaceURI,
                                         startElement.localName,
                                         startElement.raw);
                      builder.endDocument();
                      Node node = builder.getDocument().getDocumentElement();
                      MyVariables vars = 
                          (MyVariables)jxpathContext.getVariables();
                      Map saveLocals = vars.localVariables;
                      vars.localVariables = new HashMap();
                      MyJexlContext localJexlContext = 
                          new MyJexlContext(globalJexlContext);
                      NodeList children = node.getChildNodes();
                      List items = new ArrayList(children.getLength());
                      for (int j = 0, len = children.getLength(); j < len; j++) {
                          items.add(children.item(j));
                      }
                      localJexlContext.put("body", items);
                      Iterator iter = def.parameters.entrySet().iterator();
                      while (iter.hasNext()) {
                          Map.Entry e = (Map.Entry)iter.next();
                          String key = (String)e.getKey();
                          StartParameter startParam = 
                              (StartParameter)e.getValue();
                          Object default_ = startParam.default_;
                          Object val = attributeMap.get(key);
                          if (val == null) {
                              val = default_;
                          }
                          localJexlContext.put(key, val);
                          vars.localVariables.put(key, val);
                      }
                      JXPathContext localJXPathContext =
                          jxpathContextFactory.newContext(jxpathContext, items);
                      execute(consumer, 
                              localJexlContext, localJXPathContext,
                              def.body, def.endDefine);
                      vars.localVariables = saveLocals;
                      ev = startElement.endElement.next;
                      continue;
                  }
                  Iterator i = startElement.attributeEvents.iterator();
                  AttributesImpl attrs = new AttributesImpl();
                  while (i.hasNext()) {
                      AttributeEvent attrEvent = (AttributeEvent)
                          i.next();
                      if (attrEvent instanceof CopyAttribute) {
                          CopyAttribute copy =
                              (CopyAttribute)attrEvent;
                          attrs.addAttribute(copy.namespaceURI,
                                             copy.localName,
                                             copy.raw,
                                             copy.type,
                                             copy.value);
                      } else if (attrEvent instanceof 
                                 SubstituteAttribute) {
                          StringBuffer buf = new StringBuffer();
                          SubstituteAttribute substEvent =
                              (SubstituteAttribute)attrEvent;
                          Iterator ii = substEvent.substitutions.iterator();
                          while (ii.hasNext()) {
                              Subst subst = (Subst)ii.next();
                              if (subst instanceof Literal) {
                                  Literal lit = (Literal)subst;
                                  buf.append(lit.value);
                              } else if (subst instanceof Expression) {
                                  Expression expr = (Expression)subst;
                                  Object val;
                                  try {
                                      val = 
                                          getValue(expr.compiledExpression,
                                                   jexlContext,
                                                   jxpathContext);
                                  } catch (Exception e) {
                                      throw new SAXParseException(e.getMessage(),
                                                                  ev.location,
                                                                  e);
                                  }
                                  if (val == null) {
                                      val = "";
                                  }
                                  buf.append(val.toString());
                              }
                          }
                          attrs.addAttribute(attrEvent.namespaceURI,
                                             attrEvent.localName,
                                             attrEvent.raw,
                                             attrEvent.type,
                                             buf.toString());
                      }
                  }
                  consumer.startElement(startElement.namespaceURI,
                                        startElement.localName,
                                        startElement.raw,
                                        attrs); 
              } else if (ev instanceof StartPrefixMapping) {
                  StartPrefixMapping startPrefixMapping = 
                      (StartPrefixMapping)ev;
                  consumer.startPrefixMapping(startPrefixMapping.prefix, 
                                              startPrefixMapping.uri);
              } else if (ev instanceof Comment) {
                  TextEvent text = (TextEvent)ev;
                  final StringBuffer buf = new StringBuffer();
                  characters(jexlContext, 
                             jxpathContext, 
                             text, 
                             new CharHandler() {
                                 public void characters(char[] ch, int offset,
                                                        int len) 
                                     throws SAXException {
                                     buf.append(ch, offset, len);
                                 }
                             });
                  char[] chars = new char[buf.length()];
                  buf.getChars(0, chars.length, chars, 0);
                  consumer.comment(chars, 0, chars.length);
               } else if (ev instanceof EndCDATA) {
                   consumer.endCDATA();
              } else if (ev instanceof EndDTD) {
                  consumer.endDTD();
              } else if (ev instanceof EndEntity) {
                  consumer.endEntity(((EndEntity)ev).name);
              } else if (ev instanceof StartCDATA) {
                  consumer.startCDATA();
              } else if (ev instanceof StartDTD) {
                  StartDTD startDTD = (StartDTD)ev;
                  consumer.startDTD(startDTD.name,
                                           startDTD.publicId,
                                           startDTD.systemId);
              } else if (ev instanceof StartEntity) {
                  consumer.startEntity(((StartEntity)ev).name);
              } else if (ev instanceof StartOut) {
                  StartOut startOut = (StartOut)ev;
                  Object val;
                  try {
                      val = getValue(startOut.compiledExpression,
                                     jexlContext,
                                     jxpathContext);
                  } catch (Exception e) {
                      throw new SAXParseException(e.getMessage(),
                                                  ev.location,
                                                  e);
                  }
                  if (val == null) {
                      val = "";
                  }
                  char[] ch = val.toString().toCharArray();
                  consumer.characters(ch, 0, ch.length);
              } else if (ev instanceof StartTemplate) {
                  // no action
              } else if (ev instanceof StartDefine) {
                  StartDefine startDefine = (StartDefine)ev;
                  definitions.put(startDefine.qname, startDefine);
                  ev = startDefine.endDefine.next;
              } else if (ev instanceof StartImport) {
                  String uri;
                  StartImport startImport = (StartImport)ev;
                  AttributeEvent e = startImport.uri;
                  if (e instanceof CopyAttribute) {
                      CopyAttribute copy = (CopyAttribute)e;
                      uri = copy.value;
                  } else {
                      StringBuffer buf = new StringBuffer();
                      SubstituteAttribute substAttr = (SubstituteAttribute)e;
                      Iterator i = substAttr.substitutions.iterator();
                      while (i.hasNext()) {
                          Subst subst = (Subst)i.next();
                          if (subst instanceof Literal) {
                              Literal lit = (Literal)subst;
                              buf.append(lit.value);
                          } else if (subst instanceof Expression) {
                              Expression expr = (Expression)subst;
                              Object val;
                              try {
                                  val = 
                                      getValue(expr.compiledExpression,
                                               jexlContext,
                                               jxpathContext);
                              } catch (Exception exc) {
                                  throw new SAXParseException(exc.getMessage(),
                                                              ev.location,
                                                              exc);
                              } catch (Error err) {
                                  throw new SAXParseException(err.getMessage(),
                                                              ev.location,
                                                              null);
                              }
                              if (val == null) {
                                  val = "";
                              }
                              buf.append(val.toString());
                          }
                      }
                      uri = buf.toString();
                      
                  }
                  Source input;
                  try {
                      input = resolver.resolveURI(uri);
                  } catch (Exception exc) {
                      throw new SAXParseException(exc.getMessage(),
                                                  ev.location,
                                                  exc);
                  }
                  long lastMod = input.getLastModified();
                  StartDocument doc;
                  synchronized (cache) {
                      doc = (StartDocument)cache.get(input.getURI());
                      if (doc != null) {
                          if (doc.compileTime < lastMod) {
                              doc = null; // recompile
                          }
                      }
                  }
                  if (doc == null) {
                      try {
                          Parser parser = new Parser();
                          this.resolver.toSAX(input, parser);
                          doc = parser.getStartEvent();
                          doc.compileTime = lastMod;
                      } catch (Exception exc) {
                          throw new SAXParseException(exc.getMessage(),
                                                      ev.location,
                                                      exc);
                      }
                      synchronized (cache) {
                          cache.put(input.getURI(), doc);
                      }
                  }
                  JXPathContext selectJXPath = jxpathContext;
                  MyJexlContext selectJexl = jexlContext;
                  if (startImport.select != null) {
                      try {
                          Object obj = getValue(startImport.select,
                                                jexlContext,
                                                jxpathContext);
                          selectJXPath = 
                              jxpathContextFactory.newContext(null, obj);
                          selectJXPath.setVariables(variables);
                          selectJexl = new MyJexlContext(globalJexlContext);
                          fillContext(obj, selectJexl);
                      } catch (Exception exc) {
                          throw new SAXParseException(exc.getMessage(),
                                                      ev.location,
                                                      exc);
                      } catch (Error err) {
                          throw new SAXParseException(err.getMessage(),
                                                      ev.location,
                                                      null);
                      }
                  }
                  execute(consumer, selectJexl, selectJXPath, doc.next, null);
                  ev = startImport.endImport.next;
                  continue;
              }
              ev = ev.next;
          }
      }
  }
  
  
  
  1.14      +5 -7      cocoon-2.1/src/scratchpad/webapp/samples/petstore/sitemap.xmap
  
  Index: sitemap.xmap
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/sitemap.xmap,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- sitemap.xmap	15 Apr 2003 20:25:20 -0000	1.13
  +++ sitemap.xmap	21 Apr 2003 05:34:46 -0000	1.14
  @@ -5,12 +5,10 @@
     <map:components> 
       <map:transformers default="xslt">
         <map:transformer name="xmlform" src="org.apache.cocoon.transformation.XMLFormTransformer" logger="xmlform.sitemap.transformer"/>
  -      <map:transformer name="jexl" src="org.apache.cocoon.transformation.JexlTransformer" logger="jexl.sitemap.transformer"/>
       </map:transformers>
       <map:generators default="file">
           <map:generator label="content,data" logger="sitemap.generator.velocity" name="velocity" src="org.apache.cocoon.generation.FlowVelocityGenerator"/>
  -        <map:generator label="content,data" logger="sitemap.generator.jxpath" name="jxpath" src="org.apache.cocoon.generation.JXPathTemplate"/>
  -        <map:generator label="content,data" logger="sitemap.generator.jexl" name="jexl" src="org.apache.cocoon.generation.JexlTemplate"/>
  +        <map:generator label="content,data" logger="sitemap.generator.jx" name="jx" src="org.apache.cocoon.generation.JXTemplate"/>
       </map:generators>
       <map:flow-interpreters default="JavaScript"/>
       <map:serializers default="html"/>
  @@ -108,20 +106,20 @@
           <map:serialize type="html"/>
        </map:match>
        <map:match pattern="view/Cart.jxpath">
  -        <map:generate src="view/jxpath/Cart.xml" type="jxpath" />
  +        <map:generate src="view/jxpath/Cart.xml" type="jx" />
           <map:serialize type="html"/>
        </map:match>
        <map:match pattern="view/*.jxpath">
  -        <map:generate src="view/jxpath/{1}.xml" type="jxpath" />
  +        <map:generate src="view/jxpath/{1}.xml" type="jx" />
           <map:transform src="stylesheets/site2html.xsl" />
           <map:serialize type="html"/>
        </map:match>
        <map:match pattern="view/Cart.jexl">
  -        <map:generate src="view/jexl/Cart.xml" type="jexl" />
  +        <map:generate src="view/jexl/Cart.xml" type="jx" />
           <map:serialize type="html"/>
        </map:match>
        <map:match pattern="view/*.jexl">
  -        <map:generate src="view/jexl/{1}.xml" type="jexl" />
  +        <map:generate src="view/jexl/{1}.xml" type="jx" />
           <map:transform src="stylesheets/site2html.xsl" />
           <map:serialize type="html"/>
        </map:match>
  
  
  
  1.3       +1 -7      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Cart.xml
  
  Index: Cart.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Cart.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Cart.xml	15 Apr 2003 20:24:44 -0000	1.2
  +++ Cart.xml	21 Apr 2003 05:34:46 -0000	1.3
  @@ -1,10 +1,4 @@
  -<!-- 
  -     Examples of <import> 
  -     You can use embedded expressions in the import "uri" and you can
  -     [optionally] select a context object for the imported template 
  --->
  -
  -<html xmlns:t="http://cocoon.apache.org/transformation/jexl/1.0">
  +<html xmlns:t="http://cocoon.apache.org/generation/jx/1.0">
   <body>
   <t:import uri="view/jexl/IncludeTop.xml"/>
   <table border="0" width="100%" cellspacing="0" cellpadding="0">
  
  
  
  1.3       +4 -4      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Category.xml
  
  Index: Category.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Category.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Category.xml	6 Apr 2003 06:37:34 -0000	1.2
  +++ Category.xml	21 Apr 2003 05:34:46 -0000	1.3
  @@ -1,12 +1,12 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  -    <site signOn="${accountForm.signOn}" view="jexl">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
  +    <site signOn="${accountForm.signOn}" view="c">
           <backpointer name="Main Menu" do="index.do" />
           <category name="${category.name}">
  -            <jexl:forEach var="prod" items="${productList}" >
  +            <c:forEach var="prod" items="${productList}" >
                   <product name="${prod.name}" id="${prod.productId}"/>
  -            </jexl:forEach>
  +            </c:forEach>
               <situation firstPage="${firstPage}" lastPage="${lastPage}" continuation="${continuation.id}"/>
           </category>
       </site>
  
  
  
  1.3       +13 -13    cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Checkout.xml
  
  Index: Checkout.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Checkout.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Checkout.xml	13 Apr 2003 05:25:18 -0000	1.2
  +++ Checkout.xml	21 Apr 2003 05:34:46 -0000	1.3
  @@ -1,24 +1,24 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  -    <site signOn="${accountForm.signOn}" view="jexl">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
  +    <site signOn="${accountForm.signOn}" view="c">
           <cart name="Checkout Summary">
               <backpointer name="Shopping Cart" do="viewCart.do" />
  -            <jexl:forEach var="cartItem" items="${cartItems}" >
  +            <c:forEach var="cartItem" items="${cartItems}" >
                   <item product-id="${cartItem.item.productId}" id="${cartItem.item.itemId}">
                       <desc>
  -                        <jexl:out value="${cartItem.item.attr1}"/> 
  -                        <jexl:out value="${cartItem.item.attr2}"/> 
  -                        <jexl:out value="${cartItem.item.attr3}"/> 
  -                        <jexl:out value="${cartItem.item.attr4}"/> 
  -                        <jexl:out value="${cartItem.item.attr5}"/> 
  -                        <jexl:out value="${cartItem.item.product.name}"/> 
  +                        ${cartItem.item.attr1} 
  +                        ${cartItem.item.attr2} 
  +                        ${cartItem.item.attr3} 
  +                        ${cartItem.item.attr4} 
  +                        ${cartItem.item.attr5} 
  +                        ${cartItem.item.product.name} 
                       </desc>
  -                    <price><jexl:out value="${cartItem.item.listPrice}"/></price>
  -                    <quantity><jexl:out value="${cartItem.quantity}"/></quantity>
  +                    <price>${cartItem.item.listPrice}</price>
  +                    <quantity>${cartItem.quantity}</quantity>
                   </item>
  -            </jexl:forEach>
  -            <total><jexl:out value="${cartForm.cart.subTotal}"/></total>
  +            </c:forEach>
  +            <total>${cartForm.cart.subTotal}</total>
               <nextpointer img="images/button_continue.gif" do="${continuation.id}.kont"/>
           </cart>
       </site>
  
  
  
  1.2       +21 -21    cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/ConfirmOrder.xml
  
  Index: ConfirmOrder.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/ConfirmOrder.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ConfirmOrder.xml	27 Mar 2003 18:59:23 -0000	1.1
  +++ ConfirmOrder.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,37 +1,37 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <backpointer name="Main Menu" do="index.do" />
           <message>Please confirm the information below and then press continue...</message>
           <panel header="Order #${order.orderId}" subheader="${order.orderDate}">
               <panel label="Payment Details">
  -                <field label="Card Type"><jexl:out value="${order.cardType}" /></field>
  -                <field label="Card Number"><jexl:out value="${order.creditCard}" /></field>
  -                <field label="Expiry Date (MM/YYYY)"><jexl:out value="${order.expiryDate}" /></field>
  +                <field label="Card Type">${order.cardType}</field>
  +                <field label="Card Number">${order.creditCard}</field>
  +                <field label="Expiry Date (MM/YYYY)">${order.expiryDate}</field>
               </panel>
               <panel label="Billing Address">
  -                <field label="First name"><jexl:out value="${order.billToFirstName}}"/></field>
  -                <field label="Last name" ><jexl:out value="${order.billToLastName}"/></field>
  -                <field label="Address 1" ><jexl:out value="${order.billAddress1}"/></field>
  -                <field label="Address 2" ><jexl:out value="${order.billAddress2}"/></field>
  -                <field label="City" ><jexl:out value="${order.billCity}"/></field>
  -                <field label="State" ><jexl:out value="${order.billState}"/></field>
  -                <field label="Zip" ><jexl:out value="${order.billZip}"/></field>
  -                <field label="Country" ><jexl:out value="${order.billCountry}"/></field>
  +                <field label="First name">${order.billToFirstName}</field>
  +                <field label="Last name" >${order.billToLastName}</field>
  +                <field label="Address 1" >${order.billAddress1}</field>
  +                <field label="Address 2" >${order.billAddress2}</field>
  +                <field label="City" >${order.billCity}</field>
  +                <field label="State" >${order.billState}</field>
  +                <field label="Zip" >${order.billZip}</field>
  +                <field label="Country" >${order.billCountry}</field>
               </panel>
               <panel label="Shipping Address">
  -                <field label="First name"><jexl:out value="${order.shipToFirstName}"/></field>
  -                <field label="Last name" ><jexl:out value="${order.shipToLastName}"/></field>
  -                <field label="Address 1" ><jexl:out value="${order.shipAddress1}"/></field>
  -                <field label="Address 2" ><jexl:out value="${order.shipAddress2}"/></field>
  -                <field label="City" ><jexl:out value="${order.shipCity}"/></field>
  -                <field label="State" ><jexl:out value="${order.shipState}"/></field>
  -                <field label="Zip" ><jexl:out value="${order.shipZip}"/></field>
  -                <field label="Country" ><jexl:out value="${order.shipCountry}"/></field>
  +                <field label="First name">${order.shipToFirstName}</field>
  +                <field label="Last name" >${order.shipToLastName}</field>
  +                <field label="Address 1" >${order.shipAddress1}</field>
  +                <field label="Address 2" >${order.shipAddress2}</field>
  +                <field label="City" >${order.shipCity}</field>
  +                <field label="State" >${order.shipState}</field>
  +                <field label="Zip" >${order.shipZip}</field>
  +                <field label="Country" >${order.shipCountry}</field>
               </panel>
           </panel>
  -        <nextpointer img="images/button_continue.gif" do="${continuation.id}.kont?confirmed=true}"/>
  +        <nextpointer img="images/button_continue.gif" do="${continuation.id}.kont?confirmed=true"/>
       </site>
   
   </page>
  
  
  
  1.2       +2 -2      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/IncludeBottom.xml
  
  Index: IncludeBottom.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/IncludeBottom.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- IncludeBottom.xml	15 Apr 2003 20:24:44 -0000	1.1
  +++ IncludeBottom.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,4 +1,4 @@
  -<c:template xmlns:c="http://cocoon.apache.org/transformation/jexl/1.0">
  +<c:template xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
   <br />
   <c:if test="${accountForm.account != null}">
     <c:if test="${accountForm.account.username != null}">
  @@ -8,7 +8,7 @@
   <c:if test="${accountForm.account.bannerName != null}"> 
         <center>
             <image>
  -          <c:out value="${accountForm.account.bannerName}"/>
  +          ${accountForm.account.bannerName}
   	  </image>
         </center>
   </c:if>
  
  
  
  1.2       +1 -1      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/IncludeMyList.xml
  
  Index: IncludeMyList.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/IncludeMyList.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- IncludeMyList.xml	15 Apr 2003 20:24:44 -0000	1.1
  +++ IncludeMyList.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,4 +1,4 @@
  -<t:template xmlns:t="http://cocoon.apache.org/transformation/jexl/1.0">
  +<t:template xmlns:t="http://cocoon.apache.org/generation/jx/1.0">
   <t:if test="${myList != null}">
   <p> </p>
   <table align="right" bgcolor="#008800" border="0" cellspacing="2" cellpadding="3">
  
  
  
  1.2       +1 -1      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/IncludeQuickHeader.xml
  
  Index: IncludeQuickHeader.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/IncludeQuickHeader.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- IncludeQuickHeader.xml	15 Apr 2003 20:24:44 -0000	1.1
  +++ IncludeQuickHeader.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,4 +1,4 @@
  -<t:template xmlns:t="http://cocoon.apache.org/transformation/jexl/1.0">
  +<t:template xmlns:t="http://cocoon.apache.org/generation/jx/1.0">
   
   <center>
   <a href="viewCategory.do?categoryId=FISH">
  
  
  
  1.2       +1 -1      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/IncludeTop.xml
  
  Index: IncludeTop.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/IncludeTop.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- IncludeTop.xml	15 Apr 2003 20:24:44 -0000	1.1
  +++ IncludeTop.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,4 +1,4 @@
  -<t:template xmlns:t="http://cocoon.apache.org/transformation/jexl/1.0">
  +<t:template xmlns:t="http://cocoon.apache.org/generation/jx/1.0">
   
   <table background="images/bkg-topbar.gif" border="0" cellspacing="0" cellpadding="5" width="100%">
     <tbody>
  
  
  
  1.2       +11 -11    cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Item.xml
  
  Index: Item.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Item.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Item.xml	27 Mar 2003 18:59:23 -0000	1.1
  +++ Item.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,21 +1,21 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <backpointer name="${product.name}" do="viewProduct.do?productId=${product.productId}"/>
           <item id="${item.itemId}">
  -            <product-desc><jexl:out value="${product.descn}"/></product-desc>
  -            <product-name><jexl:out value="${product.name}"/></product-name>
  +            <product-desc>${product.descn}</product-desc>
  +            <product-name>${product.name}</product-name>
               <desc>
  -                <jexl:out value="${item.attr1}"/> 
  -                <jexl:out value="${item.attr2}"/> 
  -                <jexl:out value="${item.attr3}"/> 
  -                <jexl:out value="${item.attr4}"/> 
  -                <jexl:out value="${item.attr5}"/> 
  -                <jexl:out value="${item.product.name}"/> 
  +                ${item.attr1} 
  +                ${item.attr2} 
  +                ${item.attr3} 
  +                ${item.attr4} 
  +                ${item.attr5} 
  +                ${item.product.name} 
               </desc>
  -            <instock><jexl:out value="${quantity}"/></instock>
  -            <price><jexl:out value="${item.listPrice}"/></price>
  +            <instock>${quantity}</instock>
  +            <price>${item.listPrice}</price>
           </item>
       </site>
   </page>
  
  
  
  1.2       +4 -4      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/NewAccountForm.xml
  
  Index: NewAccountForm.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/NewAccountForm.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- NewAccountForm.xml	27 Mar 2003 18:59:23 -0000	1.1
  +++ NewAccountForm.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,6 +1,6 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <form method="POST" styleId="workingAccountForm" action="${continuation.id}.kont">
   <!--
  @@ -31,9 +31,9 @@
                       <option value="Japanese">Japanese</option>
                   </select>
                   <select name="workingAccountForm.account.favouriteCategoryId" label="Favourite Category">
  -                    <jexl:forEach var="item" items="${categoryList}" >
  -                        <option value="${item.name}"><jexl:out value="${item.name}" /></option>
  -                    </jexl:forEach>
  +                    <c:forEach var="item" items="${categoryList}" >
  +                        <option value="${item.name}">${item.name}</option>
  +                    </c:forEach>
                   </select>
                   <input type="checkbox" name="workingAccountForm.account.listOption" label="Enable MyList"/> 
                   <input type="checkbox" name="workingAccountForm.account.bannerOption" label="Enable MyBanner"/>
  
  
  
  1.2       +4 -4      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/NewOrderForm.xml
  
  Index: NewOrderForm.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/NewOrderForm.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- NewOrderForm.xml	27 Mar 2003 18:59:23 -0000	1.1
  +++ NewOrderForm.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,14 +1,14 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <form method="POST" styleId="workingOrderForm" action="${continuation.id}.kont">
           <panel>
               <panel label="Payment Details">
                   <select name="order.cardType" label="Card Type">
  -                    <jexl:forEach var="card" items="${creditCardTypes}" >
  -                        <option value="${card}"><jexl:out value="${card}" /></option>
  -                    </jexl:forEach>
  +                    <c:forEach var="card" items="${creditCardTypes}" >
  +                        <option value="${card}">${card}</option>
  +                    </c:forEach>
                   </select>
                   <input type="text" name="creditCard" label="Card Number" />
                   <input type="text" name="expiryDate" label="Expiry Date (MM/YYYY)" />
  
  
  
  1.2       +9 -9      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Product.xml
  
  Index: Product.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/Product.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Product.xml	27 Mar 2003 18:59:23 -0000	1.1
  +++ Product.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,21 +1,21 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <backpointer name="${product.category}" do="viewCategory.do?categoryId=${product.category}"/>
           <product name="${product.name}">
  -            <jexl:forEach var="item" items="${itemList}" >
  +            <c:forEach var="item" items="${itemList}" >
                   <item productId="${item.productId}" id="${item.itemId}">
                       <desc>
  -                        <jexl:out value="${item.attr1}"/> 
  -                        <jexl:out value="${item.attr2}"/> 
  -                        <jexl:out value="${item.attr3}"/> 
  -                        <jexl:out value="${item.attr4}"/> 
  -                        <jexl:out value="${item.attr5}"/> 
  +                        ${item.attr1}
  +                        ${item.attr2}
  +                        ${item.attr3}
  +                        ${item.attr4}
  +                        ${item.attr5}
                       </desc>
  -                    <price><jexl:out value="${item.listPrice}"/></price>
  +                    <price>${item.listPrice}</price>
                   </item>
  -            </jexl:forEach>
  +            </c:forEach>
               <situation firstPage="${firstPage}" lastPage="${lastPage}" continuation="${continuation.id}"/>
           </product>
       </site>
  
  
  
  1.3       +4 -4      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/SearchProducts.xml
  
  Index: SearchProducts.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/SearchProducts.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SearchProducts.xml	13 Apr 2003 05:25:18 -0000	1.2
  +++ SearchProducts.xml	21 Apr 2003 05:34:46 -0000	1.3
  @@ -1,14 +1,14 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <backpointer name="Main Menu" do="index.do" />
           <search>
  -            <jexl:forEach var="item" items="${searchResultsProductList}" >
  +            <c:forEach var="item" items="${searchResultsProductList}" >
                   <product name="${item.name} id="${item.productId}">
  -                    <product-desc><jexl:out value="${descn}"/></product-desc>
  +                    <product-desc>${descn}</product-desc>
                   </product>
  -            </jexl:forEach>
  +            </c:forEach>
               <situation firstPage="${firstPage}" lastPage="${lastPage}" continuation="${continuation.id}"/>
           </search>
       </site>
  
  
  
  1.3       +1 -1      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/ShippingForm.xml
  
  Index: ShippingForm.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/ShippingForm.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ShippingForm.xml	13 Apr 2003 05:25:18 -0000	1.2
  +++ ShippingForm.xml	21 Apr 2003 05:34:46 -0000	1.3
  @@ -1,6 +1,6 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <backpointer name="Main Menu" do="index.do" />
           <form method="POST" styleId="workingOrderForm" action="${continuation.id}.kont">
  
  
  
  1.3       +2 -2      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/SignonForm.xml
  
  Index: SignonForm.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/SignonForm.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SignonForm.xml	13 Apr 2003 05:25:18 -0000	1.2
  +++ SignonForm.xml	21 Apr 2003 05:34:46 -0000	1.3
  @@ -1,9 +1,9 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <form method="POST" label="signon" action="${continuation.id}.kont">
  -            <message type="warning"><jexl:out value="${message}"/></message>
  +            <message type="warning">${message}</message>
               <input type="text" name="username" value="j2ee" label="Username" />
               <input type="password" name="password" value="j2ee" label="Password" />
               <input type="image" src="images/button_submit.gif" name="update" />
  
  
  
  1.2       +32 -32    cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/ViewOrder.xml
  
  Index: ViewOrder.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/ViewOrder.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ViewOrder.xml	27 Mar 2003 18:59:23 -0000	1.1
  +++ ViewOrder.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,54 +1,54 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
           <backpointer name="Main Menu" do="index.do" />
           <message></message>
           <panel header="Order #${order.orderId}" subheader="${order.orderDate}">
               <panel label="Payment Details">
  -                <field label="Card Type"><jexl:out value="${order.cardType}" /></field>
  -                <field label="Card Number"><jexl:out value="${order.creditCard}" /></field>
  -                <field label="Expiry Date (MM/YYYY)"><jexl:out value="${order.expiryDate}" /></field>
  +                <field label="Card Type"><${order.cardType}</field>
  +                <field label="Card Number"><${order.creditCard}</field>
  +                <field label="Expiry Date (MM/YYYY)"><${order.expiryDate}</field>
               </panel>
               <panel label="Billing Address">
  -                <field label="First name"><jexl:out value="${order.billToFirstName}"/></field>
  -                <field label="Last name" ><jexl:out value="${order.billToLastName}"/></field>
  -                <field label="Address 1" ><jexl:out value="${order.billAddress1}"/></field>
  -                <field label="Address 2" ><jexl:out value="${order.billAddress2}"/></field>
  -                <field label="City" ><jexl:out value="${order.billCity}"/></field>
  -                <field label="State" ><jexl:out value="${order.billState}"/></field>
  -                <field label="Zip" ><jexl:out value="${order.billZip}"/></field>
  -                <field label="Country" ><jexl:out value="${order.billCountry}"/></field>
  +                <field label="First name"><${order.billToFirstName}</field>
  +                <field label="Last name" ><${order.billToLastName}</field>
  +                <field label="Address 1" ><${order.billAddress1}</field>
  +                <field label="Address 2" ><${order.billAddress2}</field>
  +                <field label="City" ><${order.billCity}</field>
  +                <field label="State" ><${order.billState}</field>
  +                <field label="Zip" ><${order.billZip}</field>
  +                <field label="Country" ><${order.billCountry}</field>
               </panel>
               <panel label="Shipping Address">
  -                <field label="First name"><jexl:out value="${order.shipToFirstName}"/></field>
  -                <field label="Last name" ><jexl:out value="${order.shipToLastName}"/></field>
  -                <field label="Address 1" ><jexl:out value="${order.shipAddress1}"/></field>
  -                <field label="Address 2" ><jexl:out value="${order.shipAddress2}"/></field>
  -                <field label="City" ><jexl:out value="${order.shipCity}"/></field>
  -                <field label="State" ><jexl:out value="${order.shipState}"/></field>
  -                <field label="Zip" ><jexl:out value="${order.shipZip}"/></field>
  -                <field label="Country" ><jexl:out value="${order.shipCountry}"/></field>
  -                <field label="Courier" ><jexl:out value="${order.courier}"/></field>
  +                <field label="First name"><${order.shipToFirstName}</field>
  +                <field label="Last name" ><${order.shipToLastName}</field>
  +                <field label="Address 1" ><${order.shipAddress1}</field>
  +                <field label="Address 2" ><${order.shipAddress2}</field>
  +                <field label="City" ><${order.shipCity}</field>
  +                <field label="State" ><${order.shipState}</field>
  +                <field label="Zip" ><${order.shipZip}</field>
  +                <field label="Country" ><${order.shipCountry}</field>
  +                <field label="Courier" ><${order.courier}</field>
               </panel>
               <panel label="Status">
                   <field empty="2">
                       <cart name="Status">
  -                        <jexl:forEach var ="cartItem" items="${itemList}" >
  +                        <c:forEach var ="cartItem" items="${itemList}" >
                               <item product-id="${cartItem.item.productId}" id="${cartItem.item.itemId}">
                                   <desc>
  -                                    <jexl:out value="${cartItem.item.attr1}"/> 
  -                                    <jexl:out value="${cartItem.item.attr2}"/> 
  -                                    <jexl:out value="${cartItem.item.attr3}"/> 
  -                                    <jexl:out value="${cartItem.item.attr4}"/> 
  -                                    <jexl:out value="${cartItem.item.attr5}"/> 
  -                                    <jexl:out value="${cartItem.item.product.name}"/> 
  +                                    <${cartItem.item.attr1} 
  +                                    <${cartItem.item.attr2} 
  +                                    <${cartItem.item.attr3} 
  +                                    <${cartItem.item.attr4} 
  +                                    <${cartItem.item.attr5} 
  +                                    <${cartItem.item.product.name} 
                                   </desc>
  -                                <price><jexl:out value="${cartItem.listPrice}"/></price>
  -                                <quantity><jexl:out value="${cartItem.quantity}"/></quantity>
  +                                <price><${cartItem.listPrice}</price>
  +                                <quantity><${cartItem.quantity}</quantity>
                               </item>
  -                        </jexl:forEach>
  -                        <total><jexl:out value="${order.totalPrice}"/></total>
  +                        </c:forEach>
  +                        <total><${order.totalPrice}</total>
                       </cart>
                   </field>
               </panel>
  
  
  
  1.2       +7 -7      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/index.xml
  
  Index: index.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jexl/index.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- index.xml	27 Mar 2003 18:59:23 -0000	1.1
  +++ index.xml	21 Apr 2003 05:34:46 -0000	1.2
  @@ -1,15 +1,15 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jexl="http://cocoon.apache.org/transformation/jexl/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="${accountForm.signOn}" view="jexl">
               <welcome>
  -                <jexl:if test="${!accountForm.signOn}">
  -                    <firstName><jexl:out value="${accountForm.account.firstName}"/></firstName>
  -                </jexl:if>
  +                <c:if test="${!accountForm.signOn}">
  +                    <firstName>${accountForm.account.firstName}</firstName>
  +                </c:if>
                   <menu>
  -                    <jexl:forEach var="item" items="${categoryList}" >
  -                        <category name="${item.name}" id="${item.catId}"/>
  -                    </jexl:forEach>
  +                   <c:forEach var="item" items="${categoryList}" >
  +                      <category name="${item.name}" id="${item.catId}"/>
  +                   </c:forEach>
                   </menu>
               </welcome>
       </site>
  
  
  
  1.6       +3 -9      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Cart.xml
  
  Index: Cart.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Cart.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Cart.xml	15 Apr 2003 21:13:22 -0000	1.5
  +++ Cart.xml	21 Apr 2003 05:34:47 -0000	1.6
  @@ -1,10 +1,4 @@
  -<!-- 
  -     Examples of <import> 
  -     You can use embedded expressions in the import "uri" and you can
  -     [optionally] select a context object for the imported template 
  --->
  -
  -<html xmlns:t="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<html xmlns:t="http://cocoon.apache.org/generation/jx/1.0">
   <body>
   <t:import uri="view/jxpath/IncludeTop.xml"/>
   <table border="0" width="100%" cellspacing="0" cellpadding="0">
  @@ -25,7 +19,7 @@
   <t:if test="#{number(cartForm/cart/numberOfItems) = 0}"> 
   <tr bgcolor="#FFFF88"><td colspan="6"><b>Your cart is empty.</b></td></tr>
   </t:if>
  -<t:for-each select="#{cartItems}">
  +<t:forEach select="#{cartItems}">
     <tr bgcolor="#FFFF88">
     <td><b>
    #{item/itemId}
  @@ -47,7 +41,7 @@
     <td><a href="removeItemFromCart.do?workingItemId=#{item/itemId}">
     <img border="0" src="images/button_remove.gif" /></a></td>
     </tr>
  -</t:for-each>
  +</t:forEach>
   <tr bgcolor="#FFFF88">
   <td colspan="5" align="right">
   
  
  
  
  1.3       +3 -3      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Category.xml
  
  Index: Category.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Category.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Category.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ Category.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,12 +1,12 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <backpointer name="Main Menu" do="index.do" />
           <category name="#{category/name}">
  -            <jxpath:for-each select="productList" >
  +            <c:forEach select="#{productList}" >
                   <product name="#{name}" id="#{productId}"/>
  -            </jxpath:for-each>
  +            </c:forEach>
               <situation firstPage="#{firstPage}" lastPage="#{lastPage}" continuation="#{$continuation/id}"/>
           </category>
       </site>
  
  
  
  1.3       +12 -12    cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Checkout.xml
  
  Index: Checkout.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Checkout.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Checkout.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ Checkout.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,24 +1,24 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <cart name="Checkout Summary">
               <backpointer name="Shopping Cart" do="viewCart.do" />
  -            <jxpath:for-each select="cartItems" >
  +            <c:forEach select="#{cartItems}" >
                   <item product-id="#{item/productId}" id="#{item/itemId}">
                       <desc>
  -                        <jxpath:value-of select="item/attr1"/> 
  -                        <jxpath:value-of select="item/attr2"/> 
  -                        <jxpath:value-of select="item/attr3"/> 
  -                        <jxpath:value-of select="item/attr4"/> 
  -                        <jxpath:value-of select="item/attr5"/> 
  -                        <jxpath:value-of select="item/product/name"/> 
  +                        <c:out value="#{item/attr1}"/> 
  +                        <c:out value="#{item/attr2}"/> 
  +                        <c:out value="#{item/attr3}"/> 
  +                        <c:out value="#{item/attr4}"/> 
  +                        <c:out value="#{item/attr5}"/> 
  +                        <c:out value="#{item/product/name}"/> 
                       </desc>
  -                    <price><jxpath:value-of select="item/listPrice"/></price>
  -                    <quantity><jxpath:value-of select="quantity"/></quantity>
  +                    <price><c:out value="#{item/listPrice}"/></price>
  +                    <quantity><c:out value="#{quantity}"/></quantity>
                   </item>
  -            </jxpath:for-each>
  -            <total><jxpath:value-of select="cartForm/cart/subTotal"/></total>
  +            </c:forEach>
  +            <total><c:out value="#{cartForm/cart/subTotal}"/></total>
               <nextpointer img="images/button_continue.gif" do="#{$continuation/id}.kont"/>
           </cart>
       </site>
  
  
  
  1.4       +20 -20    cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/ConfirmOrder.xml
  
  Index: ConfirmOrder.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/ConfirmOrder.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ConfirmOrder.xml	15 Apr 2003 21:13:22 -0000	1.3
  +++ ConfirmOrder.xml	21 Apr 2003 05:34:47 -0000	1.4
  @@ -1,34 +1,34 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <backpointer name="Main Menu" do="index.do" />
           <message>Please confirm the information below and then press continue...</message>
           <panel header="Order ##{order/orderId}" subheader="#{order/orderDate}">
               <panel label="Payment Details">
  -                <field label="Card Type"><jxpath:value-of select="order/cardType" /></field>
  -                <field label="Card Number"><jxpath:value-of select="order/creditCard" /></field>
  -                <field label="Expiry Date (MM/YYYY)"><jxpath:value-of select="order/expiryDate" /></field>
  +                <field label="Card Type">#{order/cardType}</field>
  +                <field label="Card Number">#{order/creditCard}</field>
  +                <field label="Expiry Date (MM/YYYY)">#{order/expiryDate}</field>
               </panel>
               <panel label="Billing Address">
  -                <field label="First name"><jxpath:value-of select="order/billToFirstName"/></field>
  -                <field label="Last name" ><jxpath:value-of select="order/billToLastName"/></field>
  -                <field label="Address 1" ><jxpath:value-of select="order/billAddress1"/></field>
  -                <field label="Address 2" ><jxpath:value-of select="order/billAddress2"/></field>
  -                <field label="City" ><jxpath:value-of select="order/billCity"/></field>
  -                <field label="State" ><jxpath:value-of select="order/billState"/></field>
  -                <field label="Zip" ><jxpath:value-of select="order/billZip"/></field>
  -                <field label="Country" ><jxpath:value-of select="order/billCountry"/></field>
  +                <field label="First name">#{order/billToFirstName}</field>
  +                <field label="Last name" >#{order/billToLastName}</field>
  +                <field label="Address 1" >#{order/billAddress1}</field>
  +                <field label="Address 2" >#{order/billAddress2}</field>
  +                <field label="City" >#{order/billCity}</field>
  +                <field label="State" >#{order/billState}</field>
  +                <field label="Zip" >#{order/billZip}</field>
  +                <field label="Country" >#{order/billCountry}</field>
               </panel>
               <panel label="Shipping Address">
  -                <field label="First name"><jxpath:value-of select="order/shipToFirstName"/></field>
  -                <field label="Last name" ><jxpath:value-of select="order/shipToLastName"/></field>
  -                <field label="Address 1" ><jxpath:value-of select="order/shipAddress1"/></field>
  -                <field label="Address 2" ><jxpath:value-of select="order/shipAddress2"/></field>
  -                <field label="City" ><jxpath:value-of select="order/shipCity"/></field>
  -                <field label="State" ><jxpath:value-of select="order/shipState"/></field>
  -                <field label="Zip" ><jxpath:value-of select="order/shipZip"/></field>
  -                <field label="Country" ><jxpath:value-of select="order/shipCountry"/></field>
  +                <field label="First name">#{order/shipToFirstName}</field>
  +                <field label="Last name" >#{order/shipToLastName}</field>
  +                <field label="Address 1" >#{order/shipAddress1}</field>
  +                <field label="Address 2" >#{order/shipAddress2}</field>
  +                <field label="City" >#{order/shipCity}</field>
  +                <field label="State" >#{order/shipState}</field>
  +                <field label="Zip" >#{order/shipZip}</field>
  +                <field label="Country" >#{order/shipCountry}</field>
               </panel>
           </panel>
           <nextpointer img="images/button_continue.gif" do="#{$continuation/id}.kont?confirmed=true"/>
  
  
  
  1.3       +2 -2      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/IncludeBottom.xml
  
  Index: IncludeBottom.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/IncludeBottom.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- IncludeBottom.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ IncludeBottom.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,4 +1,4 @@
  -<c:template xmlns:c="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<c:template xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
   <br />
   <c:if test="#{accountForm/account}">
     <c:if test="#{accountForm/account/username}">
  @@ -8,7 +8,7 @@
   <c:if test="#{accountForm/account/bannerName}"> 
         <center>
             <image>
  -          <c:value-of select="#{accountForm/account/bannerName}"/>
  +          #{accountForm/account/bannerName}
   	  </image>
         </center>
   </c:if>
  
  
  
  1.3       +3 -3      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/IncludeMyList.xml
  
  Index: IncludeMyList.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/IncludeMyList.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- IncludeMyList.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ IncludeMyList.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,4 +1,4 @@
  -<t:template xmlns:t="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<t:template xmlns:t="http://cocoon.apache.org/generation/jx/1.0">
   <t:if test="#{myList}">
   <p> </p>
   <table align="right" bgcolor="#008800" border="0" cellspacing="2" cellpadding="3">
  @@ -8,13 +8,13 @@
     </td></tr>
     <tr bgcolor="#FFFF88">
     <td>
  -<t:for-each select="#{myList}"> 
  +<t:forEach select="#{myList}"> 
       <a href="viewProduct.do?productId=#{product/productId}">
           #{product/name}</a>
       <br />
       <font size="2">#{product/productId}</font>
       <br />
  -</t:for-each>
  +</t:forEach>
     </td>
     </tr>
     <tr>
  
  
  
  1.2       +1 -1      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/IncludeQuickHeader.xml
  
  Index: IncludeQuickHeader.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/IncludeQuickHeader.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- IncludeQuickHeader.xml	14 Apr 2003 15:54:41 -0000	1.1
  +++ IncludeQuickHeader.xml	21 Apr 2003 05:34:47 -0000	1.2
  @@ -1,4 +1,4 @@
  -<t:template xmlns:t="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<t:template xmlns:t="http://cocoon.apache.org/generation/jx/1.0">
   
   <center>
   <a href="viewCategory.do?categoryId=FISH">
  
  
  
  1.3       +3 -3      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/IncludeTop.xml
  
  Index: IncludeTop.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/IncludeTop.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- IncludeTop.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ IncludeTop.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,4 +1,4 @@
  -<t:template xmlns:t="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<t:template xmlns:t="http://cocoon.apache.org/generation/jx/1.0">
   
   <table background="images/bkg-topbar.gif" border="0" cellspacing="0" cellpadding="5" width="100%">
     <tbody>
  @@ -45,10 +45,10 @@
   
   <!-- Support for non-traditional but simpler use of errors... -->
   <t:if test="#{errors}">
  -  <t:for-each select="#{errors}">
  +  <t:forEach select="#{errors}">
       <B><FONT color="RED">
         <BR>#{.}</BR>
       </FONT></B>
  -  </t:for-each>
  +  </t:forEach>
   </t:if>
   </t:template>
  
  
  
  1.3       +11 -11    cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Item.xml
  
  Index: Item.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Item.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Item.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ Item.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,21 +1,21 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <backpointer name="#{product/name}" do="viewProduct.do?productId=#{product/productId}"/>
           <item id="#{item/itemId}">
  -            <product-desc><jxpath:value-of select="product/descn"/></product-desc>
  -            <product-name><jxpath:value-of select="product/name"/></product-name>
  +            <product-desc>#{product/descn}</product-desc>
  +            <product-name>#{product/name}</product-name>
               <desc>
  -                <jxpath:value-of select="item/attr1"/> 
  -                <jxpath:value-of select="item/attr2"/> 
  -                <jxpath:value-of select="item/attr3"/> 
  -                <jxpath:value-of select="item/attr4"/> 
  -                <jxpath:value-of select="item/attr5"/> 
  -                <jxpath:value-of select="item/product/name"/> 
  +                #{item/attr1}
  +                #{item/attr2}
  +                #{item/attr3}
  +                #{item/attr4}
  +                #{item/attr5}
  +                #{item/product/name}
               </desc>
  -            <instock><jxpath:value-of select="quantity"/></instock>
  -            <price><jxpath:value-of select="item/listPrice"/></price>
  +            <instock>#{quantity}</instock>
  +            <price>#{item/listPrice}</price>
           </item>
   
       </site>
  
  
  
  1.3       +4 -4      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/NewAccountForm.xml
  
  Index: NewAccountForm.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/NewAccountForm.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- NewAccountForm.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ NewAccountForm.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,6 +1,6 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <form method="POST" styleId="workingAccountForm" action="#{$continuation/id}.kont">
   <!--
  @@ -31,9 +31,9 @@
                       <option value="Japanese">Japanese</option>
                   </select>
                   <select name="workingAccountForm.account.favouriteCategoryId" label="Favourite Category">
  -                    <jxpath:for-each select="categoryList" >
  -                        <option value="{name}"><jxpath:value-of select="name" /></option>
  -                    </jxpath:for-each>
  +                    <c:forEach select="#{categoryList}" >
  +                        <option value="#{name}">#{name}</option>
  +                    </c:forEach>
                   </select>
                   <input type="checkbox" name="workingAccountForm.account.listOption" label="Enable MyList"/> 
                   <input type="checkbox" name="workingAccountForm.account.bannerOption" label="Enable MyBanner"/>
  
  
  
  1.5       +4 -4      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/NewOrderForm.xml
  
  Index: NewOrderForm.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/NewOrderForm.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- NewOrderForm.xml	15 Apr 2003 21:13:22 -0000	1.4
  +++ NewOrderForm.xml	21 Apr 2003 05:34:47 -0000	1.5
  @@ -1,14 +1,14 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <form method="POST" styleId="workingOrderForm" action="#{$continuation/id}.kont">
           <panel>
               <panel label="Payment Details">
                   <select name="order.cardType" label="Card Type">
  -                    <jxpath:for-each select="creditCardTypes" >
  -                        <option value="#{.}"><jxpath:value-of select="." /></option>
  -                    </jxpath:for-each>
  +                    <c:forEach select="#{creditCardTypes}" >
  +                        <option value="#{.}">#{.}</option>
  +                    </c:forEach>
                   </select>
                   <input type="text" name="creditCard" label="Card Number" />
                   <input type="text" name="expiryDate" label="Expiry Date (MM/YYYY)" />
  
  
  
  1.3       +9 -9      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Product.xml
  
  Index: Product.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/Product.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Product.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ Product.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,21 +1,21 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <backpointer name="#{product/category}" do="viewCategory.do?categoryId=#{product/category}"/>
           <product name="#{product/name}">
  -            <jxpath:for-each select="itemList" >
  +            <c:forEach select="#{itemList}" >
                   <item productId="#{productId}" id="#{itemId}">
                       <desc>
  -                        <jxpath:value-of select="attr1"/> 
  -                        <jxpath:value-of select="attr2"/> 
  -                        <jxpath:value-of select="attr3"/> 
  -                        <jxpath:value-of select="attr4"/> 
  -                        <jxpath:value-of select="attr5"/> 
  +                        #{attr1}
  +                        #{attr2}
  +                        #{attr3}
  +                        #{attr4}
  +                        #{attr5}
                       </desc>
  -                    <price><jxpath:value-of select="listPrice"/></price>
  +                    <price>#{listPrice}</price>
                   </item>
  -            </jxpath:for-each>
  +            </c:forEach>
               <situation firstPage="#{firstPage}" lastPage="#{lastPage}" continuation="#{$continuation/id}"/>
           </product>
       </site>
  
  
  
  1.3       +4 -4      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/SearchProducts.xml
  
  Index: SearchProducts.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/SearchProducts.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SearchProducts.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ SearchProducts.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,14 +1,14 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/transformation/jxpath/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <backpointer name="Main Menu" do="index.do" />
           <search>
  -            <jxpath:for-each select="searchResultsProductList" >
  +            <c:forEach select="#{searchResultsProductList}" >
                   <product name="#{name}" id="#{productId}">
  -                    <product-desc><jxpath:value-of select="descn"/></product-desc>
  +                    <product-desc>#{descn}</product-desc>
                   </product>
  -            </jxpath:for-each>
  +            </c:forEach>
               <situation firstPage="#{firstPage}" lastPage="#{lastPage}" continuation="#{$continuation/id}"/>
           </search>
       </site>
  
  
  
  1.3       +1 -1      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/ShippingForm.xml
  
  Index: ShippingForm.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/ShippingForm.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ShippingForm.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ ShippingForm.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,6 +1,6 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <backpointer name="Main Menu" do="index.do" />
           <form method="POST" styleId="workingOrderForm" action="#{$continuation/id}.kont">
  
  
  
  1.3       +2 -2      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/SignonForm.xml
  
  Index: SignonForm.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/SignonForm.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SignonForm.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ SignonForm.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,9 +1,9 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <form method="POST" label="signon" action="#{$continuation/id}.kont">
  -            <message type="warning"><jxpath:value-of select="//message"/></message>
  +            <message type="warning">#{//message}</message>
               <input type="text" name="username" value="j2ee" label="Username" />
               <input type="password" name="password" value="j2ee" label="Password" />
               <input type="image" src="images/button_submit.gif" name="update" />
  
  
  
  1.4       +32 -32    cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/ViewOrder.xml
  
  Index: ViewOrder.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/ViewOrder.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ViewOrder.xml	15 Apr 2003 21:13:22 -0000	1.3
  +++ ViewOrder.xml	21 Apr 2003 05:34:47 -0000	1.4
  @@ -1,54 +1,54 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
           <backpointer name="Main Menu" do="index.do" />
           <message></message>
           <panel header="Order ##{order/orderId}" subheader="#{order/orderDate}">
               <panel label="Payment Details">
  -                <field label="Card Type"><jxpath:value-of select="order/cardType" /></field>
  -                <field label="Card Number"><jxpath:value-of select="order/creditCard" /></field>
  -                <field label="Expiry Date (MM/YYYY)"><jxpath:value-of select="order/expiryDate" /></field>
  +                <field label="Card Type">#{order/cardType}</field>
  +                <field label="Card Number">#{order/creditCard}</field>
  +                <field label="Expiry Date (MM/YYYY)">#{order/expiryDate}</field>
               </panel>
               <panel label="Billing Address">
  -                <field label="First name"><jxpath:value-of select="order/billToFirstName"/></field>
  -                <field label="Last name" ><jxpath:value-of select="order/billToLastName"/></field>
  -                <field label="Address 1" ><jxpath:value-of select="order/billAddress1"/></field>
  -                <field label="Address 2" ><jxpath:value-of select="order/billAddress2"/></field>
  -                <field label="City" ><jxpath:value-of select="order/billCity"/></field>
  -                <field label="State" ><jxpath:value-of select="order/billState"/></field>
  -                <field label="Zip" ><jxpath:value-of select="order/billZip"/></field>
  -                <field label="Country" ><jxpath:value-of select="order/billCountry"/></field>
  +                <field label="First name">#{order/billToFirstName}</field>
  +                <field label="Last name" >#{order/billToLastName}</field>
  +                <field label="Address 1" >#{order/billAddress1}</field>
  +                <field label="Address 2" >#{order/billAddress2}</field>
  +                <field label="City" >#{order/billCity}</field>
  +                <field label="State" >#{order/billState}</field>
  +                <field label="Zip" >#{order/billZip}</field>
  +                <field label="Country" >#{order/billCountry}</field>
               </panel>
               <panel label="Shipping Address">
  -                <field label="First name"><jxpath:value-of select="order/shipToFirstName"/></field>
  -                <field label="Last name" ><jxpath:value-of select="order/shipToLastName"/></field>
  -                <field label="Address 1" ><jxpath:value-of select="order/shipAddress1"/></field>
  -                <field label="Address 2" ><jxpath:value-of select="order/shipAddress2"/></field>
  -                <field label="City" ><jxpath:value-of select="order/shipCity"/></field>
  -                <field label="State" ><jxpath:value-of select="order/shipState"/></field>
  -                <field label="Zip" ><jxpath:value-of select="order/shipZip"/></field>
  -                <field label="Country" ><jxpath:value-of select="order/shipCountry"/></field>
  -                <field label="Courier" ><jxpath:value-of select="order/courier"/></field>
  +                <field label="First name">#{order/shipToFirstName}</field>
  +                <field label="Last name" >#{order/shipToLastName}</field>
  +                <field label="Address 1" >#{order/shipAddress1}</field>
  +                <field label="Address 2" >#{order/shipAddress2}</field>
  +                <field label="City" >#{order/shipCity}</field>
  +                <field label="State" >#{order/shipState}</field>
  +                <field label="Zip" >#{order/shipZip}</field>
  +                <field label="Country" >#{order/shipCountry}</field>
  +                <field label="Courier" >#{order/courier}</field>
               </panel>
               <panel label="Status">
                   <field empty="2">
                       <cart name="Status">
  -                        <jxpath:for-each select="itemList" >
  +                        <c:forEach select="#{itemList}" >
                               <item product-id="#{item/productId}" id="#{item/itemId}">
                                   <desc>
  -                                    <jxpath:value-of select="item/attr1"/> 
  -                                    <jxpath:value-of select="item/attr2"/> 
  -                                    <jxpath:value-of select="item/attr3"/> 
  -                                    <jxpath:value-of select="item/attr4"/> 
  -                                    <jxpath:value-of select="item/attr5"/> 
  -                                    <jxpath:value-of select="item/product/name"/> 
  +                                    #{item/attr1} 
  +                                    #{item/attr2} 
  +                                    #{item/attr3} 
  +                                    #{item/attr4} 
  +                                    #{item/attr5} 
  +                                    #{item/product/name} 
                                   </desc>
  -                                <price><jxpath:value-of select="item/listPrice"/></price>
  -                                <quantity><jxpath:value-of select="quantity"/></quantity>
  +                                <price>#{item/listPrice}</price>
  +                                <quantity>#{quantity}</quantity>
                               </item>
  -                        </jxpath:for-each>
  -                        <total><jxpath:value-of select="order/totalPrice"/></total>
  +                        </c:forEach>
  +                        <total>#{order/totalPrice}</total>
                       </cart>
                   </field>
               </panel>
  
  
  
  1.3       +6 -6      cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/index.xml
  
  Index: index.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/scratchpad/webapp/samples/petstore/view/jxpath/index.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- index.xml	15 Apr 2003 21:13:22 -0000	1.2
  +++ index.xml	21 Apr 2003 05:34:47 -0000	1.3
  @@ -1,15 +1,15 @@
   <?xml version="1.0"?>
   
  -<page xmlns:jxpath="http://cocoon.apache.org/transformation/jxpath/1.0">
  +<page xmlns:c="http://cocoon.apache.org/generation/jx/1.0">
       <site signOn="#{accountForm/signOn}" view="jxpath">
               <welcome>
  -                <jxpath:if test="not(accountForm/signOn)">
  -                    <firstName><jxpath:value-of select="accountForm/account/firstName"/></firstName>
  -                </jxpath:if>
  +                <c:if test="#{not(accountForm/signOn)}">
  +                    <firstName>#{accountForm/account/firstName}</firstName>
  +                </c:if>
                   <menu>
  -                    <jxpath:for-each select="categoryList" >
  +                    <c:forEach select="#{categoryList}" >
                           <category name="#{name}" id="#{catId}"/>
  -                    </jxpath:for-each>
  +                    </c:forEach>
                   </menu>
               </welcome>
       </site>