# For JSTL changes:
#   http://jcp.org/aboutJava/communityprocess/maintenance/jsr052/jstl-1_2-mr-changeLog_PFD.html

# Build system changes. New versions of spec jars (servlet, jsp, el). Cactus fix.
M      build_sample_standard.properties
M      build-tests.xml
M      build.xml

# old tld is copied to the side for history. New tld sees some name/version changing and the addition of
# deferred value (as per JSTL change #1) to:
## ForEachTag
## ForTokensTag
## SetTag
A      conf/c-1_1.tld
M      conf/c.tld

# OutputProperties replaced with OutputPropertiesFactory. Deprecated method change in Xalan.
M      src/org/apache/taglibs/standard/extra/spath/SPathFilter.java

# Change the version. Not spec related.
M      src/org/apache/taglibs/standard/Version.java

# setItems moved from String to Object. JSTL change #1
M      src/org/apache/taglibs/standard/tag/rt/core/ForTokensTag.java

# Support for Java 6 JDBC; AND SecurityManager code added to a call to get ClassLoader
M      src/org/apache/taglibs/standard/tag/common/sql/DataSourceWrapper.java

# SecurityManager code added to call to get ClassLoader
M      src/org/apache/taglibs/standard/tag/common/fmt/BundleSupport.java

# Test related to Version change
M      test/org/apache/taglibs/standard/TestVersion.java

# Generified method as per JSTL change #3
M      src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java

# New method added for JSP 2.1 additional method in stub class
M      test/org/apache/taglibs/standard/lang/jstl/test/PageContextImpl.java

# Large change to support JSTL change #2
#TODO# Commented out section with question in may need deleting or uncommenting
# Also the convertToExpectedType method is changed to use new EL API.
M      src/org/apache/taglibs/standard/tag/common/core/SetSupport.java

# Changes to support JSTL change #1. Not as large as it looks - code was indented.
M      src/javax/servlet/jsp/jstl/core/LoopTagSupport.java

# Large change to support JSTL change #1
#TODO# Various questions in determineLengthAndType to look at
#TODO# prepare has commented out code in it to consider deleting
M      src/org/apache/taglibs/standard/tag/common/core/ForEachSupport.java

# Large change to support JSTL change #1
M      src/org/apache/taglibs/standard/tag/common/core/ForTokensSupport.java

# New classes in JSTL 1.2. Only mention in spec is the javadoc,
# but they're there to support change#1 by the look of it.
#TODO# Need javadoc explaining all three.

A      src/javax/servlet/jsp/jstl/core/IteratedExpression.java

#TODO# Ensure equals() method is explained. Broken hashcode contract?
A      src/javax/servlet/jsp/jstl/core/IndexedValueExpression.java
A      src/javax/servlet/jsp/jstl/core/IteratedValueExpression.java


diff --git a/build-tests.xml b/build-tests.xml
index aa9acb6..a6fde56 100644
--- a/build-tests.xml
+++ b/build-tests.xml
@@ -20,8 +20,9 @@
         jstl.jar                      JSTL API jar file
         standard.jar                  JSTL implementation jar file
 
-        servlet24.jar                 Servlet 2.4 jar
-        jsp20.jar                     JSP 2.0 jar
+        servlet25.jar                 Servlet 2.5 jar
+        jsp21.jar                     JSP 2.1 jar
+        el.jar                        Unified EL jar
 
         junit.jar                     JUnit jar
 
@@ -99,6 +100,9 @@
   <property name="junit.jar" 
             value="${tomcat.home}/../junit3.8.1/junit.jar"/>
 
+  <property name="commons-logging.jar" 
+            value="${cactus.home}/lib/commons-logging-1.0.4.jar"/>
+
   <property name="standard.jar" 
             value="${tomcat.home}/jstl/lib/standard.jar"/>
     
@@ -125,9 +129,11 @@
     <echo>optimize: ${compile.optimize}</echo>
     <echo>---------- Dependencies ---------------------</echo>
     <echo>tomcat.home=${tomcat.home}</echo>
-    <echo>servlet24.jar: ${servlet24.jar}</echo>
-    <echo>jsp20.jar: ${jsp20.jar}</echo>
+    <echo>servlet25.jar: ${servlet25.jar}</echo>
+    <echo>jsp21.jar: ${jsp21.jar}</echo>
+    <echo>el.jar: ${el.jar}</echo>
     <echo>junit.jar: ${junit.jar}</echo>
+    <echo>commons-logging.jar: ${commons-logging.jar}</echo>
     <echo>cactus.home: ${cactus.home}</echo>
     <echo>cactus.ant.jar: ${cactus.ant.jar}</echo>
     <echo>cactus.jar: ${cactus.jar}</echo>
@@ -150,9 +156,11 @@
   <path id="compile.classpath">
     <pathelement location="${jstl.jar}"/>
     <pathelement location="${standard.jar}"/>
-    <pathelement location="${servlet24.jar}"/>
-    <pathelement location="${jsp20.jar}"/>
+    <pathelement location="${servlet25.jar}"/>
+    <pathelement location="${jsp21.jar}"/>
+    <pathelement location="${el.jar}"/>
     <pathelement location="${junit.jar}"/>
+    <pathelement location="${commons-logging.jar}"/>
     <pathelement location="${cactus.jar}"/>
     <pathelement location="${httpclient.jar}"/>
     <pathelement location="${aspectjrt.jar}"/>
@@ -243,6 +251,7 @@
     <copy file="${jstl.jar}" todir="${out.test.dir}/WEB-INF/lib"/>
     <copy file="${standard.jar}" todir="${out.test.dir}/WEB-INF/lib"/>
     <copy file="${junit.jar}" todir="${out.test.dir}/WEB-INF/lib"/>
+    <copy file="${commons-logging.jar}" todir="${out.test.dir}/WEB-INF/lib"/>
     <copy file="${cactus.jar}" todir="${out.test.dir}/WEB-INF/lib"/>
     <copy file="${httpclient.jar}" todir="${out.test.dir}/WEB-INF/lib"/>
     <copy file="${aspectjrt.jar}" todir="${out.test.dir}/WEB-INF/lib"/>
@@ -377,7 +386,7 @@
           <include name="**/TestVersion.java"/>
           <include name="**/StaticFunctionTests.java"/>
           <include name="**/ParserTest.java"/>
-          <exclude name="**/EvaluationTest.java"/>
+          <include name="**/EvaluationTest.java"/>
           <exclude name="**/testutil/*.java"/>
         </fileset>
       </batchtest>
diff --git a/build.xml b/build.xml
index 52f174a..8582a6e 100644
--- a/build.xml
+++ b/build.xml
@@ -4,7 +4,7 @@
   <!-- Version Number                                                      -->
   <!-- =================================================================== -->
 
-  <property name="standard-version" value="1.1.2" />
+  <property name="standard-version" value="1.2.0" />
   <property name="release.name" value="jakarta-taglibs-standard-${standard-version}" />
   <property name="release.pre" value="nop" />
   <property name="release.post" value="nop" />
@@ -54,8 +54,9 @@
     <echo>deprecation: ${compile.deprecation}</echo>
     <echo>optimize: ${optimize.debug}</echo>
     <echo>---------- Dependencies ---------------------</echo>
-    <echo>servlet24.jar: ${servlet24.jar}</echo>
-    <echo>jsp20.jar: ${jsp20.jar}</echo>
+    <echo>servlet25.jar: ${servlet25.jar}</echo>
+    <echo>jsp21.jar: ${jsp21.jar}</echo>
+    <echo>el.jar: ${el.jar}</echo>
     <echo>jdbc2_0-stdext.jar: ${jdbc2_0-stdext.jar}</echo>
     <echo>jaxp-api.jar: ${jaxp-api.jar}</echo>
     <echo>dom.jar: ${dom.jar}</echo>
@@ -78,15 +79,21 @@
     <!-- Check the build/runtime dependencies -->
 
     <antcall target="requiredJar">
-       <param name="prop" value="servlet24.jar"/>
-       <param name="file" value="${servlet24.jar}"/>
-       <param name="desc" value="Servlet 2.4 API classes"/>
+       <param name="prop" value="servlet25.jar"/>
+       <param name="file" value="${servlet25.jar}"/>
+       <param name="desc" value="Servlet 2.5 API classes"/>
     </antcall>
 
     <antcall target="requiredJar">
-       <param name="prop" value="jsp20.jar"/>
-       <param name="file" value="${jsp20.jar}"/>
-       <param name="desc" value="JSP 2.0 API classes"/>
+       <param name="prop" value="jsp21.jar"/>
+       <param name="file" value="${jsp21.jar}"/>
+       <param name="desc" value="JSP 2.1 API classes"/>
+    </antcall>
+
+    <antcall target="requiredJar">
+       <param name="prop" value="el.jar"/>
+       <param name="file" value="${el.jar}"/>
+       <param name="desc" value="Unified EL API classes"/>
     </antcall>
 
     <antcall target="processIfPropSet">
@@ -173,7 +180,7 @@
       srcdir="${library.src}" 
       destdir="${build.library}/classes"
       bootclasspath="${xalan.jar}:${java.runtime.jar}"
-      classpath="${servlet24.jar}:${jsp20.jar}:${jdbc2_0-stdext.jar}:${jaxp-api.jar}:${dom.jar}:${sax.jar}"
+      classpath="${servlet25.jar}:${jsp21.jar}:${el.jar}:${jdbc2_0-stdext.jar}:${jaxp-api.jar}:${dom.jar}:${sax.jar}"
       excludes="org/apache/taglibs/standard/lang/jstl/parser/jsp20/* org/apache/taglibs/standard/lang/jpath/** org/apache/taglibs/standard/lang/spel/**"
       debug="${compile.debug}"
       deprecation="${compile.deprecation}"
@@ -276,7 +283,7 @@
 
     <!-- Compile the examples source code -->
     <javac srcdir="${examples.src}" destdir="${build.examples}/WEB-INF/classes"
-           classpath="${servlet24.jar}:${jsp20.jar}:${build.library}/classes"
+           classpath="${servlet25.jar}:${jsp21.jar}:${el.jar}:${build.library}/classes"
            debug="${compile.debug}"
            deprecation="${compile.deprecation}"
            optimize="${compile.optimize}"/>
@@ -362,7 +369,7 @@
   <target name="javadoc-dist" depends="prepare-dist">
    <javadoc packagenames="javax.servlet.jsp.jstl.*"
             sourcepath="src"
-            classpath="${servlet24.jar}:${jsp20.jar}:${jdbc2_0-stdext.jar}:${jaxp-api.jar}:${dom.jar}:${sax.jar}:${xercesImpl.jar}:${xalan.jar}"
+            classpath="${servlet25.jar}:${jsp21.jar}:${el.jar}:${jdbc2_0-stdext.jar}:${jaxp-api.jar}:${dom.jar}:${sax.jar}:${xercesImpl.jar}:${xalan.jar}"
             destdir="${dist.library}/javadoc"
             bottom='&lt;font size="-1"&gt;Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.&lt;/font&gt;'/>
   </target>
diff --git a/build_sample_standard.properties b/build_sample_standard.properties
index 217647e..5d32d27 100644
--- a/build_sample_standard.properties
+++ b/build_sample_standard.properties
@@ -66,12 +66,12 @@
 junit.jar=
 
 cactus.home=
-cactus.jar=${cactus.home}/lib/cactus-1.6.1.jar
-cactus.ant.jar=${cactus.home}/lib/cactus-ant-1.6.1.jar
-aspectjrt.jar=${cactus.home}/lib/aspectjrt-1.1.1.jar
-httpclient.jar=${cactus.home}/lib/commons-httpclient-2.0.jar
-commons-logging.jar=${cactus.home}/lib/commons-logging-1.0.3.jar
-derby.jar=${cactus.home}/lib/derby-10.2.2.0.jar
+cactus.jar=${cactus.home}/lib/cactus-1.7.1.jar
+cactus.ant.jar=${cactus.home}/lib/cactus-ant-1.7.1.jar
+aspectjrt.jar=${cactus.home}/lib/aspectjrt-1.2.1.jar
+httpclient.jar=${cactus.home}/lib/commons-httpclient-2.0.2.jar
+commons-logging.jar=${cactus.home}/lib/commons-logging-1.0.4.jar
+derby.jar=
 
 # --------------------------------------------------
 #   RUN-TIME COMPONENTS FOR UNIT TESTS
diff --git a/conf/c-1_1.tld b/conf/c-1_1.tld
new file mode 100644
index 0000000..71d3a86
--- /dev/null
+++ b/conf/c-1_1.tld
@@ -0,0 +1,563 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
+    version="2.0">
+    
+  <description>JSTL 1.1 core library</description>
+  <display-name>JSTL core</display-name>
+  <tlib-version>1.1</tlib-version>
+  <short-name>c</short-name>
+  <uri>http://java.sun.com/jsp/jstl/core_1_1</uri>
+
+  <validator>
+    <description>
+        Provides core validation features for JSTL tags.
+    </description>
+    <validator-class>
+        org.apache.taglibs.standard.tlv.JstlCoreTLV
+    </validator-class>
+  </validator>
+
+  <tag>
+    <description>
+        Catches any Throwable that occurs in its body and optionally
+        exposes it.
+    </description>
+    <name>catch</name>
+    <tag-class>org.apache.taglibs.standard.tag.common.core.CatchTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+exception thrown from a nested action. The type of the
+scoped variable is the type of the exception thrown.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+	Simple conditional tag that establishes a context for
+	mutually exclusive conditional operations, marked by
+	&lt;when&gt; and &lt;otherwise&gt;
+    </description>
+    <name>choose</name>
+    <tag-class>org.apache.taglibs.standard.tag.common.core.ChooseTag</tag-class>
+    <body-content>JSP</body-content>
+  </tag>
+
+  <tag>
+    <description>
+	Simple conditional tag, which evalutes its body if the
+	supplied condition is true and optionally exposes a Boolean
+	scripting variable representing the evaluation of this condition
+    </description>
+    <name>if</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The test condition that determines whether or
+not the body content should be processed.
+        </description>
+        <name>test</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+	<type>boolean</type>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+resulting value of the test condition. The type
+of the scoped variable is Boolean.        
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Retrieves an absolute or relative URL and exposes its contents
+        to either the page, a String in 'var', or a Reader in 'varReader'.
+    </description>
+    <name>import</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.ImportTag</tag-class>
+    <tei-class>org.apache.taglibs.standard.tei.ImportTEI</tei-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The URL of the resource to import.
+        </description>
+        <name>url</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+resource's content. The type of the scoped
+variable is String.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+resource's content. The type of the scoped
+variable is Reader.
+        </description>
+        <name>varReader</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the context when accessing a relative
+URL resource that belongs to a foreign
+context.
+        </description>
+        <name>context</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Character encoding of the content at the input
+resource.
+        </description>
+        <name>charEncoding</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+	The basic iteration tag, accepting many different
+        collection types and supporting subsetting and other
+        functionality
+    </description>
+    <name>forEach</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.ForEachTag</tag-class>
+    <tei-class>org.apache.taglibs.standard.tei.ForEachTEI</tei-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Collection of items to iterate over.
+        </description>
+	<name>items</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>java.lang.Object</type>
+    </attribute>
+    <attribute>
+        <description>
+If items specified:
+Iteration begins at the item located at the
+specified index. First item of the collection has
+index 0.
+If items not specified:
+Iteration begins with index set at the value
+specified.
+        </description>
+	<name>begin</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+If items specified:
+Iteration ends at the item located at the
+specified index (inclusive).
+If items not specified:
+Iteration ends when index reaches the value
+specified.
+        </description>
+	<name>end</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Iteration will only process every step items of
+the collection, starting with the first one.
+        </description>
+	<name>step</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+current item of the iteration. This scoped
+variable has nested visibility. Its type depends
+on the object of the underlying collection.
+        </description>
+	<name>var</name>
+	<required>false</required>
+	<rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+status of the iteration. Object exported is of type
+javax.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested
+visibility.
+        </description>
+	<name>varStatus</name>
+	<required>false</required>
+	<rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+	Iterates over tokens, separated by the supplied delimeters
+    </description>
+    <name>forTokens</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.ForTokensTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+String of tokens to iterate over.
+        </description>
+	<name>items</name>
+	<required>true</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>java.lang.String</type>
+    </attribute>
+    <attribute>
+        <description>
+The set of delimiters (the characters that
+separate the tokens in the string).
+        </description>
+	<name>delims</name>
+	<required>true</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>java.lang.String</type>
+    </attribute>
+    <attribute>
+        <description>
+Iteration begins at the token located at the
+specified index. First token has index 0.
+        </description>
+	<name>begin</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Iteration ends at the token located at the
+specified index (inclusive).
+        </description>
+	<name>end</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Iteration will only process every step tokens
+of the string, starting with the first one.
+        </description>
+	<name>step</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+current item of the iteration. This scoped
+variable has nested visibility.
+        </description>
+	<name>var</name>
+	<required>false</required>
+	<rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+status of the iteration. Object exported is of
+type
+javax.servlet.jsp.jstl.core.LoopTag
+Status. This scoped variable has nested
+visibility.
+        </description>
+	<name>varStatus</name>
+	<required>false</required>
+	<rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Like &lt;%= ... &gt;, but for expressions.
+    </description> 
+    <name>out</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.OutTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Expression to be evaluated.
+        </description>
+        <name>value</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Default value if the resulting value is null.
+        </description>
+        <name>default</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Determines whether characters &lt;,&gt;,&amp;,'," in the
+resulting string should be converted to their
+corresponding character entity codes. Default value is
+true.
+        </description>
+        <name>escapeXml</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+
+  <tag>
+    <description>
+        Subtag of &lt;choose&gt; that follows &lt;when&gt; tags
+        and runs only if all of the prior conditions evaluated to
+        'false'
+    </description>
+    <name>otherwise</name>
+    <tag-class>org.apache.taglibs.standard.tag.common.core.OtherwiseTag</tag-class>
+    <body-content>JSP</body-content>
+  </tag>
+
+  <tag>
+    <description>
+        Adds a parameter to a containing 'import' tag's URL.
+    </description>
+    <name>param</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.ParamTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Name of the query string parameter.
+        </description>
+        <name>name</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Value of the parameter.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Redirects to a new URL.
+    </description>
+    <name>redirect</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.RedirectTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The URL of the resource to redirect to.
+        </description>
+        <name>url</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the context when redirecting to a relative URL
+resource that belongs to a foreign context.
+        </description>
+        <name>context</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Removes a scoped variable (from a particular scope, if specified).
+    </description>
+    <name>remove</name>
+    <tag-class>org.apache.taglibs.standard.tag.common.core.RemoveTag</tag-class>
+    <body-content>empty</body-content>
+    <attribute>
+        <description>
+Name of the scoped variable to be removed.
+        </description>
+        <name>var</name>
+        <required>true</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+ <tag>
+    <description>
+        Sets the result of an expression evaluation in a 'scope'
+    </description>
+    <name>set</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.SetTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Name of the exported scoped variable to hold the value
+specified in the action. The type of the scoped variable is
+whatever type the value expression evaluates to.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Expression to be evaluated.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Target object whose property will be set. Must evaluate to
+a JavaBeans object with setter property property, or to a
+java.util.Map object.
+        </description>
+        <name>target</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the property to be set in the target object.
+        </description>
+        <name>property</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Creates a URL with optional query parameters.
+    </description>
+    <name>url</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.UrlTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+processed url. The type of the scoped variable is
+String.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+URL to be processed.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the context when specifying a relative URL
+resource that belongs to a foreign context.
+        </description>
+        <name>context</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+	Subtag of &lt;choose&gt; that includes its body if its
+	condition evalutes to 'true'
+    </description>
+    <name>when</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.WhenTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The test condition that determines whether or not the
+body content should be processed.
+        </description>
+        <name>test</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+	<type>boolean</type>
+    </attribute>
+  </tag>
+
+</taglib>
diff --git a/conf/c.tld b/conf/c.tld
index 22698c9..60879c2 100644
--- a/conf/c.tld
+++ b/conf/c.tld
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 
-<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
+<taglib xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
-    version="2.0">
-    
-  <description>JSTL 1.1 core library</description>
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
+    version="2.1">
+
+  <description>JSTL 1.2 core library</description>
   <display-name>JSTL core</display-name>
-  <tlib-version>1.1</tlib-version>
+  <tlib-version>1.2</tlib-version>
   <short-name>c</short-name>
   <uri>http://java.sun.com/jsp/jstl/core</uri>
 
@@ -174,6 +174,9 @@
 	<required>false</required>
 	<rtexprvalue>true</rtexprvalue>
 	<type>java.lang.Object</type>
+	<deferred-value>
+	    <type>java.lang.Object</type>
+    </deferred-value>
     </attribute>
     <attribute>
         <description>
@@ -253,6 +256,9 @@
 	<required>true</required>
 	<rtexprvalue>true</rtexprvalue>
 	<type>java.lang.String</type>
+    <deferred-value>
+	    <type>java.lang.String</type>
+    </deferred-value>	
     </attribute>
     <attribute>
         <description>
@@ -467,6 +473,9 @@
         <name>value</name>
         <required>false</required>
         <rtexprvalue>true</rtexprvalue>
+        <deferred-value>
+	        <type>java.lang.Object</type>
+        </deferred-value>
     </attribute>
     <attribute>
         <description>
diff --git a/src/javax/servlet/jsp/jstl/core/IndexedValueExpression.java b/src/javax/servlet/jsp/jstl/core/IndexedValueExpression.java
new file mode 100644
index 0000000..9ed0e2d
--- /dev/null
+++ b/src/javax/servlet/jsp/jstl/core/IndexedValueExpression.java
@@ -0,0 +1,80 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package javax.servlet.jsp.jstl.core;
+
+import java.io.Serializable;
+
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+
+public final class IndexedValueExpression extends ValueExpression implements Serializable {
+
+    private static final long serialVersionUID = -7300711701036452952L;
+    protected final Integer i;
+    protected final ValueExpression orig;
+    
+    public IndexedValueExpression(ValueExpression valueExpression, int _i) {
+        orig = valueExpression;
+        i=_i;
+    }
+    
+    public boolean equals(Object arg0) {
+        boolean rc=false;
+        if (arg0!=null) {
+            if (arg0.equals(orig)) {
+                rc = true;
+            }
+        }
+        return rc;
+    }
+
+    public Class getExpectedType() {
+        return orig.getExpectedType();
+    }
+
+    public String getExpressionString() {
+        return orig.getExpressionString();
+    }
+
+    public Class getType(ELContext elContext) {
+        return elContext.getELResolver().getType(elContext, orig.getValue(elContext), i);
+    }
+
+    public Object getValue(ELContext elContext) {
+        return elContext.getELResolver().getValue(elContext, orig.getValue(elContext), i);
+    }
+
+    public int hashCode() {
+        return orig.hashCode()+i;
+    }
+
+    public boolean isLiteralText() {
+        return false;
+    }
+
+    public boolean isReadOnly(ELContext elContext) {
+        return elContext.getELResolver().isReadOnly(elContext, orig.getValue(elContext), i);
+    }
+
+    public void setValue(ELContext elContext, Object arg1) {
+        elContext.getELResolver().setValue(elContext, orig.getValue(elContext), i, arg1);
+    }
+
+}
diff --git a/src/javax/servlet/jsp/jstl/core/IteratedExpression.java b/src/javax/servlet/jsp/jstl/core/IteratedExpression.java
new file mode 100644
index 0000000..6c7b7dd
--- /dev/null
+++ b/src/javax/servlet/jsp/jstl/core/IteratedExpression.java
@@ -0,0 +1,136 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package javax.servlet.jsp.jstl.core;
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+
+public final class IteratedExpression {
+    protected final ValueExpression orig;
+    protected final String delims;
+    private Object originalListObject = null;
+    private Iterator currentListObject = null;
+    private int currentIndex=0;
+    private enum TypesEnum {Undefined, ACollection, AnIterator, AnEnumeration, AMap, AString};
+    private TypesEnum type = TypesEnum.Undefined;
+    
+    public IteratedExpression(ValueExpression valueExpression, String stringTokenSeparator) {
+        orig = valueExpression;
+        delims = stringTokenSeparator;
+    }
+    
+    public Object getItem(ELContext context, int i) {
+        if (originalListObject == null) {
+            originalListObject = orig.getValue(context);
+            if (originalListObject instanceof Collection){
+                type=TypesEnum.ACollection;
+            } else if (originalListObject instanceof Iterator) {
+                type=TypesEnum.AnIterator;
+            } else if (originalListObject instanceof Enumeration) {
+                type=TypesEnum.AnEnumeration;
+            } else if (originalListObject instanceof Map) {
+                type=TypesEnum.AMap;
+            } else if (originalListObject instanceof String) { //StringTokens
+                type=TypesEnum.AString;
+            } else {
+                //it's of some other type ... should never get here
+                throw new RuntimeException("IteratedExpression.getItem: Object not of correct type.");
+            }
+            currentListObject = returnNewIterator(originalListObject, type);
+        }
+        Object currentObject=null;
+        if (i<currentIndex) {
+            currentListObject = returnNewIterator(originalListObject, type);
+            currentIndex = 0;
+        } 
+        for (;currentIndex<=i;currentIndex++) {
+            if (currentListObject.hasNext()) {
+                currentObject= currentListObject.next();
+            } else {
+                throw new RuntimeException("IteratedExpression.getItem: Index out of Bounds");
+            }
+        }
+        return currentObject;
+    }
+    
+    public ValueExpression getValueExpression() {
+        return orig;
+    }
+
+    private Iterator returnNewIterator(Object o, TypesEnum type) {
+        Iterator i = null;
+        switch (type) {
+        case ACollection: 
+            i = ((Collection)o).iterator();
+            break;
+        case AnIterator: 
+            if (currentListObject==null) {
+                //first time through ... need to create Vector for originalListObject
+                Vector v = new Vector();
+                Iterator myI = (Iterator)o;
+                while (myI.hasNext()) {
+                    v.add(myI.next());
+                }
+                originalListObject = v;
+            }
+            i = ((Vector)originalListObject).iterator();
+            break;
+        case AnEnumeration: 
+            if (currentListObject==null) {
+                //first time through ... need to create Vector for originalListObject
+                Vector v = new Vector();
+                Enumeration myE = (Enumeration)o;
+                while (myE.hasMoreElements()) {
+                    v.add(myE.nextElement());
+                }
+                originalListObject = v;
+            }
+            i = ((Vector)originalListObject).iterator();
+            break;
+        case AMap: 
+            Set s = ((Map)o).entrySet();
+            i = s.iterator();
+            break;
+        case AString: 
+            if (currentListObject==null) {
+                //first time through ... need to create Vector for originalListObject
+                Vector v = new Vector();
+                StringTokenizer st = new StringTokenizer((String)o, delims);
+                while (st.hasMoreElements()) {
+                    v.add(st.nextElement());
+                }
+                originalListObject = v;
+            }
+            i = ((Vector)originalListObject).iterator();
+            break;
+        default: //do Nothing ... this is not possible 
+            break;
+        }
+        return i;        
+    }
+}
\ No newline at end of file
diff --git a/src/javax/servlet/jsp/jstl/core/IteratedValueExpression.java b/src/javax/servlet/jsp/jstl/core/IteratedValueExpression.java
new file mode 100644
index 0000000..fe11b52
--- /dev/null
+++ b/src/javax/servlet/jsp/jstl/core/IteratedValueExpression.java
@@ -0,0 +1,78 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package javax.servlet.jsp.jstl.core;
+
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+
+public final class IteratedValueExpression extends ValueExpression {
+
+    private static final long serialVersionUID = 2771035360633553883L;
+    //IteratedExpression is not serializable
+    protected final IteratedExpression iteratedExpression;
+    protected final int i;
+    
+    public IteratedValueExpression(IteratedExpression _iteratedExpression, int _i) {
+        iteratedExpression = _iteratedExpression;
+        i = _i;
+    }
+    
+    public boolean equals(Object arg0) {
+        if (arg0==null) {
+            return false;
+        }
+        if (iteratedExpression.getValueExpression().equals(arg0)) {
+            return true;
+        }
+        return false;
+    }
+
+    public Class getExpectedType() {
+        return iteratedExpression.getValueExpression().getExpectedType();
+    }
+
+    public String getExpressionString() {
+        return iteratedExpression.getValueExpression().getExpressionString();
+    }
+
+    public Class getType(ELContext elContext) {
+        return iteratedExpression.getValueExpression().getType(elContext); 
+    }
+
+    public Object getValue(ELContext elContext) {
+        return iteratedExpression.getItem(elContext, i); 
+    }
+
+    public int hashCode() {
+        return iteratedExpression.hashCode()+i;
+    }
+
+    public boolean isLiteralText() {
+        return false;
+    }
+
+    public boolean isReadOnly(ELContext elContext) {
+        return true;
+    }
+
+    public void setValue(ELContext elContext, Object arg1) {
+    }
+
+}
diff --git a/src/javax/servlet/jsp/jstl/core/LoopTagSupport.java b/src/javax/servlet/jsp/jstl/core/LoopTagSupport.java
index efd6612..051deaf 100644
--- a/src/javax/servlet/jsp/jstl/core/LoopTagSupport.java
+++ b/src/javax/servlet/jsp/jstl/core/LoopTagSupport.java
@@ -17,6 +17,9 @@
 
 package javax.servlet.jsp.jstl.core;
 
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
 import javax.servlet.jsp.JspException;
 import javax.servlet.jsp.JspTagException;
 import javax.servlet.jsp.PageContext;
@@ -105,6 +108,7 @@
     /** Attribute-exposing control */
     protected String itemId, statusId;
 
+    protected ValueExpression deferredExpression=null;
 
     //*********************************************************************
     // 'Private' state (implementation details)
@@ -501,28 +505,33 @@
      */
     private void exposeVariables() throws JspTagException {
 
-        /*
-         * We need to support null items returned from next(); we
-         * do this simply by passing such non-items through to the
-         * scoped variable as effectively 'null' (that is, by calling
-         * removeAttribute()).
-         *
-         * Also, just to be defensive, we handle the case of a null
-         * 'status' object as well.
-         *
-         * We call getCurrent() and getLoopStatus() (instead of just using
-         * 'item' and 'status') to bridge to subclasses correctly.
-         * A subclass can override getCurrent() or getLoopStatus() but still
-         * depend on our doStartTag() and doAfterBody(), which call this
-         * method (exposeVariables()), to expose 'item' and 'status'
-         * correctly.
-         */
-
-        if (itemId != null) {
-            if (getCurrent() == null)
-                pageContext.removeAttribute(itemId, PageContext.PAGE_SCOPE);
-            else
-                pageContext.setAttribute(itemId, getCurrent());
+        if (deferredExpression==null) {
+            /*
+             * We need to support null items returned from next(); we
+             * do this simply by passing such non-items through to the
+             * scoped variable as effectively 'null' (that is, by calling
+             * removeAttribute()).
+             *
+             * Also, just to be defensive, we handle the case of a null
+             * 'status' object as well.
+             *
+             * We call getCurrent() and getLoopStatus() (instead of just using
+             * 'item' and 'status') to bridge to subclasses correctly.
+             * A subclass can override getCurrent() or getLoopStatus() but still
+             * depend on our doStartTag() and doAfterBody(), which call this
+             * method (exposeVariables()), to expose 'item' and 'status'
+             * correctly.
+             */
+            if (itemId != null) {
+                if (getCurrent() == null)
+                    pageContext.removeAttribute(itemId, PageContext.PAGE_SCOPE);
+                else
+                    pageContext.setAttribute(itemId, getCurrent());
+            }
+        } else { //this is using a DeferredExpression
+            ELContext myELContext = pageContext.getELContext();
+            VariableMapper vm = myELContext.getVariableMapper();
+            vm.setVariable(itemId, (ValueExpression)getCurrent());
         }
         if (statusId != null) {
             if (getLoopStatus() == null)
@@ -538,9 +547,16 @@
      * restores them to their prior values (and scopes).
      */
     private void unExposeVariables() {
-        // "nested" variables are now simply removed
-	if (itemId != null)
-            pageContext.removeAttribute(itemId, PageContext.PAGE_SCOPE);
+        if (deferredExpression==null) {
+            // "nested" variables are now simply removed
+        	if (itemId != null)
+                    pageContext.removeAttribute(itemId, PageContext.PAGE_SCOPE);
+        } else {
+            //we're deferred ... remove variable mapping
+            ELContext myELContext = pageContext.getELContext();
+            VariableMapper vm = myELContext.getVariableMapper();
+            vm.setVariable(itemId, null);
+        }
 	if (statusId != null)
 	    pageContext.removeAttribute(statusId, PageContext.PAGE_SCOPE);
     }
@@ -590,4 +606,11 @@
     private boolean atEnd() {
         return ((end != -1) && (begin + index >= end));
     }
+    /**
+     * Get the delimiter for string tokens. Used only for constructing
+     * the deferred expression for it.
+     */
+    protected String getDelims() {
+        return ",";
+    }
 }
diff --git a/src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java b/src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java
index c10919a..de73a56 100644
--- a/src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java
+++ b/src/javax/servlet/jsp/jstl/tlv/ScriptFreeTLV.java
@@ -77,7 +77,7 @@
    * @param initParms a mapping from the names of the initialization parameters
    * to their values, as specified in the TLD.
    */
-  public void setInitParameters (Map initParms) {
+  public void setInitParameters (Map<java.lang.String, java.lang.Object> initParms) {
     super.setInitParameters(initParms);
     String declarationsParm = (String) initParms.get("allowDeclarations");
     String scriptletsParm = (String) initParms.get("allowScriptlets");
diff --git a/src/org/apache/taglibs/standard/Version.java b/src/org/apache/taglibs/standard/Version.java
index 9e8da95..f3c4e99 100644
--- a/src/org/apache/taglibs/standard/Version.java
+++ b/src/org/apache/taglibs/standard/Version.java
@@ -90,7 +90,7 @@
    */
   public static int getReleaseVersionNum()
   {
-    return 1;
+    return 2;
   }
 
   /**
@@ -104,7 +104,7 @@
    */
   public static int getMaintenanceVersionNum()
   {
-    return 2;
+    return 0;
   }
 
   /**
diff --git a/src/org/apache/taglibs/standard/extra/spath/SPathFilter.java b/src/org/apache/taglibs/standard/extra/spath/SPathFilter.java
index 12df102..7f49813 100644
--- a/src/org/apache/taglibs/standard/extra/spath/SPathFilter.java
+++ b/src/org/apache/taglibs/standard/extra/spath/SPathFilter.java
@@ -21,9 +21,9 @@
 import java.util.List;
 import java.util.Stack;
 
-import org.apache.xalan.serialize.Serializer;
-import org.apache.xalan.serialize.SerializerFactory;
-import org.apache.xalan.templates.OutputProperties;
+import org.apache.xml.serializer.Serializer;
+import org.apache.xml.serializer.SerializerFactory;
+import org.apache.xml.serializer.OutputPropertiesFactory;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -77,7 +77,7 @@
 	f1.setParent(r);
 	f2.setParent(f1);
 	Serializer sz = SerializerFactory.getSerializer
-	    (OutputProperties.getDefaultMethodProperties("xml"));
+	    (OutputPropertiesFactory.getDefaultMethodProperties("xml"));
 	sz.setOutputStream(System.out);
 	f2.setContentHandler(sz.asContentHandler());
 
diff --git a/src/org/apache/taglibs/standard/tag/common/core/ForEachSupport.java b/src/org/apache/taglibs/standard/tag/common/core/ForEachSupport.java
index 1b65453..586c640 100644
--- a/src/org/apache/taglibs/standard/tag/common/core/ForEachSupport.java
+++ b/src/org/apache/taglibs/standard/tag/common/core/ForEachSupport.java
@@ -24,7 +24,13 @@
 import java.util.Map;
 import java.util.StringTokenizer;
 
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
 import javax.servlet.jsp.JspTagException;
+import javax.servlet.jsp.jstl.core.IndexedValueExpression;
+import javax.servlet.jsp.jstl.core.IteratedExpression;
+import javax.servlet.jsp.jstl.core.IteratedValueExpression;
 import javax.servlet.jsp.jstl.core.LoopTagSupport;
 
 import org.apache.taglibs.standard.resources.Resources;
@@ -109,7 +115,133 @@
             return i.next();
         }
     }
+    
+    protected class DeferredForEachIterator implements ForEachIterator {
 
+        private ValueExpression itemsValueExpression;
+        private IteratedExpression itemsValueIteratedExpression;
+        private int length = -1;
+        private int currentIndex = 0;
+        private boolean isIndexedValueExpression = false;
+        private boolean anIterator = false;
+        private Iterator myIterator;
+        private boolean anEnumeration = false;
+        private Enumeration myEnumeration;
+        public DeferredForEachIterator(ValueExpression o) throws JspTagException {
+            itemsValueExpression = o;
+            determineLengthAndType();
+        }
+        public boolean hasNext() throws JspTagException {
+            if (isIndexedValueExpression) {
+                if (currentIndex<length) {
+                    return true;
+                } else {
+                    return false;
+                }                
+            } else {
+                if (length!=-1) {
+                    //a Collection, Map, or StringTokenizer 
+                    if (currentIndex<length) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                } else {
+                    if (anIterator) {
+                        return myIterator.hasNext();
+                    } else if (anEnumeration) {
+                        return myEnumeration.hasMoreElements();
+                    } else {
+                        //don't know what this is
+                        return false;
+                    }
+                }
+            }
+        }
+        public Object next() throws JspTagException {
+            ValueExpression nextValue = null;
+            if (isIndexedValueExpression) {
+                nextValue = new IndexedValueExpression(itemsValueExpression, currentIndex);
+                currentIndex++;
+            } else {
+                if (itemsValueIteratedExpression==null) {
+                    itemsValueIteratedExpression = new IteratedExpression(itemsValueExpression, getDelims());
+                }
+                nextValue = new IteratedValueExpression(itemsValueIteratedExpression, currentIndex);
+                currentIndex++;
+                if (length!=-1) {
+                    //a Collection, Map, or StringTokenizer
+                    //nothing else needed
+                } else {
+                    //need to increment these guys
+                    if (anIterator) {
+                        myIterator.next();
+                    } else if (anEnumeration) {
+                        myEnumeration.nextElement();
+                    }
+                }
+            }
+            return nextValue;
+        }
+        private void determineLengthAndType() throws JspTagException {
+            ELContext myELContext = pageContext.getELContext();
+            Object o = itemsValueExpression.getValue(myELContext);
+            if (o instanceof Object[]) {
+                length = ((Object[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof boolean[]) {
+                length = ((boolean[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof byte[]) {
+                length = ((byte[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof char[]) {
+                length = ((char[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof short[]) {
+                length = ((short[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof int[]) {
+                length = ((int[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof long[]) {
+                length = ((long[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof float[]) {
+                length = ((float[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof double[]) {
+                length = ((double[])o).length;
+                isIndexedValueExpression = true;
+            } else if (o instanceof Collection) {
+                length = ((Collection)o).size();
+                isIndexedValueExpression = false;
+            } else if (o instanceof Iterator) {
+                //have to reproduce iterator here so we can determine the size
+                isIndexedValueExpression = false;
+                anIterator = true;
+                myIterator = (Iterator)o;
+            } else if (o instanceof Enumeration) {
+                isIndexedValueExpression = false;
+                anEnumeration=true;
+                myEnumeration = (Enumeration)o;
+            } else if (o instanceof Map) {
+                length = ((Map)o).size();
+                isIndexedValueExpression = false;
+            //
+            //else if (o instanceof ResultSet)
+            //    items = toForEachIterator((ResultSet) o);
+            //
+            } else if (o instanceof String) {
+                StringTokenizer st = new StringTokenizer((String)o, ",");
+                length = st.countTokens();
+                isIndexedValueExpression = false;
+            } else {
+                //What does this mean if we get here???
+                length=0;
+            }
+        }
+    }
 
     //*********************************************************************
     // ForEach-specifc state (protected)
@@ -134,8 +266,17 @@
     protected void prepare() throws JspTagException {
         // produce the right sort of ForEachIterator
         if (rawItems != null) {
-            // extract an iterator over the 'items' we've got
-            items = supportedTypeForEachIterator(rawItems);
+            if (rawItems instanceof ValueExpression) {
+                deferredExpression = (ValueExpression)rawItems;
+                ELContext myELContext = pageContext.getELContext();
+                VariableMapper vm = myELContext.getVariableMapper();
+                //String itemsName=deferredExpression.getExpressionString();
+                //vm.setVariable(itemsName, deferredExpression);
+                items = toDeferredForEachIterator(deferredExpression);
+            } else {
+                // extract an iterator over the 'items' we've got
+                items = supportedTypeForEachIterator(rawItems);
+            }
         } else {
             // no 'items', so use 'begin' and 'end'
             items = beginEndForEachIterator();
@@ -165,6 +306,7 @@
     // Private generation methods for the ForEachIterators we produce
 
     /* Extracts a ForEachIterator given an object of a supported type. */
+    //This should not be called for a deferred ValueExpression
     protected ForEachIterator supportedTypeForEachIterator(Object o)
             throws JspTagException {
 
@@ -250,6 +392,10 @@
     //*********************************************************************
     // Private conversion methods to handle the various types we support
 
+    protected ForEachIterator toDeferredForEachIterator(ValueExpression o) throws JspTagException {
+        return new DeferredForEachIterator(o);
+    }
+    
     // catch-all method whose invocation currently signals a 'matching error'
     protected ForEachIterator toForEachIterator(Object o)
             throws JspTagException {
diff --git a/src/org/apache/taglibs/standard/tag/common/core/ForTokensSupport.java b/src/org/apache/taglibs/standard/tag/common/core/ForTokensSupport.java
index 608ea26..0c876d5 100644
--- a/src/org/apache/taglibs/standard/tag/common/core/ForTokensSupport.java
+++ b/src/org/apache/taglibs/standard/tag/common/core/ForTokensSupport.java
@@ -19,7 +19,12 @@
 
 import java.util.StringTokenizer;
 
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
 import javax.servlet.jsp.JspTagException;
+import javax.servlet.jsp.jstl.core.IteratedExpression;
+import javax.servlet.jsp.jstl.core.IteratedValueExpression;
 import javax.servlet.jsp.jstl.core.LoopTagSupport;
 
 /**
@@ -50,9 +55,11 @@
     //*********************************************************************
     // ForEachTokens-specific state (protected)
 
-    protected String items;                       // 'items' attribute
+    protected Object items;                       // 'items' attribute
     protected String delims;                      // 'delims' attribute
     protected StringTokenizer st;                 // digested tokenizer
+    protected int currentIndex = 0;
+    private IteratedExpression itemsValueIteratedExpression;
 
 
     //*********************************************************************
@@ -64,7 +71,18 @@
      */
 
     protected void prepare() throws JspTagException {
-      st = new StringTokenizer(items, delims);
+        if (items instanceof ValueExpression) {
+            deferredExpression = (ValueExpression) items;
+            ELContext myELContext = pageContext.getELContext();
+            Object originalValue = deferredExpression.getValue(myELContext);
+            if (originalValue instanceof String) {
+                st = new StringTokenizer((String)originalValue, delims);
+            } else {
+                throw new JspTagException();
+            }
+        } else {
+            st = new StringTokenizer((String)items, delims);
+        }
     }
 
     protected boolean hasNext() throws JspTagException {
@@ -72,7 +90,17 @@
     }
 
     protected Object next() throws JspTagException {
-        return st.nextElement();
+        if (deferredExpression!=null) {
+            st.nextElement();
+            if (itemsValueIteratedExpression==null) {
+                itemsValueIteratedExpression = new IteratedExpression(deferredExpression, getDelims());
+            }
+            ValueExpression nextValue = new IteratedValueExpression(itemsValueIteratedExpression, currentIndex);
+            currentIndex++;
+            return nextValue;
+        } else {
+            return st.nextElement();
+        }
     }
 
 
@@ -87,4 +115,11 @@
         st = null;
     }
 
+    /**
+     * Get the delimiter for string tokens. Used only for constructing
+     * the deferred expression for it.
+     */
+    protected String getDelims() {
+        return delims;
+    }
 }
diff --git a/src/org/apache/taglibs/standard/tag/common/core/SetSupport.java b/src/org/apache/taglibs/standard/tag/common/core/SetSupport.java
index 878bb05..90e22a9 100644
--- a/src/org/apache/taglibs/standard/tag/common/core/SetSupport.java
+++ b/src/org/apache/taglibs/standard/tag/common/core/SetSupport.java
@@ -27,12 +27,15 @@
 import java.util.Map;
 
 import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspFactory;
 import javax.servlet.jsp.JspTagException;
 import javax.servlet.jsp.PageContext;
 
-import javax.servlet.jsp.el.ELException;
-import javax.servlet.jsp.el.ExpressionEvaluator;
-import javax.servlet.jsp.el.VariableResolver;
+import javax.el.ELException;
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+import javax.el.ExpressionFactory;
 
 import javax.servlet.jsp.tagext.BodyTagSupport;
 
@@ -114,9 +117,30 @@
              * is made to store something in the session without any
              * HttpSession existing).
              */
+            ELContext myELContext = pageContext.getELContext();
+            VariableMapper vm = myELContext.getVariableMapper();
             if (result != null) {
-                pageContext.setAttribute(var, result, scope);
+                //check for instanceof valueExpression
+                if (result instanceof ValueExpression) {
+                    if (scope!=PageContext.PAGE_SCOPE) {
+                        throw new JspException("Incorrect scope for ValueExpression.  PageScope is required.");
+                    }
+                    //set variable in var Mapper
+                    vm.setVariable(var, (ValueExpression)result);
+                } else {
+                    /*
+                    //else if not valueExpression - make sure to remove it from the Var mapper
+                    //if the scope is page, should I remove this?
+                    if (vm.resolveVariable(var)!=null) {
+                        vm.setVariable(var, null);
+                    }*/
+                    pageContext.setAttribute(var, result, scope);
+                }
             } else {
+                //make sure to remove it from the Var mapper
+                if (vm.resolveVariable(var)!=null) {
+                    vm.setVariable(var, null);
+                }
                 if (scopeSpecified)
                     pageContext.removeAttribute(var, scope);
                 else
@@ -179,15 +203,9 @@
      * rules of the Expression Language.
      */
     private Object convertToExpectedType(final Object value, Class expectedType) throws ELException {
-        ExpressionEvaluator evaluator = pageContext.getExpressionEvaluator();
-        return evaluator.evaluate( "${result}",
-                                   expectedType,
-                                   new VariableResolver() {
-                                       public Object resolveVariable(String pName) throws ELException {
-                                           return value;
-                                       }
-                                   },
-                                   null);
+        JspFactory jspFactory = JspFactory.getDefaultFactory();
+        ExpressionFactory expressionFactory = jspFactory.getJspApplicationContext(pageContext.getServletContext()).getExpressionFactory();
+        return expressionFactory.coerceToType(value, expectedType);
     }
 
     //*********************************************************************
diff --git a/src/org/apache/taglibs/standard/tag/common/fmt/BundleSupport.java b/src/org/apache/taglibs/standard/tag/common/fmt/BundleSupport.java
index 257240c..ccd78b3 100644
--- a/src/org/apache/taglibs/standard/tag/common/fmt/BundleSupport.java
+++ b/src/org/apache/taglibs/standard/tag/common/fmt/BundleSupport.java
@@ -201,8 +201,8 @@
 	if (locCtxt == null) {
 	    // try using the root resource bundle with the given basename
 	    try {
-		bundle = ResourceBundle.getBundle(basename, EMPTY_LOCALE,
-						  Thread.currentThread().getContextClassLoader());
+	        ClassLoader cl = getClassLoaderCheckingPrivilege();
+            bundle = ResourceBundle.getBundle(basename, EMPTY_LOCALE, cl);
 		if (bundle != null) {
 		    locCtxt = new LocalizationContext(bundle, null);
 		}
@@ -279,9 +279,8 @@
 	ResourceBundle match = null;
 
 	try {
-	    ResourceBundle bundle =
-		ResourceBundle.getBundle(basename, pref,
-					 Thread.currentThread().getContextClassLoader());
+	    ClassLoader cl = getClassLoaderCheckingPrivilege();
+        ResourceBundle bundle = ResourceBundle.getBundle(basename, pref, cl);
 	    Locale avail = bundle.getLocale();
 	    if (pref.equals(avail)) {
 		// Exact match
@@ -326,4 +325,17 @@
 
 	return match;
     }
+    
+    private static ClassLoader getClassLoaderCheckingPrivilege() {
+        ClassLoader cl;
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            cl = Thread.currentThread().getContextClassLoader();
+        } else {
+            cl = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<ClassLoader>() 
+                {public ClassLoader run() {return Thread.currentThread().getContextClassLoader();}});
+        }
+        return cl;
+    }
 }
diff --git a/src/org/apache/taglibs/standard/tag/common/sql/DataSourceWrapper.java b/src/org/apache/taglibs/standard/tag/common/sql/DataSourceWrapper.java
index 9bf632d..626d0fb 100644
--- a/src/org/apache/taglibs/standard/tag/common/sql/DataSourceWrapper.java
+++ b/src/org/apache/taglibs/standard/tag/common/sql/DataSourceWrapper.java
@@ -40,12 +40,24 @@
     private String password;
 
     public void setDriverClassName(String driverClassName) 
-	throws ClassNotFoundException, InstantiationException, 
-	       IllegalAccessException {
+        throws ClassNotFoundException, InstantiationException, 
+            IllegalAccessException {
 
-	this.driverClassName = driverClassName;
-        Class.forName(driverClassName, true, 
-            Thread.currentThread().getContextClassLoader()).newInstance();
+        this.driverClassName = driverClassName;
+
+        //get the classloader
+        ClassLoader cl;
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            cl = Thread.currentThread().getContextClassLoader();
+        } else {
+            cl = java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedAction<ClassLoader>() 
+                    {public ClassLoader run() {return Thread.currentThread().getContextClassLoader();}});
+        }
+        //done getting classloader
+    
+        Class.forName(driverClassName, true, cl).newInstance();
     }
 
     public void setJdbcURL(String jdbcURL) {
@@ -111,6 +123,13 @@
     public synchronized void setLogWriter(PrintWriter out) throws SQLException {
         throw new SQLException(Resources.getMessage("NOT_SUPPORTED"));
     }
+    
+    public synchronized boolean isWrapperFor(Class c) throws SQLException {
+        throw new SQLException(Resources.getMessage("NOT_SUPPORTED"));
+    }
 
+    public synchronized Object unwrap(Class c) throws SQLException {
+        throw new SQLException(Resources.getMessage("NOT_SUPPORTED"));
+    }
 
 }
diff --git a/src/org/apache/taglibs/standard/tag/rt/core/ForTokensTag.java b/src/org/apache/taglibs/standard/tag/rt/core/ForTokensTag.java
index a0c26da..0d207d2 100644
--- a/src/org/apache/taglibs/standard/tag/rt/core/ForTokensTag.java
+++ b/src/org/apache/taglibs/standard/tag/rt/core/ForTokensTag.java
@@ -59,8 +59,8 @@
         validateStep();
     }
 
-    // stores the 'items' String we're passed
-    public void setItems(String s) throws JspTagException {
+    // stores the 'items' Object we're passed
+    public void setItems(Object s) throws JspTagException {
         items = s;
 	// use the empty string to indicate "no iteration"
         if (s == null)
diff --git a/test/org/apache/taglibs/standard/TestVersion.java b/test/org/apache/taglibs/standard/TestVersion.java
index 7dc05de..460beb6 100644
--- a/test/org/apache/taglibs/standard/TestVersion.java
+++ b/test/org/apache/taglibs/standard/TestVersion.java
@@ -48,7 +48,7 @@
     }
 
     public void testGetMaintenanceVersionNum() {
-        int expectedReturn = 2;
+        int expectedReturn = 0;
         int actualReturn = version.getMaintenanceVersionNum();
         assertEquals("return value", expectedReturn, actualReturn);
     }
@@ -66,13 +66,13 @@
     }
 
     public void testGetReleaseVersionNum() {
-        int expectedReturn = 1;
+        int expectedReturn = 2;
         int actualReturn = version.getReleaseVersionNum();
         assertEquals("return value", expectedReturn, actualReturn);
     }
 
     public void testGetVersion() {
-        String expectedReturn = "standard-taglib 1.1.2";
+        String expectedReturn = "standard-taglib 1.2.0";
         String actualReturn = version.getVersion();
         assertEquals("return value", expectedReturn, actualReturn);
     }
diff --git a/test/org/apache/taglibs/standard/lang/jstl/test/PageContextImpl.java b/test/org/apache/taglibs/standard/lang/jstl/test/PageContextImpl.java
index e188c5f..d5f4cc4 100644
--- a/test/org/apache/taglibs/standard/lang/jstl/test/PageContextImpl.java
+++ b/test/org/apache/taglibs/standard/lang/jstl/test/PageContextImpl.java
@@ -32,6 +32,7 @@
 import javax.servlet.jsp.PageContext;
 import javax.servlet.jsp.el.ExpressionEvaluator;
 import javax.servlet.jsp.el.VariableResolver;
+import javax.el.ELContext;
 
 /**
  *
@@ -299,4 +300,5 @@
   public ExpressionEvaluator getExpressionEvaluator() { return null; }
   public VariableResolver getVariableResolver() { return null; }  
   
+  public ELContext getELContext() { return null; }
 }