Copy EL TCK from Platform TCK

Package for signature tests was corrected as the declared package and
actual package were not aligned.
POM updated to add sigtest dependency and align name/version
diff --git a/tck/docs/LICENSE_EFTL.md b/tck/docs/LICENSE_EFTL.md
new file mode 100644
index 0000000..a210682
--- /dev/null
+++ b/tck/docs/LICENSE_EFTL.md
@@ -0,0 +1,83 @@
+# Eclipse Foundation Technology Compatibility Kit License - v 1.0
+
+Copyright (c) 2018, Eclipse Foundation, Inc. and its licensors.
+
+Redistribution and use in binary form is permitted provided that the
+following conditions are met:
+
+1.  Use of the Technology Compatibility Kit accompanying this license
+    (the "TCK") and its documentation is permitted solely for the
+    purpose of testing compatibility of an implementation (the
+    "Product") of a specification (the "Specification") made available
+    by the Eclipse Foundation, Inc. ("Eclipse").
+
+2.  Only those modifications expressly permitted by the TCK and its
+    documentation are permitted. Except in these limited circumstances,
+    no modifications to the TCK are permitted under this license.
+
+3.  A Product will be deemed to be "compatible" with the Specification
+    if it fully and completely meets and satisfies all requirements of
+    the TCK.
+
+4.  Before any claim of compatibility (or any similar claim suggesting
+    compatibility) is made based on the TCK, the testing party must:
+
+    a.  use the TCK to demonstrate that the Product fully and
+	completely meets and satisfies all requirements of the TCK;
+
+    b.  make TCK test results showing full and complete satisfaction of
+	all requirements of the TCK publicly available on the testing
+	party's website and send a link to such test results to Eclipse
+	at [tck@eclipse.org](mailto:tck@eclipse.org); and
+
+    c.  comply with any requirements stated in the Specification with
+	regard to subsetting, supersetting, modifying or extending the
+	Specification in any Product claimed to be compatible with the
+	Specification.
+
+5.  The test results must be continuously available and the link must
+    be live for at least as long as the Product is available in the
+    marketplace.
+
+6.  The TCK may not be used as a basis for any statements of partial
+    compatibility. The TCK may only be used as a basis for true,
+    factual statements of full compatibility of Products that fully
+    meet and satisfy all requirements of the TCK.
+
+7.  A determination that a Product is compatible with the TCK does not,
+    in itself, give rise to the right to use any name, mark, logo
+    associated with the TCK, Eclipse, or Eclipse's contributors or
+    licensors.
+
+8.  Upon the request of Eclipse, a tester will retract any statements
+    of compatibility (or any similar claim suggesting compatibility)
+    which Eclipse reasonably determines to be false or misleading or in
+    violation of the terms of this license.
+
+9.  Redistribution of the TCK must be under this Eclipse Foundation
+    Technology Compatibility Kit License and 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.
+
+10. Neither the name, trademarks or logos of Eclipse, nor the names,
+    trademarks or logos of its contributors or licensors may be used to
+    endorse or promote products tested with this software without
+    specific prior written permission.
+
+11. The source code for the TCK accompanying this license is available
+    from Eclipse.
+
+TO THE EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED ON
+AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
+EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
+CONDITIONS OF TITLE, NON- INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR
+A PARTICULAR PURPOSE. TO THE EXTENT PERMITTED BY APPLICABLE LAW,
+NEITHER THE COPYRIGHT OWNER OR ANY CONTRIBUTORS SHALL HAVE ANY
+LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS),
+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 OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/tck/docs/ReleaseNotes.html b/tck/docs/ReleaseNotes.html
new file mode 100755
index 0000000..34cfdc6
--- /dev/null
+++ b/tck/docs/ReleaseNotes.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<!--
+
+    Copyright (c) 2018, 2024 Oracle and/or its affiliates and others.
+    All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+  <title>Expression Language TCK, Version 6.0 Release Notes, January 2024</title>
+<style type="text/css">
+<!--
+body {  background-color: #ffffdd; color: #000000}
+pre {  background-color: #eeeeee; color: #000099}
+code {  color: #000099}
+h1 {  color: #000099}
+h2 {  color: #000099}
+h3 {  color: #000099; text-decoration: underline}
+h4 {  font-style: italic; color: #000099}
+.tabletitle {  font-style: italic; color: #ffffcc; font-size: small; font-variant: small-caps}
+.subtitle {  font-style: italic; color: #ffffcc; font-variant: small-caps}
+.emphasize  {  font-style: italic; color: #000099}
+.step  { font-weight: bold}
+.note { background-color: #fffff0; border-bottom-width: thin; border-top-width: thin; border-top-style: inset; border-bottom-style: inset; font-size: -10%;}
+th {  background-color: #eeeeee; padding-left: 2pt; padding-right: 2pt;}
+td {  padding-left: 3pt;}
+-->
+</style>
+</head>
+<body>
+<div align="center">
+<h1>Expression Language Technology Compatibility Kit, Version 6.0<br>
+<span class="emphasize">Release Notes, January 2024</span></h1>
+</div>
+<hr size="3">
+
+<h2>About Expression Language Technology</h2>
+
+<hr>
+<h2><a name="kit_contents">Technology Compatibility Kit (TCK) Contents</a></h2>
+<p>The Jakarta Expression Language specification, Version 6.0 Technology Compatibility Kit (TCK) includes the following items:</p>
+
+<hr>
+<h2>Platform Notes</h2>
+
+     <p>The Expression Language TCK tests have been built and tested with the Java&trade; Platform, Standard Edition SDK, Version 17 (JavaSE 17) and Jakarta EE Compatible Implementation, Eclipse GlassFish 7.0</p>
+<p>Note that if you are using a different web server, you will need to make adjustments to the procedures outlined in these documents.</p>
+
+<hr>
+<h2><a name="install_setup_run">Installing, Setting Up, and Running the EL TCK</a></h2>
+
+<p>Refer to the <cite>Jakarta Expression Language TCK 6.0 User's Guide</cite>, available in the EL TCK 6.0 documentation bundle, for complete instructions on installing, setting up, and running the Expression Language TCK.
+
+<hr>
+
+<hr>
+<p><small>
+<address>
+Copyright (c) 2013, 2024 Oracle and/or its affiliates and others. All rights reserved.
+</address>
+</small></p>
+</body>
+</html>
diff --git a/tck/docs/TCK-Exclude-List.txt b/tck/docs/TCK-Exclude-List.txt
new file mode 100644
index 0000000..11d0cfc
--- /dev/null
+++ b/tck/docs/TCK-Exclude-List.txt
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+# This file lists the excluded tests from Jakarta EL TCK. 
+# This is intended only for documentation purpose and is not used to exclude any tests.
+# The tests are excluded from the test source using @Disabled tag in JUnit framework.
+#
diff --git a/tck/docs/assertions/ELJavadocAssertions.xml b/tck/docs/assertions/ELJavadocAssertions.xml
new file mode 100644
index 0000000..7fa11d5
--- /dev/null
+++ b/tck/docs/assertions/ELJavadocAssertions.xml
@@ -0,0 +1,5054 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<!DOCTYPE javadoc SYSTEM "https://raw.githubusercontent.com/eclipse-ee4j/jakartaee-tck/master/internal/docs/dtd/javadoc_assertions.dtd">
+<!--
+
+    Copyright (c) 2018, 2022 Oracle and/or its affiliates and others.
+    All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<javadoc>
+  <next-available-id>414</next-available-id>
+  <previous-id>410</previous-id>
+  <technology>EL</technology>
+  <id>EL</id>
+  <name>Expression Language</name>
+  <version>5.0</version>
+  <assertions>
+    <!-- ********************************************************************************** -->
+    <!-- ********************************************************************************** -->
+    <!-- UNMODIFIED ASSERTIONS LISTED BELOW -->
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>1</id>
+      <description>Creates a new read/write ArrayELResolver.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="ArrayELResolver" return-type="ArrayELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>2</id>
+      <description>Creates a new ArrayELResolver whose read-only status is determined by the given parameter.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="ArrayELResolver" return-type="ArrayELResolver">
+        <parameters>
+          <parameter>boolean</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>3</id>
+      <description>If the base object is a Java language array, returns the most general type that this resolver accepts for the property argument. Otherwise, returns null. Assuming the base is an array, this method will always return Integer.class. This is because arrays accept integers for their index.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>4</id>
+      <description>Always returns null, since there is no reason to iterate through set set of all integers. The #getCommonPropertyType method returns sufficient information about what properties this resolver accepts.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>5</id>
+      <description>If the base object is an array, returns the most general acceptable type for a value in this array. If the base is a array, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. Assuming the base is an array, this method will always return base.getClass().getComponentType(), which is the most general type of component that can be stored at any given index in the array.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>6</id>
+      <description>If the base object is a Java language array, returns the value at the given index. The index is specified by the property argument, and coerced into an integer. If the coercion could not be performed, an IllegalArgumentException is thrown. If the index is out of bounds, null is returned. If the base is a Java language array, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>7</id>
+      <description>If the base object is a Java language array, returns whether a call to #setValue will always fail. If the base is a Java language array, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. If this resolver was constructed in read-only mode, this method will always return true. Otherwise, it returns false.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>8</id>
+      <description>If the base object is a Java language array, attempts to set the value at the given index with the given value. The index is specified by the property argument, and coerced into an integer. If the coercion could not be performed, an IllegalArgumentException is thrown. If the index is out of bounds, a PropertyNotFoundException is thrown. If the base is a Java language array, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value was set. If this resolver was constructed in read-only mode, this method will always throw PropertyNotWritableException.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>9</id>
+      <description>Creates a new read/write BeanELResolver.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="BeanELResolver" return-type="BeanELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>10</id>
+      <description>Creates a new BeanELResolver whose read-only status is determined by the given parameter.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="BeanELResolver" return-type="BeanELResolver">
+        <parameters>
+          <parameter>boolean</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>11</id>
+      <description>If the base object is not null, returns the most general type that this resolver accepts for the property argument. Otherwise, returns null. Assuming the base is not null, this method will always return Object.class. This is because any object is accepted as a key and is coerced into a string.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>12</id>
+      <description>If the base object is not null, returns an Iterator containing the set of JavaBeans properties available on the given object. Otherwise, returns null. The Iterator returned must contain zero or more instances of java.beans.FeatureDescriptor. Each info object contains information about a property in the bean, as obtained by calling the BeanInfo.getPropertyDescriptors method. The FeatureDescriptor is initialized using the same fields as are present in the PropertyDescriptor, with the additional required named attributes "type" and "resolvableAtDesignTime" set as follows: ELResolver#TYPE - The runtime type of the property, from PropertyDescriptor.getPropertyType(). ELResolver#RESOLVABLE_AT_DESIGN_TIME - true.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>13</id>
+      <description>If the base object is not null, returns the most general acceptable type that can be set on this bean property. If the base is not null, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. The provided property will first be coerced to a String. If there is a BeanInfoProperty for this property and there were no errors retrieving it, the propertyType of the propertyDescriptor is returned. Otherwise, a PropertyNotFoundException is thrown.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>14</id>
+      <description>If the base object is not null, returns the current value of the given property on this bean. If the base is not null, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. The provided property name will first be coerced to a String. If the property is a readable property of the base object, as per the JavaBeans specification, then return the result of the getter call. If the getter throws an exception, it is propagated to the caller. If the property is not found or is not readable, a PropertyNotFoundException is thrown.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>15</id>
+      <description>If the base object is not null, returns whether a call to #setValue will always fail. If the base is not null, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value was set. If this resolver was constructed in read-only mode, this method will always return true. The provided property name will first be coerced to a String. If property is a writable property of base, false is returned. If the property is found but is not writable, true is returned. If the property is not found, a PropertyNotFoundException is thrown.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>16</id>
+      <description>If the base object is not null, attempts to set the value of the given property on this bean. If the base is not null, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value was set. If this resolver was constructed in read-only mode, this method will always throw PropertyNotWritableException. The provided property name will first be coerced to a String. If property is a writable property of base (as per the JavaBeans Specification), the setter method is called (passing value). If the property exists but does not have a setter, then a PropertyNotFoundException is thrown. If the property does not exist, a PropertyNotFoundException is thrown.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>24</id>
+      <description>Adds the given resolver to the list of component resolvers. Resolvers are consulted in the order in which they are added.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="add" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELResolver</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>25</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="CompositeELResolver" return-type="CompositeELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>26</id>
+      <description>Returns the most general type that this resolver accepts for the property argument, given a base object. One use for this method is to assist tools in auto-completion. The result is obtained by querying all component resolvers. The Class returned is the most specific class that is a common superclass of all the classes returned by each component resolver's getCommonPropertyType method. If null is returned by a resolver, it is skipped.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>27</id>
+      <description>Returns information about the set of variables or properties that can be resolved for the given base object. One use for this method is to assist tools in auto-completion. The results are collected from all component resolvers. The propertyResolved property of the ELContext is not relevant to this method. The results of all ELResolvers are concatenated. The Iterator returned is an iterator over the collection of FeatureDescriptor objects returned by the iterators returned by each component resolver's getFeatureDescriptors method. If null is returned by a resolver, it is skipped.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>28</id>
+      <description>For a given base and property, attempts to identify the most general type that is acceptable for an object to be passed as the value parameter in a future call to the #setValue method. The result is obtained by querying all component resolvers. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. First, propertyResolved is set to false on the provided ELContext. Next, for each component resolver in this composite: The getType() method is called, passing in the provided context, base and property. If the ELContext's propertyResolved flag is false then iteration continues. Otherwise, iteration stops and no more component resolvers are considered. The value returned by getType() is returned by this method. If none of the component resolvers were able to perform this operation, the value null is returned and the propertyResolved flag remains set to false. Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>29</id>
+      <description>Attempts to resolve the given property object on the given base object by querying all component resolvers. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. First, propertyResolved is set to false on the provided ELContext. Next, for each component resolver in this composite: The getValue() method is called, passing in the provided context, base and property. If the ELContext's propertyResolved flag is false then iteration continues. Otherwise, iteration stops and no more component resolvers are considered. The value returned by getValue() is returned by this method. If none of the component resolvers were able to perform this operation, the value null is returned and the propertyResolved flag remains set to false. Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>30</id>
+      <description>For a given base and property, attempts to determine whether a call to #setValue will always fail. The result is obtained by querying all component resolvers. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. First, propertyResolved is set to false on the provided ELContext. Next, for each component resolver in this composite: The isReadOnly() method is called, passing in the provided context, base and property. If the ELContext's propertyResolved flag is false then iteration continues. Otherwise, iteration stops and no more component resolvers are considered. The value returned by isReadOnly() is returned by this method. If none of the component resolvers were able to perform this operation, the value false is returned and the propertyResolved flag remains set to false. Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>31</id>
+      <description>Attempts to set the value of the given property object on the given base object. All component resolvers are asked to attempt to set the value. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value has been set. First, propertyResolved is set to false on the provided ELContext. Next, for each component resolver in this composite: The setValue() method is called, passing in the provided context, base, property and value. If the ELContext's propertyResolved flag is false then iteration continues. Otherwise, iteration stops and no more component resolvers are considered. If none of the component resolvers were able to perform this operation, the propertyResolved flag remains set to false. Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>32</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="ELContext" return-type="ELContext" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>33</id>
+      <description>Returns the context object associated with the given key. The ELContext maintains a collection of context objects relevant to the evaluation of an expression. These context objects are used by ELResolvers. This method is used to retrieve the context with the given key from the collection. By convention, the object returned will be of the type specified by the key. However, this is not required and the key is used strictly as a unique identifier.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getContext" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>34</id>
+      <description>Retrieves the ELResolver associated with this context. The ELContext maintains a reference to the ELResolver that will be consulted to resolve variables and properties during an expression evaluation. This method retrieves the reference to the resolver. Once an ELContext is constructed, the reference to the ELResolver associated with the context cannot be changed.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getELResolver" return-type="jakarta.el.ELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>35</id>
+      <description>Retrieves the FunctionMapper associated with this ELContext.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getFunctionMapper" return-type="jakarta.el.FunctionMapper" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>36</id>
+      <description>Get the Locale stored by a previous invocation to #setLocale. If this method returns non null, this Locale must be used for all localization needs in the implementation. The Locale must not be cached to allow for applications that change Locale dynamically.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getLocale" return-type="java.util.Locale" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>37</id>
+      <description>Retrieves the VariableMapper associated with this ELContext.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getVariableMapper" return-type="jakarta.el.VariableMapper" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>38</id>
+      <description>Returns whether an ELResolver has successfully resolved a given (base, property) pair. The CompositeELResolver checks this property to determine whether it should consider or skip other component resolvers.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="isPropertyResolved" return-type="boolean" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>39</id>
+      <description>Associates a context object with this ELContext. The ELContext maintains a collection of context objects relevant to the evaluation of an expression. These context objects are used by ELResolvers. This method is used to add a context object to that collection. By convention, the contextObject will be of the type specified by the key. However, this is not required and the key is used strictly as a unique identifier.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="putContext" return-type="void">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>42</id>
+      <description>Constructs an ELContextEvent object to indicate that an ELContext has been created.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContextEvent</class-interface>
+      <method name="ELContextEvent" return-type="ELContextEvent">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>43</id>
+      <description>Returns the ELContext that was created. This is a type-safe equivalent of the #getSource method.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContextEvent</class-interface>
+      <method name="getELContext" return-type="jakarta.el.ELContext" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>44</id>
+      <description>Invoked when a new ELContext has been created.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContextListener</class-interface>
+      <method name="contextCreated" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContextEvent</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>45</id>
+      <description>Creates an ELException with no detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELException</class-interface>
+      <method name="ELException" return-type="ELException" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>46</id>
+      <description>Creates an ELException with the provided detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELException</class-interface>
+      <method name="ELException" return-type="ELException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>47</id>
+      <description>Creates an ELException with the given cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELException</class-interface>
+      <method name="ELException" return-type="ELException">
+        <parameters>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>48</id>
+      <description>Creates an ELException with the given detail message and root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELException</class-interface>
+      <method name="ELException" return-type="ELException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>49</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="ELResolver" return-type="ELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>50</id>
+      <description>Returns the most general type that this resolver accepts for the property argument, given a base object. One use for this method is to assist tools in auto-completion. This assists tools in auto-completion and also provides a way to express that the resolver accepts a primitive value, such as an integer index into an array. For example, the ArrayELResolver will accept any int as a property, so the return value would be Integer.class.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>51</id>
+      <description>Returns information about the set of variables or properties that can be resolved for the given base object. One use for this method is to assist tools in auto-completion. If the base parameter is null, the resolver must enumerate the list of top-level variables it can resolve. The Iterator returned must contain zero or more instances of java.beans.FeatureDescriptor, in no guaranteed order. In the case of primitive types such as int, the value null must be returned. This is to prevent the useless iteration through all possible primitive values. A return value of null indicates that this resolver does not handle the given base object or that the results are too complex to represent with this method and the #getCommonPropertyType method should be used instead. Each FeatureDescriptor will contain information about a single variable or property. In addition to the standard properties, the FeatureDescriptor must have two named attributes (as set by the setValue method): #TYPE - The value of this named attribute must be an instance of java.lang.Class and specify the runtime type of the variable or property. #RESOLVABLE_AT_DESIGN_TIME - The value of this named attribute must be an instance of java.lang.Boolean and indicates whether it is safe to attempt to resolve this property at design-time. For instance, it may be unsafe to attempt a resolution at design time if the ELResolver needs access to a resource that is only available at runtime and no acceptable simulated value can be provided. The caller should be aware that the Iterator returned might iterate through a very large or even infinitely large set of properties. Care should be taken by the caller to not get stuck in an infinite loop. This is a "best-effort" list. Not all ELResolvers will return completely accurate results, but all must be callable at both design-time and runtime (i.e. whether or not Beans.isDesignTime() returns true), without causing errors. The propertyResolved property of the ELContext is not relevant to this method. The results of all ELResolvers are concatenated in the case of composite resolvers.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>52</id>
+      <description>For a given base and property, attempts to identify the most general type that is acceptable for an object to be passed as the value parameter in a future call to the #setValue method. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. This is not always the same as getValue().getClass(). For example, in the case of an ArrayELResolver, the getType method will return the element type of the array, which might be a superclass of the type of the actual element that is currently in the specified array element.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>53</id>
+      <description>Attempts to resolve the given property object on the given base object. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>54</id>
+      <description>For a given base and property, attempts to determine whether a call to #setValue will always fail. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>55</id>
+      <description>Attempts to set the value of the given property object on the given base object. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value has been set.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>56</id>
+      <description>Determines whether the specified object is equal to this Expression. The result is true if and only if the argument is not null, is an Expression object that is the of the same type (ValueExpression or MethodExpression), and has an identical parsed representation. Note that two expressions can be equal if their expression Strings are different. For example, ${fn1:foo()} and ${fn2:foo()} are equal if their corresponding FunctionMappers mapped fn1:foo and fn2:foo to the same method.</description>
+      <package>jakarta.el</package>
+      <class-interface>Expression</class-interface>
+      <method name="equals" return-type="boolean">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>57</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>Expression</class-interface>
+      <method name="Expression" return-type="Expression" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>58</id>
+      <description>Returns the original String used to create this Expression, unmodified. This is used for debugging purposes but also for the purposes of comparison (e.g. to ensure the expression in a configuration file has not changed). This method does not provide sufficient information to re-create an expression. Two different expressions can have exactly the same expression string but different function mappings. Serialization should be used to save and restore the state of an Expression.</description>
+      <package>jakarta.el</package>
+      <class-interface>Expression</class-interface>
+      <method name="getExpressionString" return-type="java.lang.String" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>59</id>
+      <description>Returns the hash code for this Expression. See the note in the #equals method on how two expressions can be equal if their expression Strings are different. Recall that if two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. Implementations must take special note and implement hashCode correctly.</description>
+      <package>jakarta.el</package>
+      <class-interface>Expression</class-interface>
+      <method name="hashCode" return-type="int" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>60</id>
+      <description>Returns whether this expression was created from only literal text. This method must return true if and only if the expression string this expression was created from contained no unescaped EL delimeters (${...} or #{...}).</description>
+      <package>jakarta.el</package>
+      <class-interface>Expression</class-interface>
+      <method name="isLiteralText" return-type="boolean" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>62</id>
+      <description>Parses an expression into a MethodExpression for later evaluation. Use this method for expressions that refer to methods. If the expression is a String literal, a MethodExpression is created, which when invoked, returns the String literal, coerced to expectedReturnType. An ELException is thrown if expectedReturnType is void or if the coercion of the String literal to the expectedReturnType yields an error (see Section "1.16 Type Conversion"). This method should perform syntactic validation of the expression. If in doing so it detects errors, it should raise an ELException.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="createMethodExpression" return-type="jakarta.el.MethodExpression">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.lang.Class[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>63</id>
+      <description>Parses an expression into a ValueExpression for later evaluation. Use this method for expressions that refer to values. This method should perform syntactic validation of the expression. If in doing so it detects errors, it should raise an ELException.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="createValueExpression" return-type="jakarta.el.ValueExpression">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>64</id>
+      <description>Creates a ValueExpression that wraps an object instance. This method can be used to pass any object as a ValueExpression. The wrapper ValueExpression is read only, and returns the wrapped object via its getValue() method, optionally coerced.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="createValueExpression" return-type="jakarta.el.ValueExpression">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>65</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="ExpressionFactory" return-type="ExpressionFactory" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>66</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>FunctionMapper</class-interface>
+      <method name="FunctionMapper" return-type="FunctionMapper" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>67</id>
+      <description>Resolves the specified prefix and local name into a java.lang.Method. Returns null if no function could be found that matches the given prefix and local name.</description>
+      <package>jakarta.el</package>
+      <class-interface>FunctionMapper</class-interface>
+      <method name="resolveFunction" return-type="java.lang.reflect.Method">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>68</id>
+      <description>If the base object is a list, returns the most general type that this resolver accepts for the property argument. Otherwise, returns null. Assuming the base is a List, this method will always return Integer.class. This is because Lists accept integers as their index.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>69</id>
+      <description>Always returns null, since there is no reason to iterate through set set of all integers. The #getCommonPropertyType method returns sufficient information about what properties this resolver accepts.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>70</id>
+      <description>If the base object is a list, returns the most general acceptable type for a value in this list. If the base is a List, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. Assuming the base is a List, this method will always return Object.class. This is because Lists accept any object as an element.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>71</id>
+      <description>If the base object is a list, returns the value at the given index. The index is specified by the property argument, and coerced into an integer. If the coercion could not be performed, an IllegalArgumentException is thrown. If the index is out of bounds, null is returned. If the base is a List, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>72</id>
+      <description>If the base object is a list, returns whether a call to #setValue will always fail. If the base is a List, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. If this resolver was constructed in read-only mode, this method will always return true. If a List was created using java.util.Collections#unmodifiableList, this method must return true. Unfortunately, there is no Collections API method to detect this. However, an implementation can create a prototype unmodifiable List and query its runtime type to see if it matches the runtime type of the base object as a workaround.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>73</id>
+      <description>Creates a new read/write ListELResolver.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="ListELResolver" return-type="ListELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>74</id>
+      <description>Creates a new ListELResolver whose read-only status is determined by the given parameter.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="ListELResolver" return-type="ListELResolver">
+        <parameters>
+          <parameter>boolean</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>75</id>
+      <description>If the base object is a list, attempts to set the value at the given index with the given value. The index is specified by the property argument, and coerced into an integer. If the coercion could not be performed, an IllegalArgumentException is thrown. If the index is out of bounds, a PropertyNotFoundException is thrown. If the base is a List, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value was set. If this resolver was constructed in read-only mode, this method will always throw PropertyNotWritableException. If a List was created using java.util.Collections#unmodifiableList, this method must throw PropertyNotWritableException. Unfortunately, there is no Collections API method to detect this. However, an implementation can create a prototype unmodifiable List and query its runtime type to see if it matches the runtime type of the base object as a workaround.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>76</id>
+      <description>If the base object is a map, returns the most general type that this resolver accepts for the property argument. Otherwise, returns null. Assuming the base is a Map, this method will always return Object.class. This is because Maps accept any object as a key.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>77</id>
+      <description>If the base object is a map, returns an Iterator containing the set of keys available in the Map. Otherwise, returns null. The Iterator returned must contain zero or more instances of java.beans.FeatureDescriptor. Each info object contains information about a key in the Map, and is initialized as follows: displayName - The return value of calling the toString method on this key, or "null" if the key is null. name - Same as displayName property. shortDescription - Empty string expert - false hidden - false preferred - true In addition, the following named attributes must be set in the returned FeatureDescriptors: ELResolver#TYPE - The return value of calling the getClass() method on this key, or null if the key is null. ELResolver#RESOLVABLE_AT_DESIGN_TIME - true</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>78</id>
+      <description>If the base object is a map, returns the most general acceptable type for a value in this map. If the base is a Map, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. Assuming the base is a Map, this method will always return Object.class. This is because Maps accept any object as the value for a given key.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>79</id>
+      <description>If the base object is a map, returns the value associated with the given key, as specified by the property argument. If the key was not found, null is returned. If the base is a Map, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. Just as in java.util.Map#get, just because null is returned doesn't mean there is no mapping for the key; it's also possible that the Map explicitly maps the key to null.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>80</id>
+      <description>If the base object is a map, returns whether a call to #setValue will always fail. If the base is a Map, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. If this resolver was constructed in read-only mode, this method will always return true. If a Map was created using java.util.Collections#unmodifiableMap, this method must return true. Unfortunately, there is no Collections API method to detect this. However, an implementation can create a prototype unmodifiable Map and query its runtime type to see if it matches the runtime type of the base object as a workaround.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>81</id>
+      <description>Creates a new read/write MapELResolver.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="MapELResolver" return-type="MapELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>82</id>
+      <description>Creates a new MapELResolver whose read-only status is determined by the given parameter.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="MapELResolver" return-type="MapELResolver">
+        <parameters>
+          <parameter>boolean</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>83</id>
+      <description>If the base object is a map, attempts to set the value associated with the given key, as specified by the property argument. If the base is a Map, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value was set. If this resolver was constructed in read-only mode, this method will always throw PropertyNotWritableException. If a Map was created using java.util.Collections#unmodifiableMap, this method must throw PropertyNotWritableException. Unfortunately, there is no Collections API method to detect this. However, an implementation can create a prototype unmodifiable Map and query its runtime type to see if it matches the runtime type of the base object as a workaround.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>84</id>
+      <description>Evaluates the expression relative to the provided context, and returns information about the actual referenced method.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="getMethodInfo" return-type="jakarta.el.MethodInfo">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>86</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="MethodExpression" return-type="MethodExpression" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>87</id>
+      <description>Returns the name of the method</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodInfo</class-interface>
+      <method name="getName" return-type="java.lang.String" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>88</id>
+      <description>Returns the parameter types of the method</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodInfo</class-interface>
+      <method name="getParamTypes" return-type="java.lang.Class[]" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>89</id>
+      <description>Returns the return type of the method</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodInfo</class-interface>
+      <method name="getReturnType" return-type="java.lang.Class" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>90</id>
+      <description>Creates a new instance of MethodInfo with the given information.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodInfo</class-interface>
+      <method name="MethodInfo" return-type="MethodInfo">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.lang.Class[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>91</id>
+      <description>Creates a MethodNotFoundException with no detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodNotFoundException</class-interface>
+      <method name="MethodNotFoundException" return-type="MethodNotFoundException" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>92</id>
+      <description>Creates a MethodNotFoundException with the provided detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodNotFoundException</class-interface>
+      <method name="MethodNotFoundException" return-type="MethodNotFoundException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>93</id>
+      <description>Creates a MethodNotFoundException with the given root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodNotFoundException</class-interface>
+      <method name="MethodNotFoundException" return-type="MethodNotFoundException">
+        <parameters>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>94</id>
+      <description>Creates a MethodNotFoundException with the given detail message and root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodNotFoundException</class-interface>
+      <method name="MethodNotFoundException" return-type="MethodNotFoundException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>95</id>
+      <description>Creates a PropertyNotFoundException with no detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>PropertyNotFoundException</class-interface>
+      <method name="PropertyNotFoundException" return-type="PropertyNotFoundException" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>96</id>
+      <description>Creates a PropertyNotFoundException with the provided detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>PropertyNotFoundException</class-interface>
+      <method name="PropertyNotFoundException" return-type="PropertyNotFoundException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>97</id>
+      <description>Creates a PropertyNotFoundException with the given root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>PropertyNotFoundException</class-interface>
+      <method name="PropertyNotFoundException" return-type="PropertyNotFoundException">
+        <parameters>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>98</id>
+      <description>Creates a PropertyNotFoundException with the given detail message and root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>PropertyNotFoundException</class-interface>
+      <method name="PropertyNotFoundException" return-type="PropertyNotFoundException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>99</id>
+      <description>Creates a PropertyNotWritableException with no detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>PropertyNotWritableException</class-interface>
+      <method name="PropertyNotWritableException" return-type="PropertyNotWritableException" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>100</id>
+      <description>Creates a PropertyNotWritableException with the provided detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>PropertyNotWritableException</class-interface>
+      <method name="PropertyNotWritableException" return-type="PropertyNotWritableException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>101</id>
+      <description>Creates a PropertyNotWritableException with the given root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>PropertyNotWritableException</class-interface>
+      <method name="PropertyNotWritableException" return-type="PropertyNotWritableException">
+        <parameters>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>102</id>
+      <description>Creates a PropertyNotWritableException with the given detail message and root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>PropertyNotWritableException</class-interface>
+      <method name="PropertyNotWritableException" return-type="PropertyNotWritableException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>103</id>
+      <description>If the base object is a ResourceBundle, returns the most general type that this resolver accepts for the property argument. Otherwise, returns null. Assuming the base is a ResourceBundle, this method will always return String.class.</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>104</id>
+      <description>If the base object is a ResourceBundle, returns an Iterator containing the set of keys available in the ResourceBundle. Otherwise, returns null. The Iterator returned must contain zero or more instances of java.beans.FeatureDescriptor. Each info object contains information about a key in the ResourceBundle, and is initialized as follows: displayName - The String key name - Same as displayName property. shortDescription - Empty string expert - false hidden - false preferred - true In addition, the following named attributes must be set in the returned FeatureDescriptors: ELResolver#TYPE - String.class ELResolver#RESOLVABLE_AT_DESIGN_TIME - true</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>105</id>
+      <description>If the base object is an instance of ResourceBundle, return null, since the resolver is read only. If the base is ResourceBundle, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>106</id>
+      <description>If the base object is an instance of ResourceBundle, the provided property will first be coerced to a String. The Object returned by getObject on the base ResourceBundle will be returned. If the base is ResourceBundle, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>107</id>
+      <description>If the base object is not null and an instanceof ResourceBundle, return true.</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>108</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="ResourceBundleELResolver" return-type="ResourceBundleELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>109</id>
+      <description>If the base object is a ResourceBundle, throw a PropertyNotWritableException.</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>110</id>
+      <description>Returns the type the result of the expression will be coerced to after evaluation.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getExpectedType" return-type="java.lang.Class" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>111</id>
+      <description>Evaluates the expression relative to the provided context, and returns the most general type that is acceptable for an object to be passed as the value parameter in a future call to the #setValue method. This is not always the same as getValue().getClass(). For example, in the case of an expression that references an array element, the getType method will return the element type of the array, which might be a superclass of the type of the actual element that is currently in the specified array element.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>112</id>
+      <description>Evaluates the expression relative to the provided context, and returns the resulting value. The resulting value is automatically coerced to the type returned by getExpectedType(), which was provided to the ExpressionFactory when this expression was created.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>113</id>
+      <description>Evaluates the expression relative to the provided context, and returns true if a call to #setValue will always fail.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>114</id>
+      <description>Evaluates the expression relative to the provided context, and sets the result to the provided value.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>115</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="ValueExpression" return-type="ValueExpression" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>116</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>VariableMapper</class-interface>
+      <method name="resolveVariable" return-type="jakarta.el.ValueExpression">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>117</id>
+      <description>Assign a ValueExpression to an EL variable, replacing any previously assignment to the same variable. The assignment for the variable is removed if the expression is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>VariableMapper</class-interface>
+      <method name="setVariable" return-type="jakarta.el.ValueExpression">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>jakarta.el.ValueExpression</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>118</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>VariableMapper</class-interface>
+      <method name="VariableMapper" return-type="VariableMapper" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>40</id>
+      <description>Sets the Locale for this instance. This method may be called by the party creating the instance, such as JavaServer Faces or JSP, to enable the EL implementation to provide localized messages to the user. If no Locale is set, the implementation must use the locale returned by Locale.getDefault( ).</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="setLocale" return-type="void">
+        <parameters>
+          <parameter>java.util.Locale</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>85</id>
+      <description>If a String literal is specified as the expression, returns the String literal coerced to the expected return type of the method signature. An ELException is thrown if expectedReturnType is void or if the coercion of the String literal to the expectedReturnType yields an error (see Section "1.18 Type Conversion" of the EL specification). If not a String literal, evaluates the expression relative to the provided context, invokes the method that was found using the supplied parameters, and returns the result of the method invocation. Any parameters passed to this method is ignored if isLiteralText() or isParmetersProvided() is true.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:121</id>
+      <description>if the given index is out of bounds for this array.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:122</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:123</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:124</id>
+      <description>if the property could not be coerced into an integer.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.IllegalArgumentException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:125</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:126</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:127</id>
+      <description>if the given index is out of bounds for this array.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:128</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:129</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:130</id>
+      <description>if the class of the specified element prevents it from being added to this array.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.ClassCastException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:131</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:132</id>
+      <description>if the property could not be coerced into an integer, or if some aspect of the specified element prevents it from being added to this array.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.IllegalArgumentException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:133</id>
+      <description>if this resolver was constructed in read-only mode.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:134</id>
+      <description>if the given index is out of bounds for this array.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:135</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ArrayELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:136</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:137</id>
+      <description>if base is not null and the specified property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:138</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:139</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:140</id>
+      <description>if base is not null and the specified property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:141</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:142</id>
+      <description>If the base object is not null, invoke the method, with the given parameters on this bean. The return value from the method is returned. If the base is not null, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. The provided method object will first be coerced to a String. The methods in the bean is then examined and an attempt will be made to select one for invocation. If no suitable can be found, a MethodNotFoundException is thrown. If the given paramTypes is not null, select the method with the given name and parameter types. Else select the method with the given name that has the same number of parameters. If there are more than one such method, the method selection process is undefined. Else select the method with the given name that takes a variable number of arguments. Note the resolution for overloaded methods will likely be clarified in a future version of the spec. The provide parameters are coerced to the correcponding parameter types of the method, and the method is then invoked.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:143</id>
+      <description>if no suitable method can be found.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.MethodNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:144</id>
+      <description>if an exception was thrown while performing (base, method) resolution. The thrown exception must be included as the cause property of this exception, if available. If the exception thrown is an InvocationTargetException, extract its cause and pass it to the ELException constructor.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:145</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:146</id>
+      <description>if base is not null and the specified property does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:147</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:148</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:149</id>
+      <description>if base is not null and the specified property does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:150</id>
+      <description>if this resolver was constructed in read-only mode, or if there is no setter for the property.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="false">
+      <id>EL:JAVADOC:151</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:152</id>
+      <description>Constructor</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="BeanNameELResolver" return-type="BeanNameELResolver">
+        <parameters>
+          <parameter>jakarta.el.BeanNameResolver</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:153</id>
+      <description>Always returns String.class, since a bean name is a String.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:154</id>
+      <description>Always returns null, since there is no reason to iterate through a list of one element: bean name.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:155</id>
+      <description>If the base is null and the property is a name resolvable by the BeanNameResolver, return the type of the bean. If the name is resolvable by the BeanNameResolver, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value has been set.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:156</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:157</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:159</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:160</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:161</id>
+      <description>If the base is null and the property is a name resolvable by the BeanNameResolver, attempts to determine if the bean is writable. If the name is resolvable by the BeanNameResolver, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value has been set.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:162</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:163</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:164</id>
+      <description>If the base is null and the property is a name that is resolvable by the BeanNameResolver, the bean in the BeanNameResolver is set to the given value. If the name is resolvable by the BeanNameResolver, or if the BeanNameResolver allows creating a new bean, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value has been set.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:165</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:166</id>
+      <description>if the BeanNameResolver does not allow the bean to be modified.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:167</id>
+      <description>if an exception was thrown while attempting to set the bean with the given name. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:168</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>BeanNameResolver</class-interface>
+      <method name="BeanNameResolver" return-type="BeanNameResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:169</id>
+      <description>Allow creating a bean of the given name if it does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameResolver</class-interface>
+      <method name="canCreateBean" return-type="boolean">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:170</id>
+      <description>Returns the bean known by its name.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameResolver</class-interface>
+      <method name="getBean" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:171</id>
+      <description>Indicates if the bean of the given name is read-only or writable</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:172</id>
+      <description>Sets a value to a bean of the given name. If the bean of the given name does not exist and if #canCreateBean is true, one is created with the given value.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameResolver</class-interface>
+      <method name="setBeanValue" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:173</id>
+      <description>if the bean cannot be modified or created.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameResolver</class-interface>
+      <method name="setBeanValue" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:174</id>
+      <description>If the provided resolver is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="add" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELResolver</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:175</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:176</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:177</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:178</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:179</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:180</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:181</id>
+      <description>Attemps to resolve and invoke the given method on the given base object by querying all component resolvers. If this resolver handles the given (base, method) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. First, propertyResolved is set to false on the provided ELContext. Next, for each component resolver in this composite: The invoke() method is called, passing in the provided context, base, method, paramTypes, and params. If the ELContext's propertyResolved flag is false then iteration continues. Otherwise, iteration stops and no more component resolvers are considered. The value returned by getValue() is returned by this method. If none of the component resolvers were able to perform this operation, the value null is returned and the propertyResolved flag remains set to false. Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:182</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:183</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:184</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:185</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:186</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:187</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property is not writable.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:188</id>
+      <description>if an exception was thrown while attempting to set the property or variable. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:192</id>
+      <description>Installs a Lambda argument map, in preparation for the evaluation of a Lambda expression. The arguments in the map will be in scope during the evaluation of the Lambda expression.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="enterLambdaScope" return-type="void">
+        <parameters>
+          <parameter>java.util.Map</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:193</id>
+      <description>Exits the Lambda expression evaluation. The Lambda argument map that was previously installed is removed.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="exitLambdaScope" return-type="void" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:194</id>
+      <description>if key is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getContext" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:195</id>
+      <description>Retrieves the ImportHandler associated with this ELContext.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getImportHandler" return-type="jakarta.el.ImportHandler" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:196</id>
+      <description>Retrieves the Lambda argument associated with a formal parameter. If the Lambda expression is nested within other Lambda expressions, the arguments for the current Lambda expression is first searched, and if not found, the arguments for the immediate nesting Lambda expression then searched, and so on.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getLambdaArgument" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:198</id>
+      <description>if key is null or contextObject is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="putContext" return-type="void">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:200</id>
+      <description>Add an user defined ELResolver to the list of ELResolvers. Can be called multiple times. The new ELResolver is placed ahead of the default ELResolvers. The list of the ELResolvers added this way are ordered chronologically.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="addELResolver" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELResolver</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:202</id>
+      <description>Define a bean in the local bean repository</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="defineBean" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:203</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="ELManager" return-type="ELManager" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:204</id>
+      <description>Return the ELContext used for parsing and evaluating EL expressions. If there is currently no ELContext, a default instance of StandardELContext is returned.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="getELContext" return-type="jakarta.el.StandardELContext" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:206</id>
+      <description>Import a class. The imported class must be loadable from the classloader, at class resolution time.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="importClass" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:207</id>
+      <description>if the name is not a full class name.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="importClass" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:208</id>
+      <description>Import a package. At the class resolution time, the imported package name will be used to construct the full class name, which will then be used to load the class. Inherently, this is less efficient than importing a class.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="importPackage" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:209</id>
+      <description>Maps a static method to an EL function.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="mapFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.reflect.Method</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:210</id>
+      <description>Set the ELContext used for parsing and evaluating EL expressions. The supplied ELContext will not be modified, except for the context object map.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="setELContext" return-type="jakarta.el.ELContext">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:211</id>
+      <description>Assign a ValueExpression to an EL variable, replacing any previous assignment to the same variable. The assignment for the variable is removed if the expression is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="setVariable" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>jakarta.el.ValueExpression</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:212</id>
+      <description>Define a bean in a local bean repository, hiding other beans of the same name.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="defineBean" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:213</id>
+      <description>Define an EL function in the local function mapper.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="defineFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:215</id>
+      <description>if the method (with or without the signature) is not a declared method of the class, or if the method signature is not valid.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="defineFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+        <throw>java.lang.NoSuchMethodException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:218</id>
+      <description>Define an EL function in the local function mapper.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="defineFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.reflect.Method</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:219</id>
+      <description>if any of the arguements is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="defineFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.reflect.Method</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:220</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="ELProcessor" return-type="ELProcessor" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:221</id>
+      <description>Evaluates an EL expression.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="eval" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:222</id>
+      <description>Return the ELManager used for EL porcessing.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="getELManager" return-type="jakarta.el.ELManager" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:223</id>
+      <description>Evaluates an EL expression, and coerces the result to the specified type.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:224</id>
+      <description>Sets an expression with a new value. The target expression is evaluated, up to the last property resolution, and the resultant (base, property) pair is set to the provided value.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:225</id>
+      <description>if one of the property resolutions failed because a specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:226</id>
+      <description>if the final variable or property resolution failed because the specified variable or property is not writable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:227</id>
+      <description>if an exception was thrown while attempting to set the property or variable. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:228</id>
+      <description>Assign an EL expression to an EL variable. The expression is parsed, but not evaluated, and the parsed expression is mapped to the EL variable in the local variable map. Any previously assigned expression to the same variable will be replaced. If the expression is null, the variable will be removed.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="setVariable" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:229</id>
+      <description>Converts an object to a specific type. An ELException is thrown if an error occurs during the conversion.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="convertToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:230</id>
+      <description>thrown if errors occur.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="convertToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:231</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:232</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:233</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:234</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:235</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:236</id>
+      <description>Attemps to resolve and invoke the given method on the given base object. If this resolver handles the given (base, method) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. A default implementation is provided that returns null so that existing classes that extend ELResolver can continue to function.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:237</id>
+      <description>if no suitable method can be found.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.MethodNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:238</id>
+      <description>if an exception was thrown while performing (base, method) resolution. The thrown exception must be included as the cause property of this exception, if available. If the exception thrown is an InvocationTargetException, extract its cause and pass it to the ELException constructor.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:239</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:240</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:241</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:242</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:243</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:244</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property is not writable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:245</id>
+      <description>if an exception was thrown while attempting to set the property or variable. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:251</id>
+      <description>thrown if an error results from applying the conversion rules.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="coerceToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:252</id>
+      <description>Thrown if there are syntactical errors in the provided expression.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="createMethodExpression" return-type="jakarta.el.MethodExpression">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.lang.Class[]</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:253</id>
+      <description>if paramTypes is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="createMethodExpression" return-type="jakarta.el.MethodExpression">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.lang.Class[]</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:254</id>
+      <description>Thrown if expectedType is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="createValueExpression" return-type="jakarta.el.ValueExpression">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:255</id>
+      <description>Thrown if there are syntactical errors in the provided expression.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="createValueExpression" return-type="jakarta.el.ValueExpression">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:256</id>
+      <description>Thrown if expectedType is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="createValueExpression" return-type="jakarta.el.ValueExpression">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:258</id>
+      <description>Creates a new instance of a ExpressionFactory. This method uses the following ordered lookup procedure to determine the ExpressionFactory implementation class to load: Use the Services API (as detailed in the JAR specification). If a resource with the name of META-INF/services/jakarta.el.ExpressionFactory exists, then its first line, if present, is used as the UTF-8 encoded name of the implementation class. Use the properties file "lib/el.properties" in the JRE directory. If this file exists and it is readable by the java.util.Properties.load(InputStream) method, and it contains an entry whose key is "jakarta.el.ExpressionFactory", then the value of that entry is used as the name of the implementation class. Use the jakarta.el.ExpressionFactory system property. If a system property with this name is defined, then its value is used as the name of the implementation class. Use a platform default implementation.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="newInstance" return-type="jakarta.el.ExpressionFactory" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:259</id>
+      <description>Create a new instance of a ExpressionFactory, with optional properties. This method uses the same lookup procedure as the one used in newInstance(). If the argument properties is not null, and if the implementation contains a constructor with a single parameter of type java.util.Properties, then the constructor is used to create the instance. Properties are optional and can be ignored by an implementation. The name of a property should start with "jakarta.el." The following are some suggested names for properties. jakarta.el.cacheSize</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="newInstance" return-type="jakarta.el.ExpressionFactory">
+        <parameters>
+          <parameter>java.util.Properties</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:260</id>
+      <description>Adds a static method that can be used as a function.</description>
+      <package>jakarta.el</package>
+      <class-interface>FunctionMapper</class-interface>
+      <method name="mapFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.reflect.Method</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:262</id>
+      <description>Import a class.</description>
+      <package>jakarta.el</package>
+      <class-interface>ImportHandler</class-interface>
+      <method name="importClass" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:263</id>
+      <description>if the name is not a full class name.</description>
+      <package>jakarta.el</package>
+      <class-interface>ImportHandler</class-interface>
+      <method name="importClass" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:264</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ImportHandler</class-interface>
+      <method name="ImportHandler" return-type="ImportHandler" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:265</id>
+      <description>Import all the classes in a package.</description>
+      <package>jakarta.el</package>
+      <class-interface>ImportHandler</class-interface>
+      <method name="importPackage" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:266</id>
+      <description>Resolve a class name from its imports.</description>
+      <package>jakarta.el</package>
+      <class-interface>ImportHandler</class-interface>
+      <method name="resolve" return-type="java.lang.Class">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:273</id>
+      <description>if not enough arguments are provided</description>
+      <package>jakarta.el</package>
+      <class-interface>LambdaExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:274</id>
+      <description>Creates a new LambdaExpression.</description>
+      <package>jakarta.el</package>
+      <class-interface>LambdaExpression</class-interface>
+      <method name="LambdaExpression" return-type="LambdaExpression">
+        <parameters>
+          <parameter>java.util.List</parameter>
+          <parameter>jakarta.el.ValueExpression</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:275</id>
+      <description>if the given index is out of bounds for this list.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:276</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:277</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:278</id>
+      <description>if the property could not be coerced into an integer.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.IllegalArgumentException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:279</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:280</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:281</id>
+      <description>if the given index is out of bounds for this list.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:282</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:283</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:284</id>
+      <description>if the class of the specified element prevents it from being added to this list.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.ClassCastException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:285</id>
+      <description>if context is null, or if the value is null and this List does not support null elements.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:286</id>
+      <description>if the property could not be coerced into an integer, or if some aspect of the specified element prevents it from being added to this list.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.IllegalArgumentException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:287</id>
+      <description>if this resolver was constructed in read-only mode, or if the set operation is not supported by the underlying list.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:288</id>
+      <description>if the given index is out of bounds for this list.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:289</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ListELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:290</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:291</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:292</id>
+      <description>if the key is of an inappropriate type for this map (optionally thrown by the underlying Map).</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.ClassCastException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:293</id>
+      <description>if context is null, or if the key is null and this map does not permit null keys (the latter is optionally thrown by the underlying Map).</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:294</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:295</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:296</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:297</id>
+      <description>if the class of the specified key or value prevents it from being stored in this map.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.ClassCastException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:298</id>
+      <description>if context is null, or if this map does not permit null keys or values, and the specified key or value is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:299</id>
+      <description>if some aspect of this key or value prevents it from being stored in this map.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.IllegalArgumentException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:300</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:301</id>
+      <description>if this resolver was constructed in read-only mode, or if the put operation is not supported by the underlying map.</description>
+      <package>jakarta.el</package>
+      <class-interface>MapELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:302</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="getMethodInfo" return-type="jakarta.el.MethodInfo">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:303</id>
+      <description>if one of the property resolutions failed because a specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="getMethodInfo" return-type="jakarta.el.MethodInfo">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:304</id>
+      <description>if no suitable method can be found.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="getMethodInfo" return-type="jakarta.el.MethodInfo">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.MethodNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:305</id>
+      <description>if an exception was thrown while performing property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="getMethodInfo" return-type="jakarta.el.MethodInfo">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:306</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:307</id>
+      <description>if one of the property resolutions failed because a specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:308</id>
+      <description>if no suitable method can be found.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.MethodNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:309</id>
+      <description>if a String literal is specified and expectedReturnType of the MethodExpression is void or if the coercion of the String literal to the expectedReturnType yields an error (see Section "1.18 Type Conversion").</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:310</id>
+      <description>if an exception was thrown while performing property or variable resolution. The thrown exception must be included as the cause property of this exception, if available. If the exception thrown is an InvocationTargetException, extract its cause and pass it to the ELException constructor.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:311</id>
+      <description>Return whether this MethodExpression was created with parameters. This method must return true if and only if parameters are specified in the EL, using the expr-a.expr-b(...) syntax.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="isParametersProvided" return-type="boolean" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:312</id>
+      <description>Use isParametersProvided instead.</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodExpression</class-interface>
+      <method name="isParmetersProvided" return-type="boolean" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:313</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:314</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:315</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:316</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:317</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:318</id>
+      <description>Always thrown if base is an instance of ReasourceBundle.</description>
+      <package>jakarta.el</package>
+      <class-interface>ResourceBundleELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:319</id>
+      <description>Add a custom ELResolver to the context. The list of the custom ELResolvers will be accessed in the order they are added. A custom ELResolver added to the context cannot be removed.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="addELResolver" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELResolver</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:320</id>
+      <description>Returns the context object associated with the given key. The ELContext maintains a collection of context objects relevant to the evaluation of an expression. These context objects are used by ELResolvers. This method is used to retrieve the context with the given key from the collection. By convention, the object returned will be of the type specified by the key. However, this is not required and the key is used strictly as a unique identifier.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="getContext" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:321</id>
+      <description>if key is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="getContext" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:323</id>
+      <description>Construct (if needed) and return a default FunctionMapper.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="getFunctionMapper" return-type="jakarta.el.FunctionMapper" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:325</id>
+      <description>Construct (if needed) and return a default VariableMapper() {</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="getVariableMapper" return-type="jakarta.el.VariableMapper" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:326</id>
+      <description>Associates a context object with this ELContext. The ELContext maintains a collection of context objects relevant to the evaluation of an expression. These context objects are used by ELResolvers. This method is used to add a context object to that collection. By convention, the contextObject will be of the type specified by the key. However, this is not required and the key is used strictly as a unique identifier.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="putContext" return-type="void">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:327</id>
+      <description>if key is null or contextObject is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="putContext" return-type="void">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:329</id>
+      <description>Construct a StandardELContext from another ELContext.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="StandardELContext" return-type="StandardELContext">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:330</id>
+      <description>Returns the type of the property. Always returns String.class, since a field name is a String.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:331</id>
+      <description>Returns the properties that can be resolved. Always returns null, since there is no reason to iterate through a list of one element: field name.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:332</id>
+      <description>Returns the type of a static field. If the base object is an instance of ELClassand the property is a String, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value has been set. If the property is the string "class", returns java.lang.Class.class. If the property string is a public static field of class specified in ELClass, return the type of the static field.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:333</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:334</id>
+      <description>if field is not a public static filed of the class, or if the field is inacessible.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:336</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:337</id>
+      <description>if the specified class does not exist, or if the field is not a public static filed of the class, or if the field is inacessible.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:339</id>
+      <description>if no suitable method can be found.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.MethodNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:340</id>
+      <description>if an exception was thrown while performing (base, method) resolution. The thrown exception must be included as the cause property of this exception, if available. If the exception thrown is an InvocationTargetException, extract its cause and pass it to the ELException constructor.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:341</id>
+      <description>Inquires whether the static field is writable. If the base object is an instance of ELClassand the property is a String, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value has been set. Always returns a true because writing to a static field is not allowed.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:342</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:343</id>
+      <description>Attempts to write to a static field. If the base object is an instance of ELClassand the property is String, a PropertyNotWritableException will always be thrown, because writing to a static field is not allowed.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:344</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:345</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:346</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="StaticFieldELResolver" return-type="StaticFieldELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:347</id>
+      <description>Converts an object to a specific type. An ELException is thrown if an error occurs during the conversion.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="convertToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:348</id>
+      <description>thrown if errors occur.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="convertToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:349</id>
+      <description>Returns the most general type that this resolver accepts for the property argument, given a base object. One use for this method is to assist tools in auto-completion. This assists tools in auto-completion and also provides a way to express that the resolver accepts a primitive value, such as an integer index into an array. For example, the ArrayELResolver will accept any int as a property, so the return value would be Integer.class.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getCommonPropertyType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:350</id>
+      <description>Returns information about the set of variables or properties that can be resolved for the given base object. One use for this method is to assist tools in auto-completion. If the base parameter is null, the resolver must enumerate the list of top-level variables it can resolve. The Iterator returned must contain zero or more instances of java.beans.FeatureDescriptor, in no guaranteed order. In the case of primitive types such as int, the value null must be returned. This is to prevent the useless iteration through all possible primitive values. A return value of null indicates that this resolver does not handle the given base object or that the results are too complex to represent with this method and the #getCommonPropertyType method should be used instead. Each FeatureDescriptor will contain information about a single variable or property. In addition to the standard properties, the FeatureDescriptor must have two named attributes (as set by the setValue method): #TYPE - The value of this named attribute must be an instance of java.lang.Class and specify the runtime type of the variable or property. #RESOLVABLE_AT_DESIGN_TIME - The value of this named attribute must be an instance of java.lang.Boolean and indicates whether it is safe to attempt to resolve this property at design-time. For instance, it may be unsafe to attempt a resolution at design time if the ELResolver needs access to a resource that is only available at runtime and no acceptable simulated value can be provided. The caller should be aware that the Iterator returned might iterate through a very large or even infinitely large set of properties. Care should be taken by the caller to not get stuck in an infinite loop. This is a "best-effort" list. Not all ELResolvers will return completely accurate results, but all must be callable at both design-time and runtime (i.e. whether or not Beans.isDesignTime() returns true), without causing errors. The propertyResolved property of the ELContext is not relevant to this method. The results of all ELResolvers are concatenated in the case of composite resolvers.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getFeatureDescriptors" return-type="java.util.Iterator">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:351</id>
+      <description>For a given base and property, attempts to identify the most general type that is acceptable for an object to be passed as the value parameter in a future call to the #setValue method. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. This is not always the same as getValue().getClass(). For example, in the case of an ArrayELResolver, the getType method will return the element type of the array, which might be a superclass of the type of the actual element that is currently in the specified array element.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:352</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:353</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:354</id>
+      <description>Attempts to resolve the given property object on the given base object. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:355</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:356</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:357</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:358</id>
+      <description>For a given base and property, attempts to determine whether a call to #setValue will always fail. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:359</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:360</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:361</id>
+      <description>if an exception was thrown while performing the property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:362</id>
+      <description>Attempts to set the value of the given property object on the given base object. If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller can safely assume no value has been set.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:363</id>
+      <description>if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:364</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property does not exist.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:365</id>
+      <description>if the given (base, property) pair is handled by this ELResolver but the specified variable or property is not writable.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:366</id>
+      <description>if an exception was thrown while attempting to set the property or variable. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:367</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>TypeConverter</class-interface>
+      <method name="TypeConverter" return-type="TypeConverter" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:368</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:369</id>
+      <description>if one of the property resolutions failed because a specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:370</id>
+      <description>if an exception was thrown while performing property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getType" return-type="java.lang.Class">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:371</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:372</id>
+      <description>if one of the property resolutions failed because a specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:373</id>
+      <description>if an exception was thrown while performing property or variable resolution. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:374</id>
+      <description>Returns a ValueReference for this expression instance.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="getValueReference" return-type="jakarta.el.ValueReference">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:375</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:376</id>
+      <description>if one of the property resolutions failed because a specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:377</id>
+      <description>if an exception was thrown while performing property or variable resolution. The thrown exception must be included as the cause property of this exception, if available. * @throws NullPointerException if context is null</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="isReadOnly" return-type="boolean">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:378</id>
+      <description>if context is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:379</id>
+      <description>if one of the property resolutions failed because a specified variable or property does not exist or is not readable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:380</id>
+      <description>if the final variable or property resolution failed because the specified variable or property is not writable.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.PropertyNotWritableException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:381</id>
+      <description>if an exception was thrown while attempting to set the property or variable. The thrown exception must be included as the cause property of this exception, if available.</description>
+      <package>jakarta.el</package>
+      <class-interface>ValueExpression</class-interface>
+      <method name="setValue" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:382</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ValueReference</class-interface>
+      <method name="getBase" return-type="java.lang.Object" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:383</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ValueReference</class-interface>
+      <method name="getProperty" return-type="java.lang.Object" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:384</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>ValueReference</class-interface>
+      <method name="ValueReference" return-type="ValueReference">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <!-- ********************************************************************************** -->
+    <!-- ********************************************************************************** -->
+    <!-- MODIFIED ASSERTIONS LISTED BELOW -->
+    <!-- The original assertion is followed by the modified version -->
+    <!-- of the assertion. Users must edit the file to verify -->
+    <!-- that the modified assertion is correct. User should then -->
+    <!-- delete the original assertion or use the style sheet -->
+    <!-- that removes them automatically.  The original and modified -->
+    <!-- assertions differ by their IDs, notice the original assertion -->
+    <!-- now ends with "__OLD" -->
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>41</id>
+      <description>Called to indicate that a ELResolver has successfully resolved a given (base, property) pair. Use #setPropertyResolved(Object, Object) if resolved is true and to notify EvaluationListeners. The CompositeELResolver checks this property to determine whether it should consider or skip other component resolvers.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="setPropertyResolved" return-type="void">
+        <parameters>
+          <parameter>boolean</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>61</id>
+      <description>Coerces an object to a specific type according to the EL type conversion rules. The custom type conversions in the ELResolvers are not considered. An ELException is thrown if an error results from applying the conversion rules.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="coerceToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:158</id>
+      <description>If the base object is null and the property is a name that is resolvable by the BeanNameResolver, returns the value resolved by the BeanNameResolver. If name is resolved by the BeanNameResolver, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:199</id>
+      <description>Register a BeanNameResolver. Construct a BeanNameELResolver with the BeanNameResolver and add it to the list of ELResolvers. Once registered, the BeanNameResolver cannot be removed.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="addBeanNameResolver" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.BeanNameResolver</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:205</id>
+      <description>Return the ExpressionFactory instance used for EL evaluations.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="getExpressionFactory" return-type="jakarta.el.ExpressionFactory" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:214</id>
+      <description>if the specified class does not exists.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="defineFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+        <throw>java.lang.ClassNotFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:216</id>
+      <description>if any of the arguments is null.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="defineFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:272</id>
+      <description>Invoke the encapsulated Lambda expression. The supplied arguments are matched, in the same order, to the formal parameters. If there are more arguments than the formal parameters, the extra arguments are ignored. If there are less arguments than the formal parameters, an ELException is thrown. The actual Lambda arguments are added to the ELContext and are available during the evaluation of the Lambda expression. They are removed after the evaluation.</description>
+      <package>jakarta.el</package>
+      <class-interface>LambdaExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:322</id>
+      <description>Construct (if needed) and return a default ELResolver. Retrieves the ELResolver associated with this context. This is a CompositeELResover consists of an ordered list of ELResolvers. A BeanNameELResolver for beans defined locally Any custom ELResolvers An ELResolver supporting the collection operations A StaticFieldELResolver for resolving static fields A MapELResolver for resolving Map properties A ResourceBundleELResolver for resolving ResourceBundle properties A ListELResolver for resolving List properties An ArrayELResolver for resolving array properties A BeanELResolver for resolving bean properties</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="getELResolver" return-type="jakarta.el.ELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:335</id>
+      <description>Returns the value of a static field. If the base object is an instance of ELClass and the property is String, the propertyResolved property of the ELContext object must be set to true by this resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. If the property is the string "class", return the java.lang.Class instance of the class specified in ELClass. If the property is a public static field of class specified in ELClass, return the value of the static field. An Enum constant is a public static field of an Enum object, and is a special case of this.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="getValue" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:338</id>
+      <description>Invokes a public static method or the constructor for a class. If the base object is an instance of ELClass and the method is a String, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value. Invoke the public static method specified by method. The process involved in the method selection is the same as that used in BeanELResolver. As a special case, if the name of the method is "&lt;init&gt;", the constructor for the class will be invoked.</description>
+      <package>jakarta.el</package>
+      <class-interface>StaticFieldELResolver</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class[]</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <!-- ********************************************************************************** -->
+    <!-- ********************************************************************************** -->
+    <!-- REMOVED ASSERTIONS LISTED BELOW -->
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:17</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver.BeanProperties</class-interface>
+      <method name="BeanELResolver.BeanProperties" return-type="BeanELResolver.BeanProperties">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:18</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver.BeanProperties</class-interface>
+      <method name="getBeanProperty" return-type="jakarta.el.BeanELResolver.BeanELResolver.BeanProperty">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:19</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver.BeanProperty</class-interface>
+      <method name="BeanELResolver.BeanProperty" return-type="BeanELResolver.BeanProperty">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+          <parameter>java.beans.PropertyDescriptor</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:20</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver.BeanProperty</class-interface>
+      <method name="getPropertyType" return-type="java.lang.Class" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:21</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver.BeanProperty</class-interface>
+      <method name="getReadMethod" return-type="java.lang.reflect.Method" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:22</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver.BeanProperty</class-interface>
+      <method name="getWriteMethod" return-type="java.lang.reflect.Method" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:23</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>BeanELResolver.BeanProperty</class-interface>
+      <method name="isReadOnly" return-type="boolean" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:119</id>
+      <description>Creates a new instance of a ExpressionFactory. This method uses the following ordered lookup procedure to determine the ExpressionFactory implementation class to load: Use the Services API (as detailed in the JAR specification). If a resource with the name of META-INF/services/jakarta.el.ExpressionFactory exists, then its first line, if present, is used as the UTF-8 encoded name of the implementation class. Use the properties file "lib/el.properties" in the JRE directory. If this file exists and it is readable by the java.util.Properties.load(InputStream) method, and it contains an entry whose key is "jakarta.el.ExpressionFactory", then the value of that entry is used as the name of the implementation class. Use the jakarta.el.ExpressionFactory system property. If a system property with this name is defined, then its value is used as the name of the implementation class. Use a platform default implementation.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="newInstance" return-type="ExpressionFactory" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:120</id>
+      <description>Create a new instance of a ExpressionFactory, with optional properties. This method uses the same lookup procedure as the one used in newInstance(). If the argument properties is not null, and if the implementation contains a constructor with a single parameter of type java.util.Properties, then the constructor is used to create the instance. Properties are optional and can be ignored by an implementation. The name of a property should start with "jakarta.el." The following are some suggested names for properties. jakarta.el.cacheSize</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="newInstance" return-type="ExpressionFactory">
+        <parameters>
+          <parameter>java.util.Properties</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:189</id>
+      <description>Constructor</description>
+      <package>jakarta.el</package>
+      <class-interface>ELClass</class-interface>
+      <method name="ELClass" return-type="ELClass">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:190</id>
+      <description>Returns the class name for the specified class.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELClass</class-interface>
+      <method name="getClassName" return-type="java.lang.String" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:191</id>
+      <description>Registers a listener to the ELContext.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="addListener" return-type="void">
+        <parameters>
+          <parameter>java.util.EventListener</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:197</id>
+      <description>Returns the list of registered listeners.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getListeners" return-type="java.util.List" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:201</id>
+      <description>Register a listener. Used only for EvaluationListeners in 3.0, but possibly to used for other listeners.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="addListener" return-type="void">
+        <parameters>
+          <parameter>java.util.EventListener</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:217</id>
+      <description>if the specified class does not exists.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELProcessor</class-interface>
+      <method name="defineFunction" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+        <throw>ClassNoFoundException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:246</id>
+      <description>Constructor</description>
+      <package>jakarta.el</package>
+      <class-interface>EvaluationEvent</class-interface>
+      <method name="EvaluationEvent" return-type="EvaluationEvent">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:247</id>
+      <description>Retruns the ELContext used in the evaluation of the expression.</description>
+      <package>jakarta.el</package>
+      <class-interface>EvaluationEvent</class-interface>
+      <method name="getELContext" return-type="jakarta.el.ELContext" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:248</id>
+      <description>Returns the original expression String</description>
+      <package>jakarta.el</package>
+      <class-interface>EvaluationEvent</class-interface>
+      <method name="getExpressionString" return-type="java.lang.String" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:249</id>
+      <description>Receives notification after an EL expression is evaluated</description>
+      <package>jakarta.el</package>
+      <class-interface>EvaluationListener</class-interface>
+      <method name="afterEvaluation" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.EvaluationEvent</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:250</id>
+      <description>Receives notification before an EL expression is evaluated</description>
+      <package>jakarta.el</package>
+      <class-interface>EvaluationListener</class-interface>
+      <method name="beforeEvaluation" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.EvaluationEvent</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:257</id>
+      <description>Retrieves an ELResolver that implements the Query Operators as described in Chapter 2 of the specification. This ELResolver relsoves the method invocation on the pair (base, property) when base is an Iterable and property is the name of the operator. Therefore, the operators behave like built-in methods of Iterables. See EL.2 for detailed descriptions of these operators, the arguments, and the return values.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="getQueryOperatorELResolver" return-type="jakarta.el.ELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:261</id>
+      <description>Return the key for the collection</description>
+      <package>jakarta.el</package>
+      <class-interface>Grouping</class-interface>
+      <method name="getKey" return-type="java.lang.Object" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="false">
+      <modified />
+      <id>EL:JAVADOC:267</id>
+      <description>Creates a InvalidOperationException with no detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>InvalidOperationException</class-interface>
+      <method name="InvalidOperationException" return-type="InvalidOperationException" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="false">
+      <modified />
+      <id>EL:JAVADOC:268</id>
+      <description>Creates a InvalidOperationException with the provided detail message.</description>
+      <package>jakarta.el</package>
+      <class-interface>InvalidOperationException</class-interface>
+      <method name="InvalidOperationException" return-type="InvalidOperationException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="false">
+      <modified />
+      <id>EL:JAVADOC:269</id>
+      <description>Creates a InvalidOperationException with the given root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>InvalidOperationException</class-interface>
+      <method name="InvalidOperationException" return-type="InvalidOperationException">
+        <parameters>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="false">
+      <modified />
+      <id>EL:JAVADOC:270</id>
+      <description>Creates a InvalidOperationException with the given detail message and root cause.</description>
+      <package>jakarta.el</package>
+      <class-interface>InvalidOperationException</class-interface>
+      <method name="InvalidOperationException" return-type="InvalidOperationException">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+          <parameter>java.lang.Throwable</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:271</id>
+      <description>Retrieves the formal parameters of the Lambda expression</description>
+      <package>jakarta.el</package>
+      <class-interface>LambdaExpression</class-interface>
+      <method name="getFormalParameters" return-type="java.util.List" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:324</id>
+      <description>Construct (if need) and return an ImportHandler</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="getImportHandler" return-type="jakarta.el.ImportHandler" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="removed" testable="true">
+      <modified />
+      <id>EL:JAVADOC:328</id>
+      <description>Construct a default ELContext for a stand-alone environment.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="StandardELContext" return-type="StandardELContext">
+        <parameters>
+          <parameter>jakarta.el.ELResolver</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <!-- ********************************************************************************** -->
+    <!-- ********************************************************************************** -->
+    <!-- NEW ASSERTIONS LISTED BELOW -->
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:385</id>
+      <description>Returns whether the given name is resolved by the BeanNameResolver</description>
+      <package>jakarta.el</package>
+      <class-interface>BeanNameResolver</class-interface>
+      <method name="isNameResolved" return-type="boolean">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:386</id>
+      <description>Converts an object to a specific type. An ELException is thrown if an error occurs during the conversion.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="convertToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:387</id>
+      <description>thrown if errors occur.</description>
+      <package>jakarta.el</package>
+      <class-interface>CompositeELResolver</class-interface>
+      <method name="convertToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:388</id>
+      <description>Constructor</description>
+      <package>jakarta.el</package>
+      <class-interface>ELClass</class-interface>
+      <method name="ELClass" return-type="ELClass">
+        <parameters>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:389</id>
+      <description>Returns the Class instance</description>
+      <package>jakarta.el</package>
+      <class-interface>ELClass</class-interface>
+      <method name="getKlass" return-type="java.lang.Class" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:390</id>
+      <description>Registers an evaluation listener to the ELContext.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="addEvaluationListener" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.EvaluationListener</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:391</id>
+      <description>Converts an object to a specific type. If a custom converter in the ELResolver handles this conversion, it is used. Otherwise the standard coercions is applied. An ELException is thrown if an error occurs during the conversion.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="convertToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:392</id>
+      <description>thrown if errors occur.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="convertToType" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Class</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:393</id>
+      <description>Returns the list of registered evaluation listeners.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="getEvaluationListeners" return-type="java.util.List" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:394</id>
+      <description>Inquires if the name is a LambdaArgument</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="isLambdaArgument" return-type="boolean">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:395</id>
+      <description>Notifies the listeners after an EL expression is evaluated</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="notifyAfterEvaluation" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:396</id>
+      <description>Notifies the listeners before an EL expression is evaluated</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="notifyBeforeEvaluation" return-type="void">
+        <parameters>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:397</id>
+      <description>Notifies the listeners when the (base, property) pair is resolved</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="notifyPropertyResolved" return-type="void">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:398</id>
+      <description>Called to indicate that a ELResolver has successfully resolved a given (base, property) pair and to notify the EvaluationListeners. The CompositeELResolver checks this property to determine whether it should consider or skip other component resolvers.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELContext</class-interface>
+      <method name="setPropertyResolved" return-type="void">
+        <parameters>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:399</id>
+      <description>Register an evaluation listener.</description>
+      <package>jakarta.el</package>
+      <class-interface>ELManager</class-interface>
+      <method name="addEvaluationListener" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.EvaluationListener</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:400</id>
+      <description>Receives notification after an EL expression is evaluated</description>
+      <package>jakarta.el</package>
+      <class-interface>EvaluationListener</class-interface>
+      <method name="afterEvaluation" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:401</id>
+      <description>Receives notification before an EL expression is evaluated</description>
+      <package>jakarta.el</package>
+      <class-interface>EvaluationListener</class-interface>
+      <method name="beforeEvaluation" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.String</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:402</id>
+      <description />
+      <package>jakarta.el</package>
+      <class-interface>EvaluationListener</class-interface>
+      <method name="EvaluationListener" return-type="EvaluationListener" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:403</id>
+      <description>Receives notification when the (base, property) pair is resolved</description>
+      <package>jakarta.el</package>
+      <class-interface>EvaluationListener</class-interface>
+      <method name="propertyResolved" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object</parameter>
+          <parameter>java.lang.Object</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:404</id>
+      <description>Retrieve a function map containing a pre-configured function mapping. It must include the following functions. linq:range linq:repeat linq:_empty</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="getInitFunctionMap" return-type="java.util.Map" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:405</id>
+      <description>Retrieves an ELResolver that implements the operations in collections. This ELResolver resolves the method invocation on the pair (base, property) when base is a Collection or a Map, and property is the name of the operation. See EL.2 for detailed descriptions of these operators, their arguments, and return values.</description>
+      <package>jakarta.el</package>
+      <class-interface>ExpressionFactory</class-interface>
+      <method name="getStreamELResolver" return-type="jakarta.el.ELResolver" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:406</id>
+      <description>is elContext is null</description>
+      <package>jakarta.el</package>
+      <class-interface>LambdaExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>java.lang.NullPointerException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:407</id>
+      <description>Invoke the encapsulated Lambda expression. The supplied arguments are matched, in the same order, to the formal parameters. If there are more arguments than the formal parameters, the extra arguments are ignored. If there are less arguments than the formal parameters, an ELException is thrown. The actual Lambda arguments are added to the ELContext and are available during the evaluation of the Lambda expression. They are removed after the evaluation. The ELContext set by LambdaExpression#setELContext is used in the evaluation of the lambda Expression.</description>
+      <package>jakarta.el</package>
+      <class-interface>LambdaExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:408</id>
+      <description>if not enough arguments are provided</description>
+      <package>jakarta.el</package>
+      <class-interface>LambdaExpression</class-interface>
+      <method name="invoke" return-type="java.lang.Object">
+        <parameters>
+          <parameter>java.lang.Object[]</parameter>
+        </parameters>
+        <throw>jakarta.el.ELException</throw>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:409</id>
+      <description>Set the ELContext to use in evaluating the LambdaExpression. The ELContext must to be set prior to the invocation of the LambdaExpression, unless it is supplied with LambdaExpression#invoke.</description>
+      <package>jakarta.el</package>
+      <class-interface>LambdaExpression</class-interface>
+      <method name="setELContext" return-type="void">
+        <parameters>
+          <parameter>jakarta.el.ELContext</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <modified />
+      <id>EL:JAVADOC:410</id>
+      <description>Construct a default ELContext for a stand-alone environment.</description>
+      <package>jakarta.el</package>
+      <class-interface>StandardELContext</class-interface>
+      <method name="StandardELContext" return-type="StandardELContext">
+        <parameters>
+          <parameter>jakarta.el.ExpressionFactory</parameter>
+        </parameters>
+      </method>
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:411</id>
+      <description>Returns the name of the method</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodInfo</class-interface>
+      <method name="getName" return-type="java.lang.String" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:412</id>
+      <description>Returns the return type of the method</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodInfo</class-interface>
+      <method name="getReturnType" return-type="java.lang.Class" />
+    </assertion>
+    <assertion required="true" impl-spec="false" status="active" testable="true">
+      <id>EL:JAVADOC:413</id>
+      <description>Returns the parameter types of the method</description>
+      <package>jakarta.el</package>
+      <class-interface>MethodInfo</class-interface>
+      <method name="getParamTypes" return-type="java.lang.Class[]" />
+    </assertion>
+  </assertions>
+</javadoc>
+
diff --git a/tck/docs/assertions/ELSpecAssertions.xml b/tck/docs/assertions/ELSpecAssertions.xml
new file mode 100644
index 0000000..bdc01b7
--- /dev/null
+++ b/tck/docs/assertions/ELSpecAssertions.xml
@@ -0,0 +1,2705 @@
+<?xml version = "1.0" encoding = "US-ASCII"?>
+<!DOCTYPE spec SYSTEM "https://raw.githubusercontent.com/eclipse-ee4j/jakartaee-tck/master/internal/docs/dtd/spec_assertions.dtd">
+<!--
+
+    Copyright (c) 2018, 2022 Oracle and/or its affiliates and others.
+    All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<?xml-stylesheet href = 'file:///files/workspaces/tools/docs/xsl/assertions/spec_assertions_comments.xsl' type = 'text/xsl'?>
+<spec>
+	<!-- @(#)ELSpecAssertions.xml 1.0 03/23/06 -->
+	<next-available-id>82</next-available-id>
+	<previous-id>48</previous-id>
+	<technology>EL</technology>
+	<id>EL</id>
+	<name>Expression Language</name>
+	<version>5.0</version>
+	<location-names>
+		<chapters>
+			<chapter id="1" name="Language Syntax and Semantics">
+				<sections>
+					<section id="1" name="Overview" />
+					<section id="1.1" name="EL in a nutshell" />
+					<section id="2" name="EL Expressions" />
+					<section id="2.1" name="Eval-expression" />
+					<section id="2.1.1" name="Eval-expressions as value expressions" />
+					<section id="2.1.2" name="Eval-expressions as method expressions" />
+					<section id="2.2" name="Literal-expression" />
+					<section id="2.3" name="Composite expressions" />
+					<section id="2.4" name="Syntax restrictions" />
+					<section id="3" name="Literals" />
+					<section id="4" name="Errors, Warnings, Default Values" />
+					<section id="5" name="Resolution of Model Objects and their Properties" />
+					<section id="6" name="Operators [] and ." />
+					<section id="7" name="Arithmetic Operators" />
+					<section id="7.1" name="Binary operators - A {+,-,*} B" />
+					<section id="7.2" name="Binary operator - A {/,div} B" />
+					<section id="7.3" name="Binary operator - A {%,mod} B" />
+					<section id="7.4" name="Unary minus operator - -A" />
+					<section id="8" name="String Concatenation Operator - A {+,cat} B" />
+					<section id="9" name="Relational Operators" />
+					<section id="9.1" name="A {&lt;,>,&lt;=,>=,lt,gt,le,ge} B" />
+					<section id="9.2" name="A {==,!=,eq,ne} B" />
+					<section id="10" name="Logical Operators" />
+					<section id="10.1" name="Binary operator - A {&amp;&amp;,||,and,or} B" />
+					<section id="11" name="Empty Operator - empty A" />
+					<section id="12" name="Conditional Operator - A ? B : C" />
+					<section id="13" name="Assignment Operator - A = B" />
+					<section id="14" name="Semicolon Operator - A ; B" />
+					<section id="15" name="Parentheses" />
+					<section id="16" name="Operator Precedence" />
+					<section id="17" name="Reserved Words" />
+					<section id="18" name="Functions" />
+					<section id="19" name="Variables" />
+					<section id="20" name="Lambda Expressions" />
+					<section id="21" name="Enums" />
+					<section id="22" name="Static Field and Method Reference" />
+					<section id="22.1" name="Access Restrictions and Imports" />
+					<section id="22.2" name="Imports of Classes and Packages" />
+					<section id="22.3" name="Special Fields and Methods" />
+					<section id="23" name="Type Conversion" />
+					<section id="23.1" name="To Coerce a Value X to Type Y" />
+					<section id="23.2" name="Coerce A to String" />
+					<section id="23.3" name="Coerce A to Number type N" />
+					<section id="23.4" name="Coerce A to Character" />
+					<section id="23.5" name="Coerce A to Boolean or boolean" />
+					<section id="23.6" name="Coerce A to an Enum Type T" />
+					<section id="23.7" name="Coerce A to an array of Type T" />
+					<section id="23.8" name="Coerce A to functional interface method invocation" />
+					<section id="23.9" name="Coerce A to Any Other Type T" />
+					<section id="24" name="Collected Syntax " />
+				</sections>
+			</chapter>
+			<chapter id="2" name="Operations on Collection Objects">
+				<sections>
+					<section id="2" name="Construction of Collection Objects" />
+					<section id="2.1" name="Set Construction" />
+					<section id="2.2" name="List Construction" />
+					<section id="2.3" name="Map Construction" />
+					<section id="3" name="Collection Operations" />
+					<section id="3.1" name="Stream and Pipeline" />
+					<section id="3.2" name="Operator Syntax Description" />
+					<section id="3.3" name="Implementation Classes" />
+					<section id="3.4" name="Functions" />
+					<section id="3.5" name="filter" />
+					<section id="3.6" name="map" />
+					<section id="3.7" name="flatMap" />
+					<section id="3.8" name="distinct" />
+					<section id="3.9" name="sorted" />
+					<section id="3.10" name="forEach" />
+					<section id="3.11" name="peek" />
+					<section id="3.12" name="iterator" />
+					<section id="3.13" name="limit" />
+					<section id="3.14" name="substream" />
+					<section id="3.15" name="toArray" />
+					<section id="3.16" name="toList" />
+					<section id="3.17" name="reduce" />
+					<section id="3.18" name="max" />
+					<section id="3.19" name="min" />
+					<section id="3.20" name="average" />
+					<section id="3.21" name="sum" />
+					<section id="3.22" name="count" />
+					<section id="3.23" name="anyMatch" />
+					<section id="3.24" name="allMatch" />
+					<section id="3.25" name="noneMatch" />
+					<section id="3.26" name="findFirst" />
+				</sections>
+			</chapter>
+		</chapters>
+	</location-names>
+	<assertions>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:45</id>
+			<description>Once parsed, an expression can optionally be evaluated
+				one or
+				more times. [ExprParsedEvalMany]</description>
+			<location chapter="1" section="2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:1</id>
+			<description>An eval-expression is formed by using the constructs
+				${expr} or
+				#{expr}. Both constructs are parsed and evaluated in
+				exactly the same way by
+				the EL, even though they might carry
+				different meanings in the technology
+				that is using the EL.
+				[PoundDollarSameMeaning]</description>
+			<location chapter="1" section="2.1" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:2</id>
+			<description>Nested eval-expressions, such as ${item[${i}]}, are
+				illegal.
+				[NestedEvalExprIllegal]</description>
+			<location chapter="1" section="2.1" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:3</id>
+			<description>When parsing a value expression, an expected type is
+				provided. In
+				the case of an rvalue, the expected type is what the
+				result of the expression
+				evaluation is coerced to. [RValueCoercion]</description>
+			<location chapter="1" section="2.1.1" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:4</id>
+			<description>When parsing lvalues, the expected type is ignored and
+				the
+				provided value is coerced to the actual type of the property the
+				expression
+				points to, before that property is set. [LValueCoercion]</description>
+			<location chapter="1" section="2.1.1" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:5</id>
+			<description>There is no coercion performed by method expressions.
+				[MethodExprSignature]</description>
+			<location chapter="1" section="2.1.2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:80</id>
+			<description>Identification of methods in method expressions from
+				parameter types follows the rules of the JLS with the addition
+				that coercion resolution is less specific than overload
+				resolution. [MethodExpressionMatch]</description>
+			<location chapter="1" section="2.1.2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:6</id>
+			<description>A literal-expression does not use the ${expr} or #{expr}
+				constructs, and simply evaluates to the text of the expression, of
+				type
+				String. Upon evaluation, an expected type of something other
+				than String can
+				be provided. [LiteralExprEval]</description>
+			<location chapter="1" section="2.2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:7</id>
+			<description>To generate literal values that include the character
+				sequence
+				"${" or ?#{?, the developer can choose to use a composite
+				expression as shown
+				in the example: [ELSyntaxAsLiteral]</description>
+			<location chapter="1" section="2.2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:8</id>
+			<description>The escape characters \$ and \# can be used to escape
+				what would
+				otherwise be treated as an eval-expression.
+				[ELSyntaxEscape]</description>
+			<location chapter="1" section="2.2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:9</id>
+			<description>A literal-expression can be used anywhere a value
+				expression can
+				be used. [LiteralExprAnywhereValueExprUsed]</description>
+			<location chapter="1" section="2.2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:10</id>
+			<description>A literal-expression can also be used as a method
+				expression that
+				returns a non-void return value. The standard EL
+				coercion rules then apply if
+				the return type of the method
+				expression is not java.lang.String.
+				[LiteralExprAsMethodExpr]</description>
+			<location chapter="1" section="2.2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:11</id>
+			<description>With composite expressions, eval-expressions are
+				evaluated from
+				left to right, coerced to Strings (according to the
+				EL type conversion
+				rules), and concatenated with any intervening
+				literal-expressions.
+				[CompositeExprEval]</description>
+			<location chapter="1" section="2.3" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:12</id>
+			<description>It is illegal to mix ${} and #{} constructs in a
+				composite
+				expression. [CannotMixTwoSyntax]</description>
+			<location chapter="1" section="2.3" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:13</id>
+			<description>There are literals for boolean, integer, floating point,
+				string,
+				and null in an eval-expression. [EvalExpressionLiterals]</description>
+			<location chapter="1" section="3" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:13.1</id>
+					<description>The boolean literal has values true and false</description>
+					<location chapter="1" section="3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:13.2</id>
+					<description>The integer literal is defined by the IntegerLiteral
+						construct.</description>
+					<location chapter="1" section="3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:13.3</id>
+					<description>The floating point literal is defined by the
+						FloatingPointLiteral construct</description>
+					<location chapter="3" section="1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:13.4</id>
+					<description>The string literal is defined with single and double
+						quotes</description>
+					<location chapter="3" section="1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:13.5</id>
+					<description>In a string literal, " is escaped as \", ' is escaped
+						as \',
+						and \ is escaped as \\. Quotes only need to be escaped in a
+						string value
+						enclosed in the same type of quote</description>
+					<location chapter="3" section="1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:13.6</id>
+					<description>The null literal has a null value.</description>
+					<location chapter="3" section="1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:14</id>
+			<description>The EL does not provide warnings, just default values
+				and errors.
+				Default values are type-correct values that are assigned
+				to a subexpression
+				when there is some problem. An error is an
+				exception thrown (to be handled by
+				the environment where the EL is
+				used). [DefaultValuesAndErrors]</description>
+			<location chapter="1" section="4" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:15</id>
+			<description>The dot and index operators have equivalent
+				functionality.
+				[DotAndIndexOperatorsSame]</description>
+			<location chapter="1" section="6" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:16</id>
+			<description>To evaluate expr-a[expr-b]:</description>
+			<location chapter="1" section="6" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:16.1</id>
+					<description>Evaluate expr-a into value-a</description>
+					<location chapter="1" section="6" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:16.2</id>
+					<description>If value-a is null:</description>
+					<location chapter="1" section="6" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:16.2.1</id>
+							<description>If expr-a[expr-b] is the last property being
+								resolved:</description>
+							<location chapter="1" section="6" />
+							<sub-assertions>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.2.1.1</id>
+									<description>If the expression is a value expression and
+										ValueExpression.getValue(context) was called to initiate this
+										expression evaluation, return null.</description>
+									<location chapter="1" section="6" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.2.1.2</id>
+									<description>Otherwise, throw PropertyNotFoundException</description>
+									<location chapter="1" section="6" />
+								</assertion>
+							</sub-assertions>
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:16.2.2</id>
+							<description>Otherwise, return null.</description>
+							<location chapter="1" section="6" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:16.3</id>
+					<description>Evaluate expr-b into value-b </description>
+					<location chapter="1" section="6" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:16.4</id>
+					<description>If value-b is null</description>
+					<location chapter="1" section="6" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:16.4.1</id>
+							<description>If expr-a[expr-b] is the last property being
+								resolved:</description>
+							<location chapter="1" section="6" />
+							<sub-assertions>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.4.1.1</id>
+									<description>If the expression is a value expression and
+										ValueExpression.getValue(context) was called to initiate this
+										expression evaluation, return null.</description>
+									<location chapter="1" section="6" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.4.1.2</id>
+									<description>Otherwise, throw PropertyNotFoundException</description>
+									<location chapter="1" section="6" />
+								</assertion>
+							</sub-assertions>
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:16.4.2</id>
+							<description>Otherwise, return null.</description>
+							<location chapter="1" section="6" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:16.5</id>
+					<description>If the expression is a value expression:</description>
+					<location chapter="1" section="6" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:16.5.1</id>
+							<description>If expr-a[expr-b] is the last property being
+								resolved:</description>
+							<location chapter="1" section="6" />
+							<sub-assertions>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.5.1.1</id>
+									<description>If ValueExpression.getValue(context) was called to
+										initiate this expression evaluation, invoke
+										elResolver.getValue(context, value-a, value-b)</description>
+									<location chapter="1" section="6" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.5.1.2</id>
+									<description>If ValueExpression.getType(context) was called,
+										invoke
+										elResolver.getType(context, value-a, value-b).</description>
+									<location chapter="1" section="6" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.5.1.3</id>
+									<description>If ValueExpression.isReadOnly(context) was called,
+										invoke
+										elResolver.isReadOnly(context, value-a, value-b).</description>
+									<location chapter="1" section="6" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.5.1.4</id>
+									<description>If ValueExpression.setValue(context, val) was
+										called,
+										invoke elResolver.setValue(context, value-a, value-b,
+										val).</description>
+									<location chapter="1" section="6" />
+								</assertion>
+							</sub-assertions>
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:16.5.2</id>
+							<description>Otherwise, invoke elResolver.getValue(value-a,
+								value-b)</description>
+							<location chapter="1" section="6" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:16.6</id>
+					<description>Otherwise, the expression is a method expression</description>
+					<location chapter="1" section="6" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:16.6.1</id>
+							<description>If expr-a[expr-b] is the last property being
+								resolved:</description>
+							<location chapter="1" section="6" />
+							<sub-assertions>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.6.1.1</id>
+									<description>Coerce value-b to String</description>
+									<location chapter="1" section="6" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.6.1.2</id>
+									<description>Find the method on object value-a with name
+										value-b and
+										with the set of expected parameter types provided
+										at parse time. If the
+										method does not exist, or the return
+										type does not match the expected
+										return type provided at parse
+										time, throw MethodNotFoundException.</description>
+									<location chapter="1" section="6" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.6.1.3</id>
+									<description>If MethodExpression.invoke(context, params) was
+										called,
+										invoke the found method with the parameters passed to
+										the invoke method</description>
+									<location chapter="1" section="6" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="false">
+									<id>EL:SPEC:16.6.1.4</id>
+									<description>If MethodExpression.getMethodInfo(context) was
+										called,
+										construct and return a new MethodInfo object.</description>
+									<location chapter="1" section="6" />
+								</assertion>
+							</sub-assertions>
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:16.6.2</id>
+							<description>Otherwise invoke elResolver.getValue(value-a,
+								value-b).</description>
+							<location chapter="1" section="6" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:17</id>
+			<description>Binary operators - A { +,-,* } B</description>
+			<location chapter="1" section="7.1" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:46</id>
+					<description>If the operator is a +, and either A or B is a
+						String,
+						then + is
+						a string concatenation operator.</description>
+					<location chapter="1" section="7.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:17.1</id>
+					<description>If A and B are null, return (Long) 0</description>
+					<location chapter="1" section="7.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:17.2</id>
+					<description>If A or B is a BigDecimal, coerce both to BigDecimal
+						and then:</description>
+					<location chapter="1" section="7.1" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:17.2.1</id>
+							<description>If operator is +, return A.add(B)</description>
+							<location chapter="1" section="7.1" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:17.2.2</id>
+							<description>If operator is -, return A.subtract(B)</description>
+							<location chapter="1" section="7.1" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:17.2.3</id>
+							<description>If operator is *, return A.multiply(B)</description>
+							<location chapter="1" section="7.1" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:17.3</id>
+					<description>If A or B is Float, Double, or a String containing
+						".", "e", or
+						"E":</description>
+					<location chapter="1" section="7.1" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:17.3.1</id>
+							<description>If A or B is BigInteger, coerce both A and B to
+								BigDecimal
+								and apply operator.</description>
+							<location chapter="1" section="7.1" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:17.3.2</id>
+							<description>Otherwise, coerce both A and B to Double and apply
+								operator</description>
+							<location chapter="1" section="7.1" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:17.4</id>
+					<description>If A or B is BigInteger, coerce both to BigInteger and
+						then:</description>
+					<location chapter="1" section="7.1" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:17.4.1</id>
+							<description>If operator is +, return A.add(B)</description>
+							<location chapter="1" section="7.1" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:17.4.2</id>
+							<description>If operator is -, return A.subtract(B)</description>
+							<location chapter="1" section="7.1" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:17.4.3</id>
+							<description>If operator is *, return A.multiply(B)</description>
+							<location chapter="1" section="7.1" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:17.5</id>
+					<description>Otherwise coerce both A and B to Long and apply
+						operator.</description>
+					<location chapter="1" section="7.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:17.6</id>
+					<description>If application of operator against A and B results in
+						an
+						exception, error.</description>
+					<location chapter="1" section="7.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:18</id>
+			<description>Binary operator - A { / or div } B</description>
+			<location chapter="1" section="7.2" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:18.1</id>
+					<description>If A and B are null, return (Long) 0</description>
+					<location chapter="1" section="7.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:18.2</id>
+					<description>If A or B is a BigDecimal or a BigInteger, coerce both
+						to
+						BigDecimal and return A.divide(B, BigDecimal.ROUND_HALF_UP)</description>
+					<location chapter="1" section="7.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:18.3</id>
+					<description>Otherwise, coerce both A and B to Double and apply
+						operator.</description>
+					<location chapter="1" section="7.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:23.4</id>
+					<description>If application of operator against A and B results in
+						an
+						exception, error.</description>
+					<location chapter="1" section="7.2" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:19</id>
+			<description>Binary Operator - A { % or mod } B</description>
+			<location chapter="1" section="7.3" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:19.1</id>
+					<description>If A and B are null, return (Long)0</description>
+					<location chapter="1" section="7.3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:19.2</id>
+					<description>If A or B is a BigDecimal, Float, Double, or String
+						containing
+						., e, or E, coerce both A and B to Double and apply
+						operator</description>
+					<location chapter="1" section="7.3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:19.3</id>
+					<description>If A or B is a BigInteger, coerce both to BigInteger
+						and return
+						A.remainder(B).</description>
+					<location chapter="1" section="7.3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:19.4</id>
+					<description>Otherwise coerce both A and B to Long and apply
+						operator.</description>
+					<location chapter="1" section="7.3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:19.5</id>
+					<description>If operator results in exception, error</description>
+					<location chapter="1" section="7.3" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:20</id>
+			<description>Unary minus operator - -A</description>
+			<location chapter="1" section="7.4" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:20.1</id>
+					<description>If A is null, return (Long) 0</description>
+					<location chapter="1" section="7.4" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:20.2</id>
+					<description>If A is a BigDecimal or BigInteger, return A.negate()</description>
+					<location chapter="1" section="7.4" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:20.3</id>
+					<description>If A is a String:</description>
+					<location chapter="1" section="7.4" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:20.3.1</id>
+							<description>If A contains ".", "e", or "E", coerce to a Double
+								and apply
+								operator.</description>
+							<location chapter="1" section="7.4" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:20.3.2</id>
+							<description>Otherwise, coerce to a Long and apply operator</description>
+							<location chapter="1" section="7.4" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:20.3.3</id>
+							<description>If operation results in exception, error.</description>
+							<location chapter="1" section="7.4" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:20.4</id>
+					<description>If A is Byte, Short, Integer, Long, Float, Double:</description>
+					<location chapter="1" section="7.4" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:20.4.1</id>
+							<description>retain the type and apply the operator.</description>
+							<location chapter="1" section="7.4" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:20.4.2</id>
+							<description>If application of operator results in exception,
+								error.</description>
+							<location chapter="1" section="7.4" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:20.5</id>
+					<description>Otherwise, error</description>
+					<location chapter="1" section="7.4" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:47</id>
+			<description>String Concatenation Operator - A {+, cat} B</description>
+			<location chapter="1" section="8" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:47.1</id>
+					<description>The + operator is a string concatenation
+						operator if
+						and only if
+						at least one of the operands
+						is a String.</description>
+					<location chapter="1" section="8.1" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:47.1.1</id>
+							<description>Coerce A and B to String.</description>
+							<location chapter="1" section="8.1" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:47.1.2</id>
+							<description>Return the concatenated string of A and B.</description>
+							<location chapter="1" section="8.1" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:21</id>
+			<description>Relational operators - A { &lt;,>,&lt;=,=>,lt,gt,le,ge }
+				B</description>
+			<location chapter="1" section="9.1" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:21.1</id>
+					<description>If A==B, and operator is &lt;=, le, >=, or ge, return
+						true</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:21.2</id>
+					<description>If A or B is null, return false.</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:21.3</id>
+					<description>If A or B is BigDecimal, coerce both A and B to
+						BigDecimal and
+						use the return value of A.compareTo(B).</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:21.4</id>
+					<description>If A or B is Float or Double coerce both A and B to
+						Double and
+						apply operator.</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:21.5</id>
+					<description>If A or B is BigInteger, coerce both A and B to
+						BigInteger and
+						use the return value of A.compareTo(B)</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:21.6</id>
+					<description>If A or B is Byte, Short, Character, Integer, or Long,
+						coerce
+						both A and B to Long and apply operator.</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:21.7</id>
+					<description>If A or B is String coerce both A and B to String,
+						compare
+						lexically.</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:21.8</id>
+					<description>If A is Comparable: </description>
+					<location chapter="1" section="9.1" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:21.8.1</id>
+							<description>If A.compareTo(B) throws an exception, error</description>
+							<location chapter="1" section="9.1" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:21.8.2</id>
+							<description>Otherwise return the result of A.compareTo(B)</description>
+							<location chapter="1" section="9.1" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:21.9</id>
+					<description>If B is Comparable, then:</description>
+					<location chapter="1" section="9.1" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:21.9.1</id>
+							<description>If B.compareTo(A) throws exception, error</description>
+							<location chapter="1" section="9.1" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:21.9.2</id>
+							<description>Otherwise use result of B.compareTo(A)</description>
+							<location chapter="1" section="9.1" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:21.10</id>
+					<description>Otherwise, error</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:22</id>
+			<description>Relational Operators - A { ==, !=, eq, ne } B</description>
+			<location chapter="1" section="9.2" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.1</id>
+					<description>If A == B, apply operator.</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.2</id>
+					<description>If A or B is null, return false for == or eq, true for
+						!= or ne</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:22.3</id>
+					<description>If A or B is BigDecimal, coerce both A and B to
+						BigDecimal and
+						then:</description>
+					<location chapter="1" section="9.2" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:22.3.1</id>
+							<description>If operator is == or eq, return A.equals(B)</description>
+							<location chapter="1" section="9.2" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:22.3.2</id>
+							<description>If operator is != or ne, return !A.equals(B)</description>
+							<location chapter="1" section="9.2" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.4</id>
+					<description>If A or B is Float or Double coerce both A and B to
+						Double and
+						apply operator.</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:22.5</id>
+					<description>If A or B is BigInteger, coerce both A and B to
+						BigInteger and
+						then:</description>
+					<location chapter="1" section="9.2" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:22.5.1</id>
+							<description>If operator is == or eq, return A.equals(B)</description>
+							<location chapter="1" section="9.2" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:22.5.2</id>
+							<description>If operator is != or ne, return !A.equals(B)</description>
+							<location chapter="1" section="9.2" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.6</id>
+					<description>If A or B is Byte, Short, Character, Integer, or Long,
+						coerce
+						both A and B to Long and apply operator.</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.7</id>
+					<description>If A or B is Boolean coerce both A and B to Boolean,
+						apply
+						operator.</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.8</id>
+					<description>If A or B is an enum, coerce both A and B to enum,
+						apply
+						operator</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.9</id>
+					<description>If A or B is String coerce both A and B to String and
+						compare
+						lexically</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.10</id>
+					<description>If error occurs calling A.equals(B), error</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:22.11</id>
+					<description>Otherwise apply operator to result of A.equals(B).</description>
+					<location chapter="1" section="9.2" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:23</id>
+			<description>Binary Operator - A { &amp;&amp;, ||, and, or } B</description>
+			<location chapter="1" section="9.1" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:23.1</id>
+					<description>Coerce both A and B to Boolean and apply operator.</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:23.2</id>
+					<description>The operator stops as soon as the expression can be
+						determined, i.e., A and B and C and D ? if B is false, then only A
+						and B is
+						evaluated.</description>
+					<location chapter="1" section="9.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:24</id>
+			<description>Logical Operators</description>
+			<location chapter="1" section="10" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:24.2</id>
+					<description>Binary operator - A {&amp;&amp;,||,and,or} B</description>
+					<location chapter="1" section="10.1" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:24.2.1</id>
+							<description>Coerce both A and B to Boolean, apply operator.</description>
+							<location chapter="1" section="10.2" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:24.1</id>
+					<description>Unary operator - { !, not } A</description>
+					<location chapter="1" section="10.2" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:24.1.1</id>
+							<description>Coerce A to Boolean and apply operator.</description>
+							<location chapter="1" section="10.2" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:25</id>
+			<description>Empty operator - empty A</description>
+			<location chapter="1" section="11" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:25.1</id>
+					<description>If A is null, return true</description>
+					<location chapter="1" section="11" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:25.2</id>
+					<description>If A is an emtpy String, return true.</description>
+					<location chapter="1" section="11" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:25.3</id>
+					<description>If A is an empty array, then return true.</description>
+					<location chapter="1" section="11" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:25.4</id>
+					<description>If A is an emtpy Map, then return true.</description>
+					<location chapter="1" section="11" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:25.5</id>
+					<description>If A is an empty Collection, then return true.</description>
+					<location chapter="1" section="11" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:25.6</id>
+					<description>Otherwise return false</description>
+					<location chapter="1" section="11" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:26</id>
+			<description>Conditional Operator - A ? B : C</description>
+			<location chapter="1" section="12" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:26.1</id>
+					<description>Evaluate B or C, depending on the result of the
+						evaluation of
+						A.
+						Coerce A to Boolean:
+					</description>
+					<location chapter="1" section="12" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:26.1.1</id>
+							<description>If A is true, evaluate and return B</description>
+							<location chapter="1" section="12" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:26.1.2</id>
+							<description>If A is false, evaluate and return C</description>
+							<location chapter="1" section="12" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:48</id>
+			<description>Assignment Operator - A = B</description>
+			<location chapter="1" section="13" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:48.1</id>
+					<description>Assign the value of B to A. A must be a lvalue,
+						otherwise, a
+						PropertyNotWritableException will be thrown.
+					</description>
+					<location chapter="1" section="13" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:48.1.1</id>
+							<description>Evluate expr-a, up to the last property reolution,
+								to
+								(base-a, prop-a)</description>
+							<location chapter="1" section="13" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:48.1.2</id>
+							<description>Evaluate expr-b, to value-b</description>
+							<location chapter="1" section="13" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:48.1.3</id>
+							<description>Invoke ELResolver.setValue(base-a, prop-a, value-b)</description>
+							<location chapter="1" section="13" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:48.1.4</id>
+							<description>Return value-b</description>
+							<location chapter="1" section="13" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:49</id>
+			<description>Semicolon Operator - A ; B</description>
+			<location chapter="1" section="14" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:49.1</id>
+					<description>To evaluate A;B, A is first evaluated, and its value
+						is
+						discarded. B is then evaluated and its value is returned.</description>
+					<location chapter="1" section="14" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:27</id>
+			<description>Parentheses can be used to change precedence</description>
+			<location chapter="1" section="15" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:28</id>
+			<description>Operator precedence (highest to lowest) - [] . then (),
+				then
+				-(unary) not ! empty, then * / div % mod, then + - (binary),
+				then &lt; >
+				&lt;= >= lt gt le ge, then == != eq ne, then &amp;&amp;
+				and, then || or, then
+				? : then -> then = then ;</description>
+			<location chapter="1" section="16" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:29</id>
+			<description>Qualified functions with a namespace prefix have
+				precedence over
+				the operators. [FunctionPrecedenceOverOperators]</description>
+			<location chapter="1" section="16" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:30</id>
+			<description>The following words are reserved for the language and
+				must not be
+				used as identifiers.
+				and eq gt true instanceof
+				or ne le
+				false empty
+				not lt ge
+				null div mod
+			</description>
+			<location chapter="1" section="17" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:31</id>
+			<description>EL functions are mapped, resolved and bound at parse
+				time.
+				[ELFunctionsBinding]</description>
+			<location chapter="1" section="18" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:32</id>
+			<description>It is the responsibility of the FunctionMapper class to
+				provide
+				the mapping of namespace-qualified functions to static
+				methods of specific
+				classes when expressions are created.
+				[FunctionMapperMapping]</description>
+			<location chapter="1" section="18" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:33</id>
+			<description>If no FunctionMapper is provided (by passing in null),
+				functions
+				are disabled. [FunctionMapperNull]</description>
+			<location chapter="1" section="" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:34</id>
+			<description>EL variables are mapped, resolved and bound at parse
+				time.
+				[ELVariablesBinding]</description>
+			<location chapter="1" section="19" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:35</id>
+			<description>It is the responsibility of the VariableMapper class to
+				provide
+				the mapping of EL variables to ValueExpressions when
+				expressions are created.
+				[VariableMapperMapping]</description>
+			<location chapter="1" section="19" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:36</id>
+			<description>If no VariableMapper is provided to a ValueExpression,
+				variable
+				mapping is disabled. [VariableMapperNull]</description>
+			<location chapter="1" section="19" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:50</id>
+			<description>Lambda Expressions</description>
+			<location chapter="1" section="20" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:50.1</id>
+					<description>x->x+1</description>
+					<location chapter="1" section="20" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:50.2</id>
+					<description>(x,y)->x+y</description>
+					<location chapter="1" section="20" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:50.3</id>
+					<description>((x,y)->x+y)(3,4) evaluates to 7.</description>
+					<location chapter="1" section="20" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:50.4</id>
+					<description>v = (x,y)->x+y</description>
+					<location chapter="1" section="20" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:50.5</id>
+					<description>v(3,4) evaluates to 7</description>
+					<location chapter="1" section="20" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:50.6</id>
+					<description>fact = n -> n==0? 1: n*fact(n-1); fact(5) evaluates to
+						120</description>
+					<location chapter="1" section="20" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:50.7</id>
+					<description>It can also be passed as an argument to a method, and
+						be
+						invoked in the method, by invoking
+						jakarta.el.LambdaExpression.invoke(), such
+						as
+						employees.where(e->e.firstName == 'Larry')</description>
+					<location chapter="1" section="20" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:50.8</id>
+					<description>A Lambda expression can be nested within another
+						Lambda
+						expression, like
+						customers.select(c->[c.name,
+						c.orders.sum(o->o.total)])</description>
+					<location chapter="1" section="20" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:37</id>
+			<description>To coerce a value X to type Y</description>
+			<location chapter="1" section="23.1" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:37.1</id>
+					<description>If X is of a primitive type, Let X' be the equivalent
+						'boxed
+						form' of X, otherwise, Let X' be the same as X.</description>
+					<location chapter="1" section="23.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:37.2</id>
+					<description>If Y is of a primitive type, Let Y' be the equivalent
+						'boxed
+						form' of Y. Otherwise, let Y' be the same as Y.</description>
+					<location chapter="1" section="23.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:37.3</id>
+					<description>Apply the rules in Sections 1.18.2-1.18.7 for coercing
+						X' to Y'</description>
+					<location chapter="1" section="23.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:37.4</id>
+					<description>If Y is a primitive type, then the result is found by
+						'unboxing' the result of the coercion. If the result of the
+						coercion is
+						null, then error.</description>
+					<location chapter="1" section="23.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:37.5</id>
+					<description>If Y is not a primitive type, then the result is the
+						result of
+						the coercion.</description>
+					<location chapter="1" section="23.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:38</id>
+			<description>Coerce A to String</description>
+			<location chapter="1" section="23.2" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:38.1</id>
+					<description>If A is a String: return A</description>
+					<location chapter="1" section="23.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:38.2</id>
+					<description>If A is null, return an empty String ("").</description>
+					<location chapter="1" section="23.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:38.3</id>
+					<description>If A is Enum, return A.name()</description>
+					<location chapter="1" section="23.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:38.4</id>
+					<description>If A.toString() throws exception, error.</description>
+					<location chapter="1" section="23.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:38.5</id>
+					<description>Otherwise return A.toString()</description>
+					<location chapter="1" section="23.2" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:39</id>
+			<description>Coerce A to Number type N</description>
+			<location chapter="1" section="23.3" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:39.1</id>
+					<description>If A is null or "", return 0</description>
+					<location chapter="1" section="23.3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:39.2</id>
+					<description>If A is Character, convert to short, apply numeric
+						rules below.</description>
+					<location chapter="1" section="23.3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:39.3</id>
+					<description>If A is a Boolean, then error.</description>
+					<location chapter="1" section="23.3" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:39.4</id>
+					<description>If A is Number type N, return A</description>
+					<location chapter="1" section="23.3" />
+				</assertion>
+				<assertion required="true" impl-spec="true" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:39.5</id>
+					<description>If A is a Number, coerce quietly to type N using the
+						following
+						algorithm:</description>
+					<location chapter="1" section="23.3" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:39.5.1</id>
+							<description>If N is BigInteger:</description>
+							<location chapter="1" section="23.3" />
+							<sub-assertions>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="true">
+									<id>EL:SPEC:39.5.1.1</id>
+									<description>If A is a BigDecimal, return A.toBigInteger()</description>
+									<location chapter="1" section="23.3" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="true">
+									<id>EL:SPEC:39.5.1.2</id>
+									<description>Otherwise, return
+										BigInteger.valueOf(A.longValue())</description>
+									<location chapter="1" section="23.3" />
+								</assertion>
+							</sub-assertions>
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:39.5.2</id>
+							<description>If N is BigDecimal</description>
+							<location chapter="1" section="23.3" />
+							<sub-assertions>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="true">
+									<id>EL:SPEC:39.5.2.1</id>
+									<description>If A is a BigInteger, return new BigDecimal(A)</description>
+									<location chapter="1" section="23.3" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="true">
+									<id>EL:SPEC:39.5.2.2</id>
+									<description>Otherwise, return new BigDecimal(A.doubleValue())</description>
+									<location chapter="1" section="23.3" />
+								</assertion>
+							</sub-assertions>
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.5.3</id>
+							<description>If N is Byte, return new Byte(A.byteValue())</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.5.4</id>
+							<description>If N is Short, return new Short(A.shortValue())</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.5.5</id>
+							<description>If N is Integer, return new Integer(A.intValue())</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.5.6</id>
+							<description>If N is Long, return new Long(A.longValue())</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.5.7</id>
+							<description>If N is Float, return new Float(A.floatValue())</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.5.8</id>
+							<description>If N is Double, return new Double(A.doubleValue())</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.5.9</id>
+							<description>Otherwise, error.</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:39.6</id>
+					<description>If A is String, then:</description>
+					<location chapter="1" section="23.3" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="false">
+							<id>EL:SPEC:39.6.1</id>
+							<description>If N is BigDecimal then:</description>
+							<location chapter="1" section="23.3" />
+							<sub-assertions>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="true">
+									<id>EL:SPEC:39.6.1.1</id>
+									<description>If new BigDecimal(A) throws an exception then
+										error.</description>
+									<location chapter="1" section="23.3" />
+								</assertion>
+								<assertion required="true" impl-spec="false" defined-by="technology"
+									status="active" testable="true">
+									<id>EL:SPEC:39.6.1.2</id>
+									<description>Otherwise, return new BigDecimal(A).</description>
+									<location chapter="1" section="23.3" />
+								</assertion>
+							</sub-assertions>
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="false">
+					<id>EL:SPEC:39.7</id>
+					<description>If N is BigInteger then</description>
+					<location chapter="1" section="23.3" />
+					<sub-assertions>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.7.1</id>
+							<description>If new BigInteger(A) throws an exception then error.</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.7.2</id>
+							<description>Otherwise, return new BigInteger(A).</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.7.3</id>
+							<description>If N.valueOf(A) throws an exception, then error.</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+						<assertion required="true" impl-spec="false" defined-by="technology"
+							status="active" testable="true">
+							<id>EL:SPEC:39.7.4</id>
+							<description>Otherwise, return N.valueOf(A).</description>
+							<location chapter="1" section="23.3" />
+						</assertion>
+					</sub-assertions>
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:39.8</id>
+					<description>Otherwise error.</description>
+					<location chapter="1" section="23.3" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:40</id>
+			<description>Coerce A to Character</description>
+			<location chapter="1" section="23.4" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:40.1</id>
+					<description>If A is null or "". return (char) 0</description>
+					<location chapter="1" section="23.4" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:40.2</id>
+					<description>If A is Character, then return A</description>
+					<location chapter="1" section="23.4" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:40.3</id>
+					<description>If A is Boolean, error.</description>
+					<location chapter="1" section="23.4" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:40.4</id>
+					<description>If A is Number, coerce quietly to type Short, then
+						return a
+						Character whose numeric value is equivalent to that
+						Short.</description>
+					<location chapter="1" section="23.4" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:40.5</id>
+					<description>If A is String, return A.charAt(0)</description>
+					<location chapter="1" section="23.4" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:40.6</id>
+					<description>All other types will result in an error.</description>
+					<location chapter="1" section="23.4" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:41</id>
+			<description>Coerce A to Boolean</description>
+			<location chapter="1" section="23.5" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:41.1</id>
+					<description>If A is null or "", return false</description>
+					<location chapter="1" section="23.5" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:41.2</id>
+					<description>Otherwise if A is Boolean, return A</description>
+					<location chapter="1" section="23.5" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:41.3</id>
+					<description>Otherwise if A is String, and Boolean.valueOf(A) does
+						not throw
+						an exception, return it.</description>
+					<location chapter="1" section="23.5" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:41.4</id>
+					<description>Otherwise error.</description>
+					<location chapter="1" section="23.5" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:42</id>
+			<description>Coerce A to an Enum Type T</description>
+			<location chapter="1" section="23.6" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:42.1</id>
+					<description>If A is null, return null</description>
+					<location chapter="1" section="23.6" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:42.2</id>
+					<description>If A is assignable to T, coerce quietly</description>
+					<location chapter="1" section="23.6" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:42.3</id>
+					<description>If A is "", return null.</description>
+					<location chapter="1" section="23.6" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:42.4</id>
+					<description>If A is a String call Enum.valueOf(T.getClass(), A)
+						and return
+						the result.</description>
+					<location chapter="1" section="23.6" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:81</id>
+			<description>Coerce A to array of type T</description>
+			<location chapter="1" section="23.7" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:81.1</id>
+					<description>If A is null, return null</description>
+					<location chapter="1" section="23.7" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:81.2</id>
+					<description>If A is assignable to an array of type T, coerce
+						quietly</description>
+					<location chapter="1" section="23.7" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:81.3</id>
+					<description>If A is an array, return a copy of the array where
+						each element has been coerced to type T using these
+						rules</description>
+					<location chapter="1" section="23.7" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:81.4</id>
+					<description>If A is an array but at least one element of the
+						array cannot be coerced to type T, error</description>
+					<location chapter="1" section="23.7" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:81.5</id>
+					<description>If A is not an array, error</description>
+					<location chapter="1" section="23.7" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:79</id>
+			<description>Coerce A to functional interface method invocation</description>
+			<location chapter="1" section="23.8" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:79.1</id>
+					<description>If A is LamdaEXpression and parameters are an exact match, coerce to functional interface invocation.</description>
+					<location chapter="1" section="23.8" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:79.2</id>
+					<description>If A is not LamdaEXpression, follow 1.23.9 and throw an exception.</description>
+					<location chapter="1" section="23.8" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:79.3</id>
+					<description>If A is LamdaEXpression and parameters match if coerced, coerce to functional interface invocation.</description>
+					<location chapter="1" section="23.8" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:43</id>
+			<description>Coerce A to any other type T</description>
+			<location chapter="1" section="23.9" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:43.1</id>
+					<description>If A is null, return null.</description>
+					<location chapter="1" section="23.9" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:43.2</id>
+					<description>If A is assignable to T, coerce quietly.</description>
+					<location chapter="1" section="23.9" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:43.3</id>
+					<description>If A is String, and T has no Property Editor, then if
+						A is ""
+						return null, otherwise error.</description>
+					<location chapter="1" section="23.9" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:43.4</id>
+					<description>If A is String, and T's PropertyEditor throws
+						exception, then
+						if A is "" return null, otherwise error.</description>
+					<location chapter="1" section="23.9" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:43.5</id>
+					<description>Otherwise, apply T's PropertyEditor</description>
+					<location chapter="1" section="23.9" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:43.6</id>
+					<description>Otherwise, error</description>
+					<location chapter="1" section="23.9" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+
+		<!-- Start Chapter 2, Operations on Collection Objects -->
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:44</id>
+			<description>All Expressions must be Serializable</description>
+			<location chapter="2" section="1" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:51</id>
+			<description>
+				Construct an instance of java.lang.util.Set&lt;Object&gt;.
+			</description>
+			<location chapter="2" section="2.2.1" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:51.1</id>
+					<description>SetData := '{' DataList '}'</description>
+					<location chapter="2" section="2.2.1.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:51.2</id>
+					<description>DataList := (expression (',' expression)* )?</description>
+					<location chapter="2" section="2.2.1.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:52</id>
+			<description>
+				Construct an instance of java.lang.util.List&lt;Object&gt;.
+			</description>
+			<location chapter="2" section="2.2.2" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:52.1</id>
+					<description>ListData := '{' DataList '}'</description>
+					<location chapter="2" section="2.2.2.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:52.2</id>
+					<description>DataList := (expression (',' expression)* )?</description>
+					<location chapter="2" section="2.2.2.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:53</id>
+			<description>
+				Construct an instance of java.lang.util.Map&lt;Object&gt;.
+			</description>
+			<location chapter="2" section="2.2.3" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:53.1</id>
+					<description>Map := '{' MapEntries '}'</description>
+					<location chapter="2" section="2.2.3.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:53.2</id>
+					<description>MapEntries := (MapEntry (',' MapEntry)* )?</description>
+					<location chapter="2" section="2.2.3.1" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:53.3</id>
+					<description>MapEntry := expression ':' expression</description>
+					<location chapter="2" section="2.2.3.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:54</id>
+			<description>Some methods have optional parameters. The
+				declarations
+				of the
+				methods with all possible combinations of the
+				parameters are
+				listed in the
+				syntax sections, as if they are
+				overloaded. A null
+				parameter is not allowed,
+				and will result in
+				NullPointerException.</description>
+			<location chapter="2" section="2.3.2" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="true">
+			<id>EL:SPEC:55</id>
+			<description>
+				An instant of Stream is obtained by calling the method
+				stream()
+				of a collection. The methods in this class support the
+				stream
+				operations and
+				are described in Section 2.3.5 to Section
+				2.3.24.
+			</description>
+			<location chapter="2" section="2.3.3.1" />
+		</assertion>
+		<assertion required="true" impl-spec="false" defined-by="technology"
+			status="active" testable="false">
+			<id>EL:SPEC:56</id>
+			<description>
+				The following are methods in an Optional&lt;T&gt; </description>
+			<location chapter="2" section="2.3.3.2" />
+			<sub-assertions>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:56.1</id>
+					<description>
+						T get() Returns the value held by the Optional, or
+						throws an
+						ELException if the Optional is empty.
+					</description>
+					<location chapter="2" section="2.3.3.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:56.2</id>
+					<description>
+						T orElse(T other) Returns the value held by the
+						Optional, or
+						the value other if the Optional is empty.
+					</description>
+					<location chapter="2" section="2.3.3.2" />
+				</assertion>
+				<assertion required="true" impl-spec="false" defined-by="technology"
+					status="active" testable="true">
+					<id>EL:SPEC:56.3</id>
+					<description>
+						T orElseGet((()->T) other) Returns the value held by the
+						Optional, or the value returned by the lambda expression
+						other if
+						the
+						Optional is empty.
+					</description>
+					<location chapter="2" section="2.3.3.2" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="true"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:57</id>
+			<description>Some operations takes functions (lambda expressions) as
+				parameters. Again, we used the notion (arg1Type,
+				...)-&gt;returnType
+				to
+				describe the argument types and the
+				return type of a function.</description>
+			<location chapter="2" section="2.3.4" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:57.1</id>
+					<description>predicate S -&gt; boolean
+						This function takes the input
+						argument, usually the element of the
+						source stream, and determines
+						if it
+						satisfies some criteria</description>
+					<location chapter="2" section="2.3.4.1" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:57.2</id>
+					<description>booleanSupplier () -&gt; boolean
+						This function takes
+						noarguments, and returns a boolean
+						value.</description>
+					<location chapter="2" section="2.3.4.2" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:57.3</id>
+					<description>mapper S -> R
+						This function maps, or transforms the
+						input
+						argument, usually the
+						element of the source stream, to the
+						result.</description>
+					<location chapter="2" section="2.3.4.3" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:57.4</id>
+					<description>
+						comparator
+						(S, S) -&gt; int
+						This function compares two
+						arguments, usually the elements of the
+						source stream, and returns a
+						negative integer, zero, or a positive
+						integer, if the first
+						argument is
+						respectively less than, equal
+						to, or greater than the
+						second argument.
+					</description>
+					<location chapter="2" section="2.3.4.4" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:57.5</id>
+					<description>
+						consumer S -&gt; void
+						This function processes the input
+						argument, usually the element of the
+						source stream, and returns
+						nothing.
+					</description>
+					<location chapter="2" section="2.3.4.5" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:57.6</id>
+					<description>
+						binaryOperator (S, S) -&gt; S
+						This function applies a
+						binary
+						operation to the input
+						arguments, and returns the result.
+						The first argument
+						is usually an internal
+						accumulator, and the
+						second argument is usually the
+						element of the source stream. The
+						arguments and the result are of the same
+						type.
+					</description>
+					<location chapter="2" section="2.3.4.6" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="true"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:58</id>
+			<description>
+				The filter method
+				produces a stream containing the source
+				stream
+				elements for which
+				the predicate function return true. The
+				argument
+				of
+				predicate
+				function represents the element to test.
+			</description>
+			<location chapter="2" section="2.3.5" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:58.1</id>
+					<description>
+						Stream&lt;S&gt; </description>
+					<location chapter="2" section="2.3.5.1" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:58.2</id>
+					<description>
+						Stream&lt;S&gt;.filter((S-&gt;boolean) predicate)
+					</description>
+					<location chapter="2" section="2.3.5.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="true"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:59</id>
+			<description>
+				The map method produces a stream by applying the mapper
+				function
+				on the elements of the source stream. The argument of
+				mapper function
+				represents the element to process.
+			</description>
+			<location chapter="2" section="2.3.6" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:59.1</id>
+					<description>
+						Stream&lt;R&gt; Stream&lt;S&gt;.map((S-&gt;R)mapper)
+					</description>
+					<location chapter="2" section="2.3.6.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="true"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:60</id>
+			<description>
+				The flatMap method produces a stream by mapping each of the
+				source elements to another stream and then concatenating the mapped streams.
+				If the mapper function does not return a Stream, the behavior is undefined.
+				source elements to zero or more elements.
+			</description>
+			<location chapter="2" section="2.3.7" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:60.1</id>
+					<description>
+						Stream&lt;R&gt;
+						Stream&lt;S&gt;.flatMap((S-&gt;Stream&lt;R&gt;) mapper)
+					</description>
+					<location chapter="2" section="2.3.7.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="true"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:61</id>
+			<description>
+				The distinct method produces a stream containing the
+				elements of
+				the source stream that are distinct, according to
+				Object.equals.
+			</description>
+			<location chapter="2" section="2.3.8" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:61.1</id>
+					<description>
+						Stream&lt;S&gt; Stream&lt;S&gt;.distinct()
+					</description>
+					<location chapter="2" section="2.3.8.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="true"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:62</id>
+			<description>
+				The sorted method produces a stream containing the
+				elements of
+				the source
+				stream in sorted order. If no comparator is
+				specified, the elements
+				are sorted in natural order, and a
+				ELException is thrown if the
+				elements do
+				not implement
+				java.lang.Comparable. If a comparator is
+				specified, the elements
+				are
+				sorted with the provided comparator.
+			</description>
+			<location chapter="2" section="2.3.9" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:62.1</id>
+					<description>
+						Stream&lt;S&gt; Stream&lt;S&gt;.sorted()
+					</description>
+					<location chapter="2" section="2.3.9.1" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:62.2</id>
+					<description>
+						Stream&lt;S&gt; Stream&lt;S&gt;.sorted((p,q)-&gt;int)
+						comparator)
+					</description>
+					<location chapter="2" section="2.3.9.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:63</id>
+			<description>
+				The forEach method invokes the consumer function for each
+				element in the source
+				stream. This method always returns null.
+			</description>
+			<location chapter="2" section="2.3.10" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:63.1</id>
+					<description>
+						Object stream&lt;S&gt;.forEach(((S)-&gt;void)consumer)
+					</description>
+					<location chapter="2" section="2.3.10.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:64</id>
+			<description>
+				The peek method produces a stream containing the elements of the
+				source stream, and
+				invokes the consumer function for each element in the
+				stream.
+			</description>
+			<location chapter="2" section="2.3.11" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:64.1</id>
+					<description>
+						Stream&lt;S&gt; Stream&lt;S&gt;.peek(((S)-&gt;void)consumer)
+					</description>
+					<location chapter="2" section="2.3.11.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:65</id>
+			<description>
+				The iterator method returns an iterator for the source stream, 
+				suitable for use in Java codes.
+			</description>
+			<location chapter="2" section="2.3.11" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:65.1</id>
+					<description>
+						Iterator&lt;S&gt; Stream&lt;S&gt;.iterator()
+					</description>
+					<location chapter="2" section="2.3.11.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:66</id>
+			<description>
+				The limit method produces a stream containing the first count
+				number of elements of the source stream.
+			</description>
+			<location chapter="2" section="2.3.13" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:66.1</id>
+					<description>
+						Stream&lt;S&gt; Stream&lt;S&gt;.limit(long count)
+					</description>
+					<location chapter="2" section="2.3.13.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:67</id>
+			<description>
+				The substream method produces a stream containing the source
+				elements, skipping the first start elements, and including the rest of the
+				elements in the stream if end is not specified, or the next (end - start)
+				elements in the stream if end is specified.
+			</description>
+			<location chapter="2" section="2.3.14" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:67.1</id>
+					<description>
+						Stream&lt;S&gt; Stream&lt;S&gt;.substream(long start)
+					</description>
+					<location chapter="2" section="2.3.14.1" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:67.2</id>
+					<description>
+						Stream&lt;S&gt; Stream&lt;S&gt;.substream(long start,
+						long end)
+					</description>
+					<location chapter="2" section="2.3.14.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:68</id>
+			<description>
+				the toArray method returns an array containing the elements of
+				the source stream.
+			</description>
+			<location chapter="2" section="2.3.15" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:68.1</id>
+					<description>
+						S[] Stream&lt;S&gt;.toArray()
+					</description>
+					<location chapter="2" section="2.3.15.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:69</id>
+			<description>
+				The toList 
+			</description>
+			<location chapter="2" section="2.3.16" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:69.1</id>
+					<description>
+						S[] Stream&lt;S&gt;.toList()
+					</description>
+					<location chapter="2" section="2.3.16.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:70</id>
+			<description>
+				The reduce method with a seed value starts by assigning the seed
+				value to an internal accumulator. Then for each of the elements in the
+				source stream, the next accumulator value is computed, by invoking the
+				binaryOperator function, with the current accumulator value as the first
+				argument and the current element as the second argument. The final
+				accumulator value is returned
+			</description>
+			<location chapter="2" section="2.3.17" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:70.1</id>
+					<description>
+						Optional&lt;S&gt; Stream&lt;S&gt;.reduce(((S,S)-&gt;S)
+						binaryOperator)
+					</description>
+					<location chapter="2" section="2.3.17.1" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:70.2</id>
+					<description>
+						S Stream&lt;S&gt;.reduce(S seed, ((S,S)-&gt;S)
+						binaryOperator))
+					</description>
+					<location chapter="2" section="2.3.17.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:71</id>
+			<description>
+				The max method computes the maximum of the elelments in the
+				source stream. If the comparator function is specified, it is used for
+				comparisons. If no comparator function is specified, the elements themselves
+				are compared, and must implement Comparable, otherwise an ELException is
+				thrown.
+			</description>
+			<location chapter="2" section="2.3.18" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:71.1</id>
+					<description>
+						Optional Stream&lt;S&gt;.max()
+					</description>
+					<location chapter="2" section="2.3.18.1" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:71.2</id>
+					<description>
+						Optional Stream&lt;S&gt;.max(((p,q)-&gt;int) comparator)
+					</description>
+					<location chapter="2" section="2.3.18.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:72</id>
+			<description>
+				The min method computes the minimum of the elelments in the
+				source stream. If the comparator function is specified, it is used for
+				comparisons. If no comparator function is specified, the elements themselves
+				are compared, and must implement Comparable, otherwise an ELException is
+				thrown.
+			</description>
+			<location chapter="2" section="2.3.19" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:72.1</id>
+					<description>
+						Optional Stream&lt;S&gt;.min()
+					</description>
+					<location chapter="2" section="2.3.19.1" />
+				</assertion>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:72.2</id>
+					<description>
+						Optional Stream&lt;S&gt;.min(((p,q)-&gt;int) comparator)
+					</description>
+					<location chapter="2" section="2.3.19.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:73</id>
+			<description>
+				The average method computes the average of all elements in the
+				source stream by first computes the sum of the elements and then divides the
+				sum by the number of elements. The elements are coerced to Number types
+				according to Section 1.23.3 during the computation.
+				This method returns zero
+				for an empty stream.
+			</description>
+			<location chapter="2" section="2.3.20" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:73.1</id>
+					<description>
+						Optional Stream&lt;S&gt;.average()
+					</description>
+					<location chapter="2" section="2.3.20.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:74</id>
+			<description>
+				The sum method computes the sum of all elements in the source
+				stream. The elements are coerced to Number types according to Section 1.23.3
+				during the computation.
+				This method returns zero for an empty stream.
+			</description>
+			<location chapter="2" section="2.3.21" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:74.1</id>
+					<description>
+						Number Stream&lt;S&gt;.sum()
+					</description>
+					<location chapter="2" section="2.3.21.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:79</id>
+			<description>
+				This method returns the count of elements in the source stream.
+			</description>
+			<location chapter="2" section="2.3.22" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:79.1</id>
+					<description>
+						Long Stream&lt;S&gt;.count()
+					</description>
+					<location chapter="2" section="2.3.22.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:75</id>
+			<description>
+				The anyMatch method returns an Optional of true if any element
+				in the source stream satisfies the test given by the predicate. It returns
+				an empty Optional if the stream is empty.
+			</description>
+			<location chapter="2" section="2.3.23" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:75.1</id>
+					<description>
+						Optional&lt;boolean&gt;
+						Stream&lt;S&gt;.anyMatch((S-&gt;boolean) predicate)
+					</description>
+					<location chapter="2" section="2.3.23.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:76</id>
+			<description>
+				The allMatch method returns an Optional of true if all elements
+				in the source stream satisfy the test given by the predicate. It returns an
+				empty Optional if the stream is empty.
+			</description>
+			<location chapter="2" section="2.3.24" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:76.1</id>
+					<description>
+						Optional&lt;boolean&gt;
+						Stream&lt;S&gt;.allMatch((S-&gt;boolean) predicate)
+					</description>
+					<location chapter="2" section="2.3.24.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:77</id>
+			<description>
+				The nonematch method returns an Optional of true if none of the
+				elements in the source stream satisfies the test given by the predicate. It
+				returns an empty Optional if the stream is empty.
+			</description>
+			<location chapter="2" section="2.3.25" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:77.1</id>
+					<description>
+						Optional&lt;boolean&gt;
+						Stream&lt;S&gt;.noneMatch((S-&gt;boolean) predicate)
+					</description>
+					<location chapter="2" section="2.3.25.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+		<assertion defined-by="technology" status="active" testable="false"
+			impl-spec="true" required="true">
+			<id>EL:SPEC:78</id>
+			<description>
+				The findFirst method returns an Optional containing the first
+				element in the stream, or an empty Optional if the stream is empty.
+			</description>
+			<location chapter="2" section="2.3.26" />
+			<sub-assertions>
+				<assertion defined-by="technology" status="active" testable="true"
+					impl-spec="true" required="true">
+					<id>EL:SPEC:78.1</id>
+					<description>
+						Optional&lt;S&gt; Stream&lt;S&gt;.findFirst()
+					</description>
+					<location chapter="2" section="2.3.26.1" />
+				</assertion>
+			</sub-assertions>
+		</assertion>
+	</assertions>
+</spec>
diff --git a/tck/docs/index.html b/tck/docs/index.html
new file mode 100755
index 0000000..42531ee
--- /dev/null
+++ b/tck/docs/index.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<!--
+
+    Copyright (c) 2018, 2024 Oracle and/or its affiliates and others.
+    All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+  <title>Welcome to the Jakarta Expression Language TCK, Version 6.0</title>
+
+  <style type="text/css">
+<!--
+pre {  background-color: #eeeeee; color: #000099}
+code {  color: #000099}
+h1 {  color: #000099}
+h2 {  color: #000099}
+h3 {  color: #000099; text-decoration: underline}
+h4 {  font-style: italic; color: #000099}
+.tabletitle {  font-style: italic; color: #ffffcc; font-size: small; font-variant: small-caps}
+.subtitle {  font-style: italic; color: #ffffcc; font-variant: small-caps}
+.emphasize  {  font-style: italic; color: #000099}
+-->
+</style>
+</head>
+  <body bgcolor="#ffffdd" text="#000000" link="#0000ff" vlink="#840084" alink="#0000ff">
+<div align="Center">
+<h1>Welcome to the Jakarta Expression Language TCK, Version 6.0<br>
+<span class="emphasize">Your Starting Point</span></h1>
+</div>
+<hr>
+<h2>Guide to Expression Language TCK 6.0 Documentation</h2>
+
+<p>The Expression Language TCK 6.0 documentation includes the following:</p>
+
+<ul>
+  <li>
+    <p>The <cite><a href="ReleaseNotes.html">Expression Language TCK Release Notes</a></cite> provide last-minute information about the EL TCK, Version 6.0. The Release Notes are located in the TCK product bundle.</p>
+  </li>
+  <li>
+    <p>The <cite>Jakarta Expression Language 6.0 Technology  Compatibility  Kit User's Guide</cite>  provides the information you need to install, configure, and run the    TCK. The User's Guide also contains the rules you need to pass for  certification.</p>
+  </li>
+  <li>
+    <p>The <a href="assertions/ELJavadocAssertions.xml">Javadoc Assertion List</a> lists all the javadoc test assertions for the Expression Language TCK.</p>
+  </li>
+  <li>
+    <p>The <a href="assertions/ELSpecAssertions.xml">Specification Assertion List</a> lists all the specification test assertions for the Expression Language TCK.</p>
+  </li>
+</ul>
+
+<hr>
+<p><small>
+<address>
+Copyright (c) 2007, 2024 Oracle and/or its affiliates and others. All rights reserved.
+</address>
+</small></p>
+</body>
+</html>
diff --git a/tck/docs/userguide/README.md b/tck/docs/userguide/README.md
new file mode 100644
index 0000000..a3ec2b6
--- /dev/null
+++ b/tck/docs/userguide/README.md
@@ -0,0 +1,77 @@
+# A JBake project template
+
+## About JBake
+
+JBake is a static site generator, it's inspired from jekyll and written
+in java.  The basic idea is to have templates for the structure of the
+page, and the body generated from asciidoc content.
+
+## Pre requisites
+
+- Maven
+- JDK8+
+
+Deploying to Github will require password less authentication.
+
+This is done by exporting your SSH public key into your Github account.
+
+## Build the site locally
+
+The site is generated under target/staging.
+
+Open file:///PATH_TO_PROJECT_DIR/target/staging in a browser to view the site.
+
+```
+mvn generate-resources
+```
+
+Or you can invoke the JBake plugin directly.
+
+```
+mvn jbake:build
+```
+
+### Rebuild the site on changes
+
+```
+mvn jbake:watch
+```
+
+If you keep this command running, changes to the sources will be
+detected and the site will be rendered incrementally.
+
+This is convenient when writing content.
+
+### Serve the site locally
+
+```
+mvn jbake:serve
+```
+
+If a webserver is required (e.g. absolute path are used), this command
+will start a webserver (jetty) at http://localhost:8820.  It will also
+watch for changes and rebuild incrementally.
+
+## Deploy the site to Github Pages
+
+```
+mvn deploy
+```
+
+## Produce a zip file for download
+
+To produce a zip file containing the generated html files, use:
+
+```
+mvn package
+```
+
+When making a release on GitHub, this zip file should be added to the release.
+
+## Links
+
+- [JBake maven plugin documentation](https://github.com/Blazebit/jbake-maven-plugin)
+- [JBake documentation](http://jbake.org/docs/2.5.1)
+- [Freemarker documentation](http://freemarker.org/docs)
+- [AsciiDoc User Guide](http://asciidoc.org/userguide.html)
+- [Asciidoctor quick reference](http://asciidoctor.org/docs/asciidoc-syntax-quick-reference)
diff --git a/tck/docs/userguide/pom.xml b/tck/docs/userguide/pom.xml
new file mode 100644
index 0000000..b99a9e2
--- /dev/null
+++ b/tck/docs/userguide/pom.xml
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2017, 2022 Oracle and/or its affiliates and others.
+    All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.eclipse.ee4j</groupId>
+        <artifactId>project</artifactId>
+        <version>1.0.5</version>
+    </parent>
+    <groupId>org.glassfish</groupId>
+    <artifactId>tck_el</artifactId>
+    <packaging>pom</packaging>
+    <version>6.0.0</version>
+    <name>Eclipse Foundation Technology Compatibility Kit User's Guide for Jakarta Expression Language for Jakarta EE, Release 6.0</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <site.output.dir>${project.build.directory}/staging</site.output.dir>
+        <maven.site.skip>true</maven.site.skip>
+        <asciidoctorj.version>2.4.2</asciidoctorj.version>
+        <asciidoctorj.diagram.version>2.1.0</asciidoctorj.diagram.version>
+        <asciidoctorj.maven.plugin.version>2.2.4</asciidoctorj.maven.plugin.version>
+        <asciidoctorj.pdf.version>1.5.3</asciidoctorj.pdf.version>
+        <jbake.maven.plugin.version>2.7.0-rc.7</jbake.maven.plugin.version>
+        <freemarker.version>2.3.30</freemarker.version>
+        <!-- status: DRAFT, BETA, etc., or blank for final -->
+        <status></status>
+        <doc.pdf>Expression-Language-TCK-Users-Guide.pdf</doc.pdf>
+        <maven.deploy.skip>true</maven.deploy.skip>
+    </properties>
+
+    <distributionManagement>
+        <site>
+            <url>scm:git:git@github.com:eclipse-ee4j/jakartaee-tck.git</url>
+        </site>
+    </distributionManagement>
+
+    <build>
+        <defaultGoal>package</defaultGoal>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-clean-plugin</artifactId>
+                <configuration>
+                    <filesets>
+                        <fileset>
+                            <directory>src/main/jbake/content</directory>
+                            <includes>
+                                <include>toc.adoc</include>
+                            </includes>
+                        </fileset>
+                    </filesets>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>enforce-versions</id>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireJavaVersion>
+                                    <version>[17,)</version>
+                                    <message>You need JDK17 or newer</message>
+                                </requireJavaVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.glassfish.doc</groupId>
+                <artifactId>glassfish-doc-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>generate-toc</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>toc</goal>
+                        </goals>
+                        <configuration>
+                            <chapterPatterns>
+                                [0-9]+\s.*,Preface.*,Part\s.*
+                            </chapterPatterns>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>generate-book</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>book</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.jbake</groupId>
+                <artifactId>jbake-maven-plugin</artifactId>
+                <configuration>
+                    <outputDirectory>${site.output.dir}</outputDirectory>
+                    <properties>
+                        <status>${status}</status>
+                    </properties>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>build-site</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.asciidoctor</groupId>
+                <artifactId>asciidoctor-maven-plugin</artifactId>
+                <configuration>
+                    <sourceDirectory>${project.build.directory}/book</sourceDirectory>
+                    <sourceDocumentName>book.adoc</sourceDocumentName>
+                    <!-- XXX - below depends on running jbake first -->
+                    <imagesDir>${project.build.directory}/staging/</imagesDir>
+                    <backend>pdf</backend>
+                    <outputFile>${doc.pdf}</outputFile>
+                    <attributes>
+                        <pdf-stylesdir>${project.basedir}/src/theme</pdf-stylesdir>
+                        <pdf-style>jakartaee</pdf-style>
+                        <doctype>book</doctype>
+                        <status>${status}</status>
+                        <compat-mode />
+                        <data-uri />
+                        <icons>font</icons>
+                        <pagenums />
+                        <toc />
+                        <icons>font</icons>
+                        <sectanchors>true</sectanchors>
+                        <idprefix />
+                        <idseparator>-</idseparator>
+                        <docinfo1>true</docinfo1>
+                        <embedAssets>true</embedAssets>
+                    </attributes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>generate-pdf-doc</id>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>process-asciidoc</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-scm-publish-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>deploy-site</id>
+                        <phase>deploy</phase>
+                        <goals>
+                            <goal>publish-scm</goal>
+                        </goals>
+                        <configuration>
+                            <scmBranch>gh-pages</scmBranch>
+                            <skipDeletedFiles>false</skipDeletedFiles>
+                            <checkinComment>Update site</checkinComment>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+	    </plugins>
+
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-clean-plugin</artifactId>
+                    <version>3.1.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.glassfish.doc</groupId>
+                    <artifactId>glassfish-doc-maven-plugin</artifactId>
+                    <version>1.3</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-enforcer-plugin</artifactId>
+                    <version>3.0.0-M3</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-assembly-plugin</artifactId>
+                    <version>3.3.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-scm-publish-plugin</artifactId>
+                    <version>3.1.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.jbake</groupId>
+                    <artifactId>jbake-maven-plugin</artifactId>
+                    <version>${jbake.maven.plugin.version}</version>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.asciidoctor</groupId>
+                            <artifactId>asciidoctorj</artifactId>
+                            <version>${asciidoctorj.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.asciidoctor</groupId>
+                            <artifactId>asciidoctorj-diagram</artifactId>
+                            <version>${asciidoctorj.diagram.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.freemarker</groupId>
+                            <artifactId>freemarker</artifactId>
+                            <version>${freemarker.version}</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+                <plugin>
+                    <groupId>org.asciidoctor</groupId>
+                    <artifactId>asciidoctor-maven-plugin</artifactId>
+                    <version>${asciidoctorj.maven.plugin.version}</version>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.asciidoctor</groupId>
+                            <artifactId>asciidoctorj-pdf</artifactId>
+                            <version>${asciidoctorj.pdf.version}</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+</project>
diff --git a/tck/docs/userguide/src/main/jbake/assets/README.md b/tck/docs/userguide/src/main/jbake/assets/README.md
new file mode 100644
index 0000000..f8f962c
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/assets/README.md
@@ -0,0 +1,4 @@
+# About
+
+The {{site.title}} project contains the [AsciiDoc](http://asciidoc.org/)
+source code for the ...
diff --git a/tck/docs/userguide/src/main/jbake/assets/_config.yml b/tck/docs/userguide/src/main/jbake/assets/_config.yml
new file mode 100644
index 0000000..0b6dd98
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/assets/_config.yml
@@ -0,0 +1,14 @@
+remote_theme: jakartaee/jekyll-theme-jakarta-ee
+
+title: [tck_uml_v3_0]
+description: [Oracle Technology Compatibility Kit User's Guide for Expression Language 6.0 for Technology Licensees, Release 6.0]
+
+# sidebar links url
+links:
+  source: https://github.com/jakartaee/platform-tck
+  download: https://download.eclipse.org/jakartaee/expression-language/
+  #mailinglist: https://javaee.groups.io/g/tck_uml_v3_0
+  #javadocs:
+  docs: https://jakarta.ee/specifications/expression-language/6.0/apidocs
+  #faq:
+
diff --git a/tck/docs/userguide/src/main/jbake/assets/css/style.css b/tck/docs/userguide/src/main/jbake/assets/css/style.css
new file mode 100644
index 0000000..182f755
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/assets/css/style.css
@@ -0,0 +1,313 @@
+/* CSS */
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+/** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
+html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ }
+
+/* HTML5 display definitions ========================================================================== */
+/** Correct `block` display not defined for any HTML5 element in IE 8/9. Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox. Correct `block` display not defined for `main` in IE 11. */
+article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary { display: block; }
+
+/** 1. Correct `inline-block` display not defined in IE 8/9. 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. */
+audio, canvas, progress, video { display: inline-block; /* 1 */ vertical-align: baseline; /* 2 */ }
+
+/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
+audio:not([controls]) { display: none; height: 0; }
+
+/** Address `[hidden]` styling not present in IE 8/9/10. Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. */
+[hidden], template { display: none; }
+
+/* Links ========================================================================== */
+/** Remove the gray background color from active links in IE 10. */
+a { background-color: transparent; }
+
+/** Improve readability when focused and also mouse hovered in all browsers. */
+a:active, a:hover { outline: 0; }
+
+/* Text-level semantics ========================================================================== */
+/** Address styling not present in IE 8/9/10/11, Safari, and Chrome. */
+abbr[title] { border-bottom: 1px dotted; }
+
+/** Address style set to `bolder` in Firefox 4+, Safari, and Chrome. */
+b, strong { font-weight: bold; }
+
+/** Address styling not present in Safari and Chrome. */
+dfn { font-style: italic; }
+
+/** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari, and Chrome. */
+h1 { font-size: 2em; margin: 0.67em 0; }
+
+/** Address styling not present in IE 8/9. */
+mark { background: #ff0; color: #000; }
+
+/** Address inconsistent and variable font size in all browsers. */
+small { font-size: 80%; }
+
+/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
+sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
+
+sup { top: -0.5em; }
+
+sub { bottom: -0.25em; }
+
+/* Embedded content ========================================================================== */
+/** Remove border when inside `a` element in IE 8/9/10. */
+img { border: 0; }
+
+/** Correct overflow not hidden in IE 9/10/11. */
+svg:not(:root) { overflow: hidden; }
+
+/* Grouping content ========================================================================== */
+/** Address margin not present in IE 8/9 and Safari. */
+figure { margin: 1em 40px; }
+
+/** Address differences between Firefox and other browsers. */
+hr { box-sizing: content-box; height: 0; }
+
+/** Contain overflow in all browsers. */
+pre { overflow: auto; }
+
+/** Address odd `em`-unit font size rendering in all browsers. */
+code, kbd, pre, samp { font-family: monospace, monospace; font-size: 1em; }
+
+/* Forms ========================================================================== */
+/** Known limitation: by default, Chrome and Safari on OS X allow very limited styling of `select`, unless a `border` property is set. */
+/** 1. Correct color not being inherited. Known issue: affects color of disabled elements. 2. Correct font properties not being inherited. 3. Address margins set differently in Firefox 4+, Safari, and Chrome. */
+button, input, optgroup, select, textarea { color: inherit; /* 1 */ font: inherit; /* 2 */ margin: 0; /* 3 */ }
+
+/** Address `overflow` set to `hidden` in IE 8/9/10/11. */
+button { overflow: visible; }
+
+/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. Correct `select` style inheritance in Firefox. */
+button, select { text-transform: none; }
+
+/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */
+button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ }
+
+/** Re-set default cursor for disabled elements. */
+button[disabled], html input[disabled] { cursor: default; }
+
+/** Remove inner padding and border in Firefox 4+. */
+button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
+
+/** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
+input { line-height: normal; }
+
+/** It's recommended that you don't attempt to style these elements. Firefox's implementation doesn't respect box-sizing, padding, or width.  1. Address box sizing set to `content-box` in IE 8/9/10. 2. Remove excess padding in IE 8/9/10. */
+input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ }
+
+/** Fix the cursor style for Chrome's increment/decrement buttons. For certain `font-size` values of the `input`, it causes the cursor style of the decrement button to change from `default` to `text`. */
+input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { height: auto; }
+
+/** 1. Address `appearance` set to `searchfield` in Safari and Chrome. 2. Address `box-sizing` set to `border-box` in Safari and Chrome (include `-moz` to future-proof). */
+input[type="search"] { -webkit-appearance: textfield; /* 1 */ /* 2 */ box-sizing: content-box; }
+
+/** Remove inner padding and search cancel button in Safari and Chrome on OS X. Safari (but not Chrome) clips the cancel button when the search input has padding (and `textfield` appearance). */
+input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
+
+/** Define consistent border, margin, and padding. */
+fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
+
+/** 1. Correct `color` not being inherited in IE 8/9/10/11. 2. Remove padding so people aren't caught out if they zero out fieldsets. */
+legend { border: 0; /* 1 */ padding: 0; /* 2 */ }
+
+/** Remove default vertical scrollbar in IE 8/9/10/11. */
+textarea { overflow: auto; }
+
+/** Don't inherit the `font-weight` (applied by a rule above). NOTE: the default cannot safely be changed in Chrome and Safari on OS X. */
+optgroup { font-weight: bold; }
+
+/* Tables ========================================================================== */
+/** Remove most spacing between table cells. */
+table { border-collapse: collapse; border-spacing: 0; }
+
+td, th { padding: 0; }
+
+/* LAYOUT STYLES */
+
+p { margin-top: 0; }
+
+code, pre { margin-bottom: 30px; font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; font-size: 13px; color: #222; }
+
+code { padding: 0 3px; background-color: #f2f8fc; border: solid 1px #dbe7f3; }
+
+pre { padding: 20px; overflow: auto; text-shadow: none; background: #fff; border: solid 1px #f2f2f2; }
+
+pre code { padding: 0; color: #2879d0; background-color: #fff; border: none; }
+
+ul, ol, dl { margin-bottom: 20px; }
+
+/* COMMON STYLES */
+
+td.halign-right { text-align: right; } 
+
+td.halign-center { text-align: center; } 
+
+form { padding: 20px; background: #f2f2f2; }
+
+h2 { 
+   font-size: 2em;
+   line-height: 1.2em;
+   font-weight: 200;
+   letter-spacing: 0;
+}
+
+h3 { 
+   font-size: 1.4em;
+   line-height: 1.2em;
+   font-weight: normal;
+   letter-spacing: 0;
+}
+
+.sect1 {
+   margin-left: 4%;
+   margin-right: 4%;
+   font: 13px/20px Arial, Helvetica, sans-serif  
+}
+
+a:link {
+   text-decoration: none;
+   color: #09569d;
+}
+
+#preamble hr{
+   margin-left: 0%;
+   margin-right: 0%;
+}
+
+#preamble .sectionbody table  {
+   font-weight: 200;
+   margin-left: 4%;
+   margin-right: 4%;
+}
+
+hr {
+   margin-bottom: 12px;
+}
+
+table.tableblock.frame-all.grid-all.spread {
+   font-size: 12px;
+}
+
+code {
+   font-size:.9em;
+   border: 1px solid #eaeaea;
+   background-color: #f6f6f6;
+   border-radius: 3px;
+   padding: 1px;
+   padding-left:2px;
+   padding-right:2px;
+}
+
+pre.prettyprint.highlight {
+   border: 1px solid #eaeaea;
+   background-color: #f6f6f6;
+   border-radius: 4px;
+   padding: 8px;
+   padding-top:4px;
+   padding-bottom:4px;
+}
+
+.language-oac_no_warn {
+   font-size:.9em;
+   color:#222;
+   background-color: transparent;
+}
+
+#doc-title {
+   margin-left: 4%;
+}
+
+#top-nav {
+   margin-left: 4%;
+   font-size: 12px;
+}
+
+#bottom-nav {
+   margin-left: 4%;
+   font-size: 12px;
+}
+
+.vector-font {
+   color:grey; 
+   font-size: 20px;
+}
+
+#copyright {
+   padding-top: 10px;
+   padding-bottom: 4px;
+   display: table;
+   margin:0 auto;
+   color: grey;
+   font-size: 12px;
+   vertical-align: middle;
+}
+
+.beta {color: #FF0000}
+
+/* GENERAL ELEMENT TYPE STYLES */
+
+/* #Media Queries
+================================================== */
+/* Smaller than standard 960 (devices and browsers) */
+/* Tablet Portrait size to standard 960 (devices and browsers) */
+@media only screen and (min-width: 768px) and (max-width: 959px) { .inner { width: 740px; }
+  header h1, header h2 { width: 340px; }
+  header h1 { font-size: 60px; }
+  header h2 { font-size: 30px; }
+}
+/* All Mobile Sizes (devices and browser) */
+@media only screen and (max-width: 767px) { .inner { width: 93%; }
+  header { padding: 20px 0; }
+  header .inner { position: relative; }
+  header h1, header h2 { width: 100%; }
+  header h1 { font-size: 48px; }
+  header h2 { font-size: 24px; }
+  header a.button { position: relative; display: inline-block; width: auto; height: auto; padding: 5px 10px; margin-top: 15px; font-size: 13px; line-height: 1; color: #2879d0; text-align: center; background-color: #9ddcff; background-image: none; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; }
+  header a.button small { display: inline; font-size: 13px; }
+}
+/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
+/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
+
+header h1 { padding-top: 14px; font-size: 2em; font-weight: 200; line-height: 1.4; color: #FFFFFF; letter-spacing: 0px; border-bottom: 0px; }
+
+header h2 { font-size: 1.2em; margin-top: 0; margin-bottom: 0; font-weight: 200; line-height: .8; color: #ec7D11; letter-spacing: 0; }
+
+//header a.button { background: transparent url(../images/logo.png) 0 0 no-repeat; padding-left: 32px; }
+
+header a:hover { text-decoration: none; }
+
+/* Admonition (Note) block */
+.admonitionblock > table {
+  border: 0;
+  background: none;
+  width: 100%;
+  table-layout: auto;
+  margin-bottom: 10.5px;
+}
+.admonitionblock > table td.icon {
+  text-align: center;
+  width: 60px;
+}
+.admonitionblock > table td.icon img {
+  max-width: none;
+}
+.admonitionblock > table td.icon .title {
+  text-transform: uppercase;
+}
+.admonitionblock > table td.content {
+  padding-left: 1em;
+  padding-right: 1em;
+  border-left: 3px solid #ddd;
+}
+.admonitionblock > table td.content > :last-child > :last-child {
+  margin-bottom: 0;
+}
+.admonitionblock td.icon [class^="fa icon-"]:before {
+  font-size: 2.5em;
+  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
+  cursor: default;
+}
+.admonitionblock td.icon .icon-note:before {
+  content: "\f05a";
+  color: #5bc0de;
+}
diff --git a/tck/docs/userguide/src/main/jbake/assets/img/eclipse_foundation_logo_tiny.png b/tck/docs/userguide/src/main/jbake/assets/img/eclipse_foundation_logo_tiny.png
new file mode 100644
index 0000000..ee830ae
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/assets/img/eclipse_foundation_logo_tiny.png
Binary files differ
diff --git a/tck/docs/userguide/src/main/jbake/content/README b/tck/docs/userguide/src/main/jbake/content/README
new file mode 100644
index 0000000..05fa2c2
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/README
@@ -0,0 +1,77 @@
+The file attributes.conf defines several attributes (variables) that
+need to be customized for each technology.
+
+The *.adoc files should not be modified.
+
+The following "include" files should be customized as necessary
+for the specific technology:
+
+- rules.inc
+
+	Additional compatibility rules needed by some technologies.
+	The rules in rules.adoc should NOT be changed.
+
+- defns.inc
+
+	Additional definitions needed by additional compatibility
+	rules in rules.inc.
+
+- config.inc
+
+	Detailed instructions for configuring the TCK, included in
+	Chapter 4.  Unfortunately, these are sections 4.1 - 4.3,
+	so even if the TCK doesn't require 3 sections you need to
+	make up something, or else change the sections to "N/A".
+
+- packages.inc
+
+	A simple list of Jakarta EE package names for the technology.
+
+- tck-packages.inc
+
+	A list of additional software packages included in the TCK.
+
+- req-software.inc
+
+	A list of software required in addition to the TCK and CI.
+
+- install-server.inc
+
+	Steps to install the Jakarta EE CI, if needed.
+	For standalone technologies, no server may be required,
+	and this file can be empty.
+	This is used in install.adoc in section 3.2.
+
+- install-server-vi.inc
+
+	Steps to install a Vendor's web server, if needed.
+	For standalone technologies, no web server may be required,
+	and this file can be empty.
+	This is used in install.adoc in section 3.2.
+
+- using-examples.inc
+
+	Command line examples showing how to run the TCK.
+
+- using.inc
+
+	Optional additional instructions for running the TCK.
+
+- debug-tips.inc
+
+	Technology-specific troubleshooting tips for Chapter 6.
+	If this isn't needed, it can be an empty file, but toc.adoc
+	will need to be fixed.
+
+- rebuild.inc
+
+	Special instructions for rebuilding the WAR files used by some TCKs.
+	If needed, customize it appropriately and define the "rebuild"
+	attribute in attributes.conf.
+
+- title.inc
+	Add acronym references as required do distinguish between legacy and 
+	current APIs.
+
+Note that this template is NOT sufficient for the Jakarta EE platform
+or Jakarta EE Web Profile.
diff --git a/tck/docs/userguide/src/main/jbake/content/attributes.conf b/tck/docs/userguide/src/main/jbake/content/attributes.conf
new file mode 100644
index 0000000..ed98305
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/attributes.conf
@@ -0,0 +1,35 @@
+:TechnologyFullName: Jakarta Expression Language
+:TechnologyShortName: Expression Language
+:LegacyAcronym: EL		   
+:TechnologyVersion: 6.0
+:ReleaseDate: January 2024
+:CopyrightDates: 2017, 2024
+:TechnologyRI: Eclipse GlassFish 6.0
+:TechnologyRIURL: https://projects.eclipse.org/projects/ee4j.glassfish
+:SpecificationURL: https://jakarta.ee/specifications/expression-language/6.0/
+:TCKInquiryList: mailto:jakartaee-tck-dev@eclipse.org[jakartaee-tck-dev@eclipse.org]
+:SpecificationInquiryList: mailto:el-dev@eclipse.org[el-dev@eclipse.org]
+:techID: ExpressionLanguage
+// Define this attribute (uncomment it) if the TCK includes no API tests.  (Rare.)
+// :no-api-tests:
+// Define this attribute (uncomment it) if the TCK includes end-to-end tests.
+// :end-to-end-tests:
+// Define this attribute (uncomment it) if subsets of the API are allowed.
+// (Common Annotations only)
+// :subset-allowed:
+//
+// The environment variable used to specify the home directory
+// for the technology.  Used in config.inc.
+:TechnologyHomeEnv: EL_HOME
+// Java SE version required.
+:SEversion: 21
+:MavenVersion: 3.6.3+
+:JakartaEEVersion: 11
+:excludeListFileName: docs/TCK-Exclude-List.txt
+:TCKPackageName: jakarta-expression-language-tck-6.0.0.zip
+// Directory names used in examples in using.adoc.
+:sigTestDirectoryExample: com/sun/ts/tests/signaturetest/el
+:singleTestDirectoryExample: com/sun/ts/tests/el/api/client
+:subsetTestDirectoryExample: com/sun/ts/tests/el/api
+// Define this attribute (uncomment it) if the TCK needs the rebuild appendix.
+// :rebuild:
diff --git a/tck/docs/userguide/src/main/jbake/content/config.adoc b/tck/docs/userguide/src/main/jbake/content/config.adoc
new file mode 100644
index 0000000..7f43a03
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/config.adoc
@@ -0,0 +1,47 @@
+type=page
+status=published
+title=Setup and Configuration
+next=using.html
+prev=install.html
+~~~~~~
+include::attributes.conf[]
+Setup and Configuration
+=======================
+
+[[GBFVV]]
+
+
+
+[[setup-and-configuration]]
+4 Setup and Configuration
+-------------------------
+
+
+[NOTE]
+====
+The Jakarta EE Specification process provides for any number of compatible implementations.
+As additional implementations become available, refer to project or product documentation from
+those vendors for specific TCK setup and operational guidance.
+
+====
+
+This chapter describes how to set up the {TechnologyShortName} TCK.
+Before proceeding with the instructions in
+this chapter, be sure to install all required software, as described in
+link:install.html#GBFTP[Chapter 3, "Installation."]
+
+After completing the instructions in this chapter, proceed to
+link:using.html#GBFWO[Chapter 5, "Executing Tests,"] for instructions on
+running the {TechnologyShortName} TCK.
+
+[NOTE]
+====
+The {TechnologyShortName} TCK is not depended on any particular build 
+tool to run the tests. It will be convenient and advisable to create a 
+Apache Maven project to setup and run the TCK.
+This chapter will henceforth use instructions and steps to provide setup 
+with Apache Maven as a build tool. 
+====
+
+include::config.inc[]
+
diff --git a/tck/docs/userguide/src/main/jbake/content/config.inc b/tck/docs/userguide/src/main/jbake/content/config.inc
new file mode 100644
index 0000000..f9a22fd
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/config.inc
@@ -0,0 +1,143 @@
+///////////////////////////////////////////////////////////////////////////////
+
+    Copyright (c) 2020, 2024 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+NOTE TO WRITERS:
+The following sections should be customized for the technology.
+This text was originally from the {TechnologyShortName} TCK.  Most references
+to {TechnologyShortName} have been parameterized to serve as a simple starting
+point for customization.  There are still many details that will
+need to be changed or removed.  The major sections 4.1, 4.2, and
+4.3 should be preserved.  If their titles are changed, the links
+at the top of config.adoc will need to be changed as well as well
+as toc.adoc.
+///////////////////////////////////////////////////////////////////////
+
+[[GBFVU]][[configuring-your-environment-to-run-the-tck-against-the-reference-implementation]]
+
+4.1 Configuring Your Environment to Run the TCK Against a Compatible Implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After configuring your environment as described in this section,
+continue with the instructions in link:using.html#GBFWO[Chapter 5, "Executing Tests."]
+
+
+[NOTE]
+=======================================================================
+
+In these instructions, variables in angle brackets need to be expanded
+for each platform. For example, `<JAVA_HOME>` becomes `$JAVA_HOME` on
+Solaris/Linux and `%JAVA_HOME%` on Windows. In addition, the forward
+slashes (`/`) used in all of the examples need to be replaced with
+backslashes (`\`) for Windows. Finally, be sure to use the appropriate
+separator for your operating system when specifying multiple path
+entries (`;` on Windows, `:` on UNIX/Linux).
+
+On Windows, you must escape any backslashes with an extra backslash in
+path separators used in any of the following properties, or use forward
+slashes as a path separator instead.
+
+=======================================================================
+
+
+1.  Set the following environment variables in your shell environment:
+  a.  `JAVA_HOME` to the directory in which Java SE {SEversion} is installed
+  b.  `M2_HOME` to the directory in which the Apache Maven build tool is installed.
+  c.  `PATH` to include the following directories: `JAVA_HOME/bin`,
+  and `M2_HOME/bin`
+2.  Set the following System properties:
+  a.  Set the `webServerHost` property to the name of the host on which
+  Jakarta EE {JakartaEEVersion} CI is running. +
+  The default setting is `localhost`.
+  b.  Set the `webServerPort` property to the port number of the host on
+  which Jakarta EE {JakartaEEVersion} CI is running. +
+  The default setting is `8080`.
+  c.  Set the `el.classes` property to the directory of Jakarta EE
+  {JakartaEEVersion} CI with implementation jar and api jar.
+  d. Set the `porting.ts.url.class.1` property to your porting
+  implementation class that is used for obtaining URLs. +
+  The default setting for this property is
+  `com.sun.ts.lib.implementation.sun.common.SunRIURL`.
++
+3. Set the below jars to the classpath 
+  a. JAR file for the {TechnologyShortName} {TechnologyVersion} API. +
+  eg.  `${webServerHost}/modules/jakarta.el-api.jar`.
++
+  b. JUnit 5 jars (5.7.2+)
+  Maven cordinates :
++
+[source,oac_no_warn]
+----
+       <dependency>
+          <groupId>org.junit</groupId>
+          <artifactId>junit-bom</artifactId>
+          <version>5.7.2</version>
+          <type>pom</type>
+          <scope>import</scope>
+       </dependency>
+----
++
+ c. sigtest-maven-plugin (1.4) to run the signature tests.
+  Maven cordinates :
++
+[source,oac_no_warn]
+----
+      <dependency>
+            <groupId>jakarta.tck</groupId>
+            <artifactId>sigtest-maven-plugin</artifactId>
+            <version>2.2</version>
+        </dependency>
+----
++
+  d.  {TechnologyRI} CI jars +
+  For eg, if you are using the {TechnologyRI} CI below jars need to be added to Classpath
+ 
++
+[source,oac_no_warn]
+----
+${webServerHost}/modules/expressly.jar:
+----
++
+4.  Provide compatible implementation of the porting package interface
+provided with the {TechnologyShortName} TCK. +
+The porting package interface, `TSURLInterface.java`, obtains URL
+strings for web resources in an implementation-specific manner. API
+documentation for the `TSURLInterface.java` porting package interface is
+available in the {TechnologyShortName} TCK documentation bundle.
+5.  If the {TechnologyShortName} TCK test applications are published on
+a Servlet 5.0-compliant Web container to run the CI, the `servlet_adaptor` 
+property needs to be set as System property, and CI-specific WAR files
+containing the Servlet information need to be created for publishing. +
+The CI-specific WAR files should never override any existing files that
+come with the TCK. Refer to link:rebuild.html#GCLIZ[Appendix B,
+"Packaging the Test Applications in Servlet-Compliant WAR
+Files With VI-Specific Information,"] for more information.
+
+[[GCLHU]][[configuring-your-environment-to-repackage-and-run-the-tck-against-the-vendor-implementation]]
+
+4.2 Configuring Your Environment to Repackage and Run the TCK Against the Vendor Implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Not needed for the EL TCK.
+
+[[GHGDG]][[publishing-the-test-applications]]
+
+4.3 Publishing the Test Applications
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Not needed for the EL TCK.
diff --git a/tck/docs/userguide/src/main/jbake/content/debug-tips.inc b/tck/docs/userguide/src/main/jbake/content/debug-tips.inc
new file mode 100644
index 0000000..bbe4252
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/debug-tips.inc
@@ -0,0 +1,15 @@
+///////////////////////////////////////////////////////////////////////
+NOTE TO WRITERS:
+The following sections should be customized for the technology.
+This text was originally from the JACC TCK.  Some references
+to JACC have been parameterized to serve as a simple starting
+point for customization.  There are still many details that will
+need to be changed or removed.
+///////////////////////////////////////////////////////////////////////
+
+[[GBFHA]][[troubleshooting-tips]]
+
+6.7 Troubleshooting Tips
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+None for the {TechnologyShortName} TCK.
diff --git a/tck/docs/userguide/src/main/jbake/content/debug.adoc b/tck/docs/userguide/src/main/jbake/content/debug.adoc
new file mode 100644
index 0000000..305d8c7
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/debug.adoc
@@ -0,0 +1,82 @@
+type=page
+status=published
+title=Debugging Test Problems
+next=faq.html
+prev=using.html
+~~~~~~
+include::attributes.conf[]
+Debugging Test Problems
+=======================
+
+[[GBFUV]]
+
+
+[[debugging-test-problems]]
+6 Debugging Test Problems
+-------------------------
+
+There are a number of reasons that tests can fail to execute properly.
+This chapter provides some approaches for dealing with these failures.
+Please note that most of these suggestions are only relevant when
+running the test harness in GUI mode.
+
+This chapter includes the following topics:
+
+* link:#GBFYP[Overview]
+* link:#GBFVF[Test Tree]
+* link:#GBFWI[Folder Information]
+* link:#GBFVP[Test Information]
+* link:#GBFVZ[Report Files]
+* link:#GBFYF[Configuration Failures]
+
+[[GBFYP]][[overview]]
+
+6.1 Overview
+~~~~~~~~~~~~
+The goal of a test run is for all tests in the test suite that are not
+filtered out to have passing results. If the root test suite folder
+contains tests with errors or failing results, you must troubleshoot and
+correct the cause to satisfactorily complete the test run.
+
+* Errors: Tests with errors could not be executed by the Junit
+framework. These errors usually occur because the test environment is not
+properly configured.
+* Failures: Tests that fail were executed but had failing results.
+
+
+For every test run, the Junit framework creates a set of report files
+in the target directory.
+
+
+If a large number of tests failed, you should read
+link:#GBFYF[Configuration Failures] to see if a
+configuration issue is the cause of the failures.
+
+[NOTE]
+=======================================================================
+
+You can set `junit.log.traceflag=true` as System property to
+get more debugging information.
+
+=======================================================================
+
+
+[[GBFVP]][[test-information]]
+
+6.2 Test Information
+~~~~~~~~~~~~~~~~~~~~
+
+If you need more information to identify the cause of the error or
+failure, use the Junit reports generated after running the tests.
+
+
+[[GBFYF]][[configuration-failures]]
+
+6.3 Configuration Failures
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Configuration failures are easily recognized because many tests fail the
+same way. When all your tests begin to fail, you may want to stop the
+run immediately and start viewing individual test output.
+
+include::debug-tips.inc[]
diff --git a/tck/docs/userguide/src/main/jbake/content/defns.inc b/tck/docs/userguide/src/main/jbake/content/defns.inc
new file mode 100644
index 0000000..038db2d
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/defns.inc
@@ -0,0 +1,46 @@
+// NOTE TO WRITERS:
+// Most technologies will only need the compatibility rules in rules.adoc.
+// Some technologies will need additional definitions to go with additional
+// rules.  If they're needed, remove the comment characters below
+// and update the definitions as appropriate.
+//
+// The first block below is additional definitions needed by
+// Jakarta XML Web Services.
+//
+// The second block below is additional defintions needed by
+// Jakarta Server Pages.
+//
+// NOTE: This set of examples is NOT complete, but should be.
+//
+//
+// Jakarta XML Web Services
+//
+// |Development Kit |A software product that implements or incorporates a
+// Compiler, a Schema Compiler, a Schema Generator, a Java-to-WSDL Tool, a
+// WSDL-to-Java Tool, and/or an RMI Compiler.
+//
+// |Java-to-WSDL Output |Output of a Java-to-WSDL Tool that is required for
+// Web service deployment and invocation.
+//
+// |Java-to-WSDL Tool |A software development tool that implements or
+// incorporates a function that generates web service endpoint descriptions
+// in WSDL and XML schema format from Source Code as specified by the
+// Jakarta XML Web Services Specification.
+//
+// |WSDL-to-Java Output |Output of a WSDL-to-Java tool that is required for
+// Web service deployment and invocation.
+//
+// |WSDL-to-Java Tool |A software development tool that implements or
+// incorporates a function that generates web service interfaces for
+// clients and endpoints from a WSDL description as specified by the
+// Jakarta XML Web Services Specification.
+//
+//
+// Jakarta Server Pages
+//
+// |Jakarta Server Page |A text-based document that uses Jakarta Server
+// Pages technology.
+//
+// |Jakarta Server Page Implementation Class |A program constructed by
+// transforming the Jakarta Server Page text into a Java language program
+// using the transformation rules described in the Specifications.
diff --git a/tck/docs/userguide/src/main/jbake/content/faq.adoc b/tck/docs/userguide/src/main/jbake/content/faq.adoc
new file mode 100644
index 0000000..a9a9928
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/faq.adoc
@@ -0,0 +1,63 @@
+type=page
+status=published
+title=Appendix A: Frequently Asked Questions
+next=rebuild.html
+prev=debug.html
+~~~~~~
+include::attributes.conf[]
+Appendix A: Frequently Asked Questions
+======================================
+
+[[GBFYD]]
+
+
+[[a-frequently-asked-questions]]
+A Frequently Asked Questions
+----------------------------
+
+This appendix contains the following questions.
+
+* link:#GBFYQ[Where do I start to debug a test failure?]
+* link:#GBFYR[How do I restart a crashed test run?]
+* link:#GBFWU[What would cause tests be added to the exclude list?]
+
+[[GBFYQ]][[a.1-where-do-i-start-to-debug-a-test-failure]]
+
+A.1 Where do I start to debug a test failure?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+From the JavaTest GUI, you can view recently run tests using the Test
+Results Summary, by selecting the red Failed tab or the blue Error tab.
+See link:debug.html#GBFUV[Chapter 6, "Debugging Test Problems,"] for more
+information.
+
+[[GBFYR]][[a.2-how-do-i-restart-a-crashed-test-run]]
+
+A.2 How do I restart a crashed test run?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you need to restart a test run, you can figure out which test crashed
+the test suite by looking at the `harness.trace` file. The
+`harness.trace` file is in the report directory that you supplied to the
+JavaTest GUI or parameter file. Examine this trace file, then change the
+JavaTest GUI initial files to that location or to a directory location
+below that file, and restart. This will overwrite only `.jtr` files that
+you rerun. As long as you do not change the value of the GUI work
+directory, you can continue testing and then later compile a complete
+report to include results from all such partial runs.
+
+[[GBFWU]][[a.3-what-would-cause-tests-be-added-to-the-exclude-list]]
+
+A.3 What would cause tests be added to the exclude list?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The exclude file (+{excludeListFileName}+) contains all tests that are not
+required to be run. The file is used only for documentation purpose. The tests are excluded using
+@Disabled tag in Junit when necessary. The following is a list of reasons for a test to be
+included in the Exclude List:
+
+* An error in a Compatible Implementation that does not allow the test to
+execute properly has been discovered.
+* An error in the specification that was used as the basis of the test
+has been discovered.
+* An error in the test has been discovered.
diff --git a/tck/docs/userguide/src/main/jbake/content/install-server-vi.inc b/tck/docs/userguide/src/main/jbake/content/install-server-vi.inc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/install-server-vi.inc
diff --git a/tck/docs/userguide/src/main/jbake/content/install-server.inc b/tck/docs/userguide/src/main/jbake/content/install-server.inc
new file mode 100644
index 0000000..f8e47e1
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/install-server.inc
@@ -0,0 +1,10 @@
+.  Install the Jakarta EE {JakartaEEVersion} CI software (the servlet Web container used
+for running the {TechnologyShortName} TCK with the
+{TechnologyShortName} {TechnologyVersion} CI), if it is not already
+installed. +
+Download and install the Servlet Web container with the
+{TechnologyShortName} {TechnologyVersion} CI used for running the
+{TechnologyShortName} TCK {TechnologyVersion}, represented by the Jakarta
+EE {JakartaEEVersion} CI.
+You may obtain a copy of this CI by downloading it from {TechnologyRIURL}.
+
diff --git a/tck/docs/userguide/src/main/jbake/content/install.adoc b/tck/docs/userguide/src/main/jbake/content/install.adoc
new file mode 100644
index 0000000..9bb768c
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/install.adoc
@@ -0,0 +1,93 @@
+type=page
+status=published
+title=Installation
+next=config.html
+prev=rules.html
+~~~~~~
+include::attributes.conf[]
+Installation
+============
+
+[[GBFTP]]
+
+
+[[installation]]
+3 Installation
+--------------
+
+This chapter explains how to install the {TechnologyFullName} TCK software.
+
+After installing the software according to the instructions in this
+chapter, proceed to link:config.html#GBFVV[Chapter 4, "Setup and
+Configuration,"] for instructions on configuring your test environment.
+
+[NOTE]
+=======================================================================
+
+Although the {TechnologyShortName} {TechnologyVersion} TCK is not 
+depended on any particular build tool, it is convenient to install 
+Apache Maven {MavenVersion} for setup and execution of tests. 
+Any other build tools like Gradle and JUnit 5 Console Runner can also 
+be used that is Jupiter API compatible.
+
+=======================================================================
+
+
+[[GBFUD]][[obtaining-the-reference-implementation]]
+
+3.1 Obtaining a Compatible Implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each compatible implementation (CI) will provide instructions for obtaining
+their implementation.
+{TechnologyRI} is a compatible implementation which may be obtained
+from {TechnologyRIURL}
+
+[[GBFTS]][[installing-the-software]]
+
+3.2 Installing the Software
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before you can run the {TechnologyShortName} TCK tests, you must
+install and set up the following software components:
+
+include::req-software.inc[]
+* Java SE {SEversion}
+* A CI for {TechnologyShortName} {TechnologyVersion}, one example is {TechnologyRI}
+* {TechnologyShortName} TCK version {TechnologyVersion}
+* The {TechnologyShortName} {TechnologyVersion} Vendor Implementation (VI)
+* Any Jupiter API compatible test runner (eg. Apache Maven {MavenVersion})
+
+Follow these steps:
+
+.  Install the Java SE {SEversion} software, if it is not already installed. +
+Download and install the Java SE {SEversion} software from
+http://www.oracle.com/technetwork/java/javase/downloads/index.html.
+Refer to the installation instructions that accompany the software for
+additional information.
+
+.  Install the build tool that will be used to run the TCK, if it is not already installed. +
+It will be convenient to use Apache Maven {MavenVersion} for running the tests. The test kit 
+is not depended on Maven, any build tool compatible with Jupiter API is suffitient.
+
+.  Install the {TechnologyShortName} TCK {TechnologyVersion} software.
+  a.  Copy or download the {TechnologyShortName} TCK software to your
+      local system. +
+      You can obtain the {TechnologyShortName} TCK software from the
+      Jakarta EE site {SpecificationURL}.
+  b.  Use the `unzip` command to extract the bundle in the directory of
+      your choice: +
+      +unzip {TCKPackageName}+ +
+      
+include::install-server.inc[]
+.  Install a {TechnologyShortName} {TechnologyVersion} Compatible
+Implementation. +
+A Compatible Implementation is used to validate your initial
+configuration and setup of the {TechnologyShortName} TCK
+{TechnologyVersion} tests, which are explained further in
+link:config.html#GBFVV[Chapter 4, "Setup and Configuration."] +
+The Compatible Implementations for {TechnologyShortName} are listed on
+the Jakarta EE Specifications web site: {SpecificationURL}.
+include::install-server-vi.inc[]
+.  Install the {TechnologyShortName} VI to be tested. +
+Follow the installation instructions for the particular VI under test.
diff --git a/tck/docs/userguide/src/main/jbake/content/intro.adoc b/tck/docs/userguide/src/main/jbake/content/intro.adoc
new file mode 100644
index 0000000..85724fc
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/intro.adoc
@@ -0,0 +1,313 @@
+type=page
+status=published
+title=Introduction
+next=rules.html
+prev=preface.html
+~~~~~~
+include::attributes.conf[]
+Introduction
+============
+
+[[GBFOW]]
+
+
+[[introduction]]
+1 Introduction
+--------------
+
+This chapter provides an overview of the principles that apply
+generally to all Technology Compatibility Kits (TCKs) and describes the
+{TechnologyFullName} TCK ({TechnologyShortName} {TechnologyVersion} TCK). 
+It also includes a high level listing
+of what is needed to get up and running with the {TechnologyShortName}
+TCK.
+
+This chapter includes the following topics:
+
+* link:#GBFTK[Compatibility Testing]
+* link:#GBFQR[About the TCK]
+* link:#GBFQW[Getting Started With the TCK]
+
+[[GBFTK]][[compatibility-testing]]
+
+1.1 Compatibility Testing
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Compatibility testing differs from traditional product testing in a
+number of ways. The focus of compatibility testing is to test those
+features and areas of an implementation that are likely to differ across
+other implementations, such as those features that:
+
+* Rely on hardware or operating system-specific behavior
+* Are difficult to port
+* Mask or abstract hardware or operating system behavior
+
+Compatibility test development for a given feature relies on a complete
+specification and compatible implementation (CI) for that feature.
+Compatibility testing is not primarily concerned with robustness,
+performance, nor ease of use.
+
+[[GBFQN]][[why-compatibility-testing-is-important]]
+
+1.1.1 Why Compatibility Testing is Important
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Jakarta platform compatibility is important to different groups involved
+with Jakarta technologies for different reasons:
+
+* Compatibility testing ensures that the Jakarta platform does not become
+fragmented as it is ported to different operating systems and hardware
+environments.
+* Compatibility testing benefits developers working in the Jakarta
+programming language, allowing them to write applications once and then
+to deploy them across heterogeneous computing environments without
+porting.
+* Compatibility testing allows application users to obtain applications
+from disparate sources and deploy them with confidence.
+* Conformance testing benefits Jakarta platform implementors by ensuring a
+level playing field for all Jakarta platform ports.
+
+[[GBFPR]][[tck-compatibility-rules]]
+
+1.1.2 TCK Compatibility Rules
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Compatibility criteria for all technology implementations are embodied
+in the TCK Compatibility Rules that apply to a specified technology.
+Each TCK tests for adherence to these Rules as described in
+link:rules.html#GBFSN[Chapter 2, "Procedure for Certification."]
+
+[[GBFPW]][[tck-overview]]
+
+1.1.3 TCK Overview
+^^^^^^^^^^^^^^^^^^
+
+A TCK is a set of tools and tests used to verify that a vendor's compatible
+implementation of a Jakarta EE technology conforms to the applicable
+specification. All tests in the TCK are based on the written
+specifications for the Jakarta EE platform. A TCK tests compatibility of a
+vendor's compatible implementation of the technology to the applicable
+specification of the technology. Compatibility testing is a means of
+ensuring correctness, completeness, and consistency across all
+implementations developed by technology licensees.
+
+The set of tests included with each TCK is called the test suite. Most
+tests in a TCK's test suite are self-checking, but some tests may
+require tester interaction. Most tests return either a Pass or Fail
+status. For a given platform to be certified, all of the required tests
+must pass. The definition of required tests may change from platform to
+platform.
+
+The definition of required tests will change over time. Before your
+final certification test pass, be sure to download the latest version
+of this TCK.
+
+[[GBFPB]][[java-community-process-jcp-program-and-compatibility-testing]]
+
+1.1.4 Jakarta EE Specification Process (JESP) Program and Compatibility Testing
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Jakarta EE Specification Process (JESP) program is the formalization of the
+open process that has been used since 2019 to develop and revise Jakarta EE
+technology specifications in cooperation with the international Jakarta EE
+community. The JESP program specifies that the following three major
+components must be included as deliverables in a final Jakarta EE technology
+release under the direction of the responsible Expert Group:
+
+* Technology Specification
+* Compatible Implementation (CI)
+* Technology Compatibility Kit (TCK)
+
+For further information about the JESP program, go to Jakarta EE Specification
+Process community page https://jakarta.ee/specifications.
+
+[[GBFQR]][[about-the-tck]]
+
+1.2 About the TCK
+~~~~~~~~~~~~~~~~~
+
+The {TechnologyShortName} TCK {TechnologyVersion} is designed as a
+portable, configurable, automated test suite for verifying the
+compatibility of a vendor's implementation of the
+{TechnologyShortName} {TechnologyVersion} Specification.
+
+[[GBFQV]][[tck-specifications-and-requirements]]
+
+1.2.1 TCK Specifications and Requirements
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This section lists the applicable requirements and specifications.
+
+* Specification Requirements: Software requirements for a
+{TechnologyShortName} implementation are described in detail in the
+{TechnologyShortName} {TechnologyVersion} Specification.  Links to the
+{TechnologyShortName} specification and other product information can
+be found at {SpecificationURL}.
+* {TechnologyShortName} Version: The {TechnologyShortName} {TechnologyVersion} TCK
+is based on the {TechnologyShortName}
+Specification, Version {TechnologyVersion}.
+* Compatible Implementation: One {TechnologyShortName}
+{TechnologyVersion} Compatible Implementation, {TechnologyRI} is
+available from the Eclipse EE4J project
+(https://projects.eclipse.org/projects/ee4j). See the CI documentation page at
+{TechnologyRIURL} for more information.
+
+See the {TechnologyShortName} TCK Release Notes for more specific
+information about Java SE version requirements, supported platforms,
+restrictions, and so on.
+
+[[GBFSQ]][[tck-components]]
+
+1.2.2 TCK Components
+^^^^^^^^^^^^^^^^^^^^
+
+The {TechnologyShortName} TCK {TechnologyVersion} includes the
+following components:
+
+* {TechnologyShortName} TCK signature tests; check that all public APIs
+are supported and/or defined as specified in the {TechnologyShortName}
+Version {TechnologyVersion} implementation under test.
+* If applicable, an exclude list, which provides a list of tests that your
+implementation is not required to pass.
+ifndef::no-api-tests[]
+* API tests for all of the {TechnologyShortName} API in all related packages:
+include::packages.inc[]
+endif::no-api-tests[]
+ifdef::end-to-end-tests[]
+* End-to-end tests that demonstrate compliance with the {TechnologyFullName}
+Specification.
+endif::end-to-end-tests[]
+
+The {TechnologyShortName} TCK tests run on the following platforms:
+
+include::platforms.inc[]
+
+[[GBFRA]][[tck-compatibility-test-suite]]
+
+1.2.3 TCK Compatibility Test Suite
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The test suite is the collection of tests used by the JavaTest harness
+to test a particular technology implementation. In this case, it is the
+collection of tests used by the {TechnologyShortName} TCK
+{TechnologyVersion} to test a {TechnologyShortName} {TechnologyVersion}
+implementation. The tests are designed to verify that a vendor's
+runtime implementation of the technology complies with the appropriate
+specification. The individual tests correspond to assertions of the
+specification.
+
+The tests that make up the TCK compatibility test suite are precompiled
+and indexed within the TCK test directory structure. When a test run is
+started, the JavaTest harness scans through the set of tests that are
+located under the directories that have been selected. While scanning,
+the JavaTest harness selects the appropriate tests according to any
+matches with the filters you are using and queues them up for execution.
+
+[[GBFSH]][[exclude-lists]]
+
+1.2.4 Exclude Lists
+^^^^^^^^^^^^^^^^^^^
+
+Each version of a TCK includes an Exclude List contained in a `TCK-Exclude-List.txt`
+file. 
+This is a list of test file URLs that identify tests which do not
+have to be run for the specific version of the TCK being used. 
+Whenever tests are run, the Junit framework automatically excludes
+these tests from being executed as those are disabled using '@Disabled' tag in JUnit.
+
+A vendor's compatible implementation is not required to pass or run any test on the Exclude List.
+The Exclude List file, +{excludeListFileName}+, is documented in the
+{TechnologyShortName} TCK. Please note this file is not parsed to exclude any test and is only
+for documentation purpose.
+
+
+[NOTE]
+=======================================================================
+
+From time to time, updates to the Exclude List are made available.
+The exclude list is included in the Jakarta TCK ZIP archive.
+Each time an update is approved and released, the version number 
+will be incremented.
+You should always make sure you are using an up-to-date copy of the
+Exclude List before running the {TechnologyShortName} TCK to verify your
+implementation.
+
+=======================================================================
+
+
+A test might be in the Exclude List for reasons such as:
+
+* An error in an underlying implementation API has been discovered which
+does not allow the test to execute properly.
+* An error in the specification that was used as the basis of the test
+has been discovered.
+* An error in the test itself has been discovered.
+* The test fails due to a bug in the tools (such as the JavaTest
+harness, for example).
+
+In addition, all tests are run against the compatible implementations.
+Any tests that fail when run on a compatible Jakarta platform are put on the
+Exclude List. Any test that is not specification-based, or for which the
+specification is vague, may be excluded. Any test that is found to be
+implementation dependent (based on a particular thread scheduling model,
+based on a particular file system behavior, and so on) may be excluded.
+
+
+[NOTE]
+=======================================================================
+
+Vendors are not permitted to alter or modify Exclude Lists. Changes to
+an Exclude List can only be made by using the procedure described in
+link:rules.html#CJAJEAEI[Section 2.3.1, "TCK Test Appeals Steps."]
+
+=======================================================================
+
+
+[[GBFRR]][[tck-configuration]]
+
+1.2.5 TCK Configuration
+^^^^^^^^^^^^^^^^^^^^^^^
+
+You need to set several variables in your test environment, 
+and run the {TechnologyShortName} tests, as described in
+link:config.html#GBFVV[Chapter 4, "Setup and Configuration."]
+
+include::intro.inc[]
+
+[[GBFQW]][[getting-started-with-the-tck]]
+
+[NOTE]
+====
+The Jakarta EE Specification Process support multiple compatible implementations. 
+These instructions explain how to get started with the {TechnologyRI} CI.
+If you are using another compatible implementation, refer to material provided
+by that implementation for specific instructions and procedures.
+
+====
+
+1.3 Getting Started With the TCK
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This section provides an general overview of what needs to be done to
+install, set up, test, and use the {TechnologyShortName} TCK. These
+steps are explained in more detail in subsequent chapters of this
+guide.
+
+1.  Make sure that the following software has been correctly installed
+on the system :
+include::req-software.inc[]
+* Java SE {SEversion}
+* A CI for {TechnologyShortName} {TechnologyVersion}. One example is {TechnologyRI}.
+* {TechnologyShortName} TCK version {TechnologyVersion}
+* The {TechnologyShortName} {TechnologyVersion} Vendor Implementation (VI) +
+See the documentation for each of these software applications for
+installation instructions. See link:install.html#GBFTP[Chapter 3,
+"Installation,"] for instructions on installing the {TechnologyShortName} TCK.
+2.  Set up the {TechnologyShortName} TCK software. +
+See link:config.html#GBFVV[Chapter 4, "Setup and Configuration,"] for
+details about the following steps.
+  a.  Set up your shell environment.
+  b.  Set the required System properties.
+3.  Test the {TechnologyShortName} {TechnologyVersion} implementation. +
+Test the {TechnologyShortName} implementation installation by running
+the test suite.  See link:using.html#GBFWO[Chapter 5, "Executing Tests."]
diff --git a/tck/docs/userguide/src/main/jbake/content/intro.inc b/tck/docs/userguide/src/main/jbake/content/intro.inc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/intro.inc
diff --git a/tck/docs/userguide/src/main/jbake/content/packages.inc b/tck/docs/userguide/src/main/jbake/content/packages.inc
new file mode 100644
index 0000000..1636650
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/packages.inc
@@ -0,0 +1 @@
+** `jakarta.el`
diff --git a/tck/docs/userguide/src/main/jbake/content/platforms.inc b/tck/docs/userguide/src/main/jbake/content/platforms.inc
new file mode 100644
index 0000000..1afa2d2
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/platforms.inc
@@ -0,0 +1 @@
+* Debian GNU/Linux 10
\ No newline at end of file
diff --git a/tck/docs/userguide/src/main/jbake/content/preface.adoc b/tck/docs/userguide/src/main/jbake/content/preface.adoc
new file mode 100644
index 0000000..bbedf61
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/preface.adoc
@@ -0,0 +1,145 @@
+type=page
+status=published
+title=Preface
+next=intro.html
+prev=title.html
+~~~~~~
+include::attributes.conf[]
+Preface
+=======
+
+[[TCJRS00001]][[GBFTI]]
+
+
+[[preface]]
+Preface
+-------
+
+This guide describes how to install, configure, and run the Technology
+Compatibility Kit (TCK) that is used to test the {TechnologyFullName}
+({TechnologyShortName} {TechnologyVersion}) technology.
+
+The {TechnologyShortName} TCK is a portable, configurable automated
+test suite for verifying the compatibility of a vendor's
+implementation of the {TechnologyShortName} {TechnologyVersion}
+Specification (hereafter referred to as the vendor implementation or VI).
+
+
+[NOTE]
+=======================================================================
+
+Note All references to specific Web URLs are given for the sake of your
+convenience in locating the resources quickly. These references are
+always subject to changes that are in many cases beyond the control of
+the authors of this guide.
+
+=======================================================================
+
+Jakarta EE is a community sponsored and community run program. 
+Organizations contribute, along side individual contributors who use, evolve 
+and assist others.
+Commercial support is not available through the Eclipse Foundation resources.
+Please refer to the Eclipse EE4J project site
+(https://projects.eclipse.org/projects/ee4j).
+There, you will find additional details as well as a list of all the associated sub-projects 
+(Implementations and APIs), that make up Jakarta EE and define these specifications. 
+If you have questions about this Specification you may
+send inquiries to {SpecificationInquiryList}. 
+If you have questions about this TCK, you may send inquiries to 
+{TCKInquiryList}.
+
+[[TCJRS00034]][[GBFUS]]
+
+
+[[who-should-use-this-book]]
+Who Should Use This Book
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+This guide is for vendors that implement the {TechnologyShortName}
+{TechnologyVersion} technology to assist them in running the test suite
+that verifies compatibility of their implementation of the
+{TechnologyShortName} {TechnologyVersion} Specification.
+
+
+[[TCJRS00035]][[GBFPO]]
+
+
+[[before-you-read-this-book]]
+Before You Read This Book
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You should be familiar with the {TechnologyShortName}
+{TechnologyVersion}, version {TechnologyVersion} Specification, 
+which can be found at {SpecificationURL}.
+
+Before running the tests in the {TechnologyShortName} TCK, you should
+familiarize yourself with the JavaTest documentation which can be
+accessed at the
+link:https://wiki.openjdk.java.net/display/CodeTools/JT+Harness[JT Harness web site].
+
+[[TCJRS00036]][[GBFWF]]
+
+
+[[typographic-conventions]]
+Typographic Conventions
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The following table describes the typographic conventions that are used
+in this book.
+
+[width="100%",cols="15%,40%,45%",options="header",]
+|=======================================================================
+|Convention |Meaning |Example
+|*Boldface* |Boldface type indicates graphical user interface elements
+associated with an action, terms defined in text, or what you type,
+contrasted with onscreen computer output. a|
+From the *File* menu, select *Open Project*.
+
+A *cache* is a copy that is stored locally.
+
+`machine_name% *su*` +
+`Password:`
+
+|`Monospace` |Monospace type indicates the names of files and
+directories, commands within a paragraph, URLs, code in examples, text
+that appears on the screen, or text that you enter. a|
+Edit your `.login` file.
+
+Use `ls` `-a` to list all files.
+
+`machine_name% you have mail.`
+
+|_Italic_ |Italic type indicates book titles, emphasis, or placeholder
+variables for which you supply particular values. a|
+Read Chapter 6 in the _User's Guide_.
+
+Do _not_ save the file.
+
+The command to remove a file is `rm` _filename_.
+
+|=======================================================================
+
+
+[[TCJRS00037]][[FWBSD]]
+
+
+[[shell-prompts-in-command-examples]]
+Shell Prompts in Command Examples
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following table shows the default UNIX system prompt and superuser
+prompt for the C shell, Bourne shell, and Korn shell.
+
+[width="100%",cols="50%,50%",options="header",]
+|=====================================================
+|Shell |Prompt
+|C shell |`machine_name%`
+|C shell for superuser |`machine_name#`
+|Bourne shell and Korn shell |`$` +
+|Bourne shell and Korn shell for superuser |`#` +
+|Bash shell |`shell_name-shell_version$`
+|Bash shell for superuser |`shell_name-shell_version#`
+|=====================================================
+
+
+
diff --git a/tck/docs/userguide/src/main/jbake/content/rebuild.adoc b/tck/docs/userguide/src/main/jbake/content/rebuild.adoc
new file mode 100644
index 0000000..e4021cf
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/rebuild.adoc
@@ -0,0 +1,20 @@
+type=page
+status=published
+title=Appendix B: Rebuild Rules
+prev=faq.html
+~~~~~~
+include::attributes.conf[]
+
+Appendix B: Rebuild Rules
+=========================
+
+
+ifdef::rebuild[]
+include::rebuild.inc[]
+endif::rebuild[]
+ifndef::rebuild[]
+
+<<<
+Appendix B is not used for the {TechnologyShortName} TCK.
+
+endif::rebuild[]
diff --git a/tck/docs/userguide/src/main/jbake/content/rebuild.inc b/tck/docs/userguide/src/main/jbake/content/rebuild.inc
new file mode 100644
index 0000000..3582e35
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/rebuild.inc
@@ -0,0 +1,8 @@
+///////////////////////////////////////////////////////////////////////
+NOTE TO WRITERS:
+The following sections should be customized for the technology.
+See JAXRS UG for an example of this include file
+///////////////////////////////////////////////////////////////////////
+
+[[GCLIZ]]
+
diff --git a/tck/docs/userguide/src/main/jbake/content/req-software.inc b/tck/docs/userguide/src/main/jbake/content/req-software.inc
new file mode 100644
index 0000000..3f5b241
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/req-software.inc
@@ -0,0 +1,11 @@
+///////////////////////////////////////////////////////////////////////
+NOTE TO WRITERS:
+This is a list of software required in addition to the TCK and a Compatible Implementation(CI).
+For many Jakarta EE APIs, a Jakarta EE CI will be required, as described below.
+For standalone technologies, no other software may be required, and the
+below line can be removed.
+
+This is used in intro.adoc in section 1.3 and install.adoc in section 3.2.
+///////////////////////////////////////////////////////////////////////
+
+* A Jakarta EE 11 Compatible Implementation
diff --git a/tck/docs/userguide/src/main/jbake/content/rules.adoc b/tck/docs/userguide/src/main/jbake/content/rules.adoc
new file mode 100644
index 0000000..f6b08ce
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/rules.adoc
@@ -0,0 +1,403 @@
+type=page
+status=published
+title=Procedure for Certification
+next=install.html
+prev=intro.html
+~~~~~~
+include::attributes.conf[]
+Procedure for Certification
+===========================
+
+[[GBFSN]]
+
+
+[[procedure-for-certification]]
+2 Procedure for Certification
+-----------------------------
+
+This chapter describes the compatibility testing procedure and
+compatibility requirements for {TechnologyFullName}.
+This chapter contains the following sections:
+
+* link:#CJAFFDGI[Certification Overview]
+* link:#CJAFGIGG[Compatibility Requirements]
+* link:#CJAIIBDJ[Test Appeals Process]
+* link:#CJAJECIE[Specifications for {TechnologyFullName}]
+* link:#CJABAHGI[Libraries for {TechnologyFullName}]
+
+[[CJAFFDGI]][[certification-overview]]
+
+2.1 Certification Overview
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The certification process for {technologyShortName} {TechnologyVersion}
+consists of the following activities:
+
+* Install the appropriate version of the Technology Compatibility Kit
+(TCK) and execute it in accordance with the instructions in this User's
+Guide.
+* Ensure that you meet the requirements outlined in
+link:#CJAFGIGG[Compatibility Requirements] below.
+* Certify to the Eclipse Foundation that you have finished
+testing and that you meet all of the compatibility requirements,
+as required by the Eclipse Foundation TCK License.
+
+[[CJAFGIGG]][[compatibility-requirements]]
+
+2.2 Compatibility Requirements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The compatibility requirements for {TechnologyShortName}
+{TechnologyVersion} consist of meeting the requirements set forth by
+the rules and associated definitions contained in this section.
+
+[[sthref4]][[definitions]]
+
+2.2.1 Definitions
+^^^^^^^^^^^^^^^^^
+
+These definitions are for use only with these compatibility requirements
+and are not intended for any other purpose.
+
+[[sthref5]][[sthref6]]
+
+Table 2-1 Definitions 
+
+[width="100%",cols="25%,75%",options="header",]
+|=======================================================================
+|Term |Definition
+|API Definition Product |A Product for which the only Java class files
+contained in the product are those corresponding to the application
+programming interfaces defined by the Specifications, and which is
+intended only as a means for formally specifying the application
+programming interfaces defined by the Specifications.
+
+|Computational Resource a|
+A piece of hardware or software that may vary in quantity, existence, or
+version, which may be required to exist in a minimum quantity and/or at
+a specific or minimum revision level so as to satisfy the requirements
+of the Test Suite.
+
+Examples of computational resources that may vary in quantity are RAM
+and file descriptors.
+
+Examples of computational resources that may vary in existence (that is,
+may or may not exist) are graphics cards and device drivers.
+
+Examples of computational resources that may vary in version are
+operating systems and device drivers.
+
+|Configuration Descriptor |Any file whose format is well defined by a
+specification and which contains configuration information for a set of
+Java classes, archive, or other feature defined in the specification.
+
+|Conformance Tests |All tests in the Test Suite for an indicated
+Technology Under Test, as released and distributed by the 
+Eclipse Foundation, excluding those tests on the 
+published Exclude List for the Technology Under Test.
+
+|Container |An implementation of the associated Libraries, as specified
+in the Specifications, and a version of a Java Platform, Standard
+Edition Runtime Product, as specified in the Specifications, or a later
+version of a Java Platform, Standard Edition Runtime Product that also
+meets these compatibility requirements.
+
+|Documented |Made technically accessible and made known to users,
+typically by means such as marketing materials, product documentation,
+usage messages, or developer support programs.
+
+|Exclude List |The most current list of tests, released and distributed by the
+Eclipse Foundation, that are not required to be passed to certify
+conformance. The Jakarta EE Specification Committee may add to the Exclude List for that
+Test Suite as needed at any time, in which case the updated TCK version
+supplants any previous Exclude Lists for that Test Suite.
+
+|Libraries a|
+The class libraries, as specified through the Jakarta EE Specification Process
+(JESP), for the Technology Under Test.
+
+The Libraries for {TechnologyFullName} are listed at the end of this chapter.
+
+|Location Resource a|
+A location of classes or native libraries that are components of the
+test tools or tests, such that these classes or libraries may be
+required to exist in a certain location in order to satisfy the
+requirements of the test suite.
+
+For example, classes may be required to exist in directories named in a
+CLASSPATH variable, or native libraries may be required to exist in
+directories named in a PATH variable.
+
+|Maintenance Lead |The corresponding Jakarta EE Specification Project
+is responsible for maintaining the Specification, and the TCK for the
+Technology.  The Specification Project Team will propose revisions and
+updates to the Jakarta EE Specification Committee which will approve
+and release new versions of the specification and TCK.
+
+|Operating Mode a|
+Any Documented option of a Product that can be changed by a user in
+order to modify the behavior of the Product.
+
+For example, an Operating Mode can be binary (enable/disable
+optimization), an enumeration (select from a list of protocols), or a
+range (set the maximum number of active threads).
+
+Note that an Operating Mode may be selected by a command line switch, an
+environment variable, a GUI user interface element, a configuration or
+control file, etc.
+
+|Product |A vendor's product in which the Technology Under Test is
+implemented or incorporated, and that is subject to compatibility
+testing.
+
+|Product Configuration a|
+A specific setting or instantiation of an Operating Mode.
+
+For example, a Product supporting an Operating Mode that permits user
+selection of an external encryption package may have a Product
+Configuration that links the Product to that encryption package.
+
+|Rebuildable Tests |Tests that must be built using an
+implementation-specific mechanism. This mechanism must produce
+specification-defined artifacts. Rebuilding and running these tests
+against a known compatible implementation verifies that the mechanism generates
+compatible artifacts.
+
+|Resource |A Computational Resource, a Location Resource, or a Security
+Resource.
+
+|Rules |These definitions and rules in this Compatibility Requirements
+section of this User's Guide.
+
+|Runtime |The Containers specified in the Specifications.
+
+|Security Resource a|
+A security privilege or policy necessary for the proper execution of the
+Test Suite.
+
+For example, the user executing the Test Suite will need the privilege
+to access the files and network resources necessary for use of the
+Product.
+
+|Specifications a|
+The documents produced through the Jakarta EE Specification Process (JESP)
+that define a particular Version of a Technology.
+
+The Specifications for the Technology Under Test are referenced later in
+this chapter.
+
+|Technology |Specifications and one or more compatible implementations produced
+through the Jakarta EE Specification Process (JESP).
+
+|Technology Under Test |Specifications and a compatible implementation
+for {TechnologyFullName} Version {TechnologyVersion}.
+
+|Test Suite |The requirements, tests, and testing tools distributed by
+the Maintenance Lead as applicable to a given Version of the Technology.
+
+|Version |A release of the Technology, as produced through the
+Jakarta EE Specification Process (JESP).
+
+include::defns.inc[]
+|=======================================================================
+
+
+[[sthref7]][[rules-for-products]]
+
+2.2.2 Rules for {TechnologyFullName} Products
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following rules apply for each version of an operating system,
+software component, and hardware platform Documented as supporting the
+Product:
+
+*{techID}1* The Product must be able to satisfy all applicable compatibility
+requirements, including passing all Conformance Tests, in every Product
+Configuration and in every combination of Product Configurations, except
+only as specifically exempted by these Rules.
+
+For example, if a Product provides distinct Operating Modes to optimize
+performance, then that Product must satisfy all applicable compatibility
+requirements for a Product in each Product Configuration, and
+combination of Product Configurations, of those Operating Modes.
+
+*{techID}1.1* If an Operating Mode controls a Resource necessary for the
+basic execution of the Test Suite, testing may always use a Product
+Configuration of that Operating Mode providing that Resource, even if
+other Product Configurations do not provide that Resource.
+Notwithstanding such exceptions, each Product must have at least one set
+of Product Configurations of such Operating Modes that is able to pass
+all the Conformance Tests.
+
+For example, a Product with an Operating Mode that controls a security
+policy (i.e., Security Resource) which has one or more Product
+Configurations that cause Conformance Tests to fail may be tested using
+a Product Configuration that allows all Conformance Tests to pass.
+
+*{techID}1.2* A Product Configuration of an Operating Mode that causes the
+Product to report only version, usage, or diagnostic information is
+exempted from these compatibility rules.
+
+*{techID}1.3* An API Definition Product is exempt from all functional
+testing requirements defined here, except the signature tests.
+
+*{techID}2* Some Conformance Tests may have properties that may be changed.
+Properties that can be changed are identified in the configuration
+interview. Properties that can be changed are identified in the JavaTest
+Environment (.jte) files in the Test Suite
+installation. Apart from changing such properties and other allowed
+modifications described in this User's Guide (if any), no source or
+binary code for a Conformance Test may be altered in any way without
+prior written permission. Any such allowed alterations to the
+Conformance Tests will be provided via the Jakarta EE Specification Project 
+website and apply to all vendor compatible implementations.
+
+*{techID}3* The testing tools supplied as part of the Test Suite or as
+updated by the Maintenance Lead must be used to certify compliance.
+
+*{techID}4* The Exclude List associated with the Test Suite cannot be
+modified.
+
+*{techID}5* The Maintenance Lead can define exceptions to these Rules. Such
+exceptions would be made available as above, and will apply to all vendor implementations.
+
+*{techID}6* All hardware and software component additions, deletions, and
+modifications to a Documented supporting hardware/software platform,
+that are not part of the Product but required for the Product to satisfy
+the compatibility requirements, must be Documented and available to
+users of the Product.
+
+For example, if a patch to a particular version of a supporting
+operating system is required for the Product to pass the Conformance
+Tests, that patch must be Documented and available to users of the
+Product.
+
+*{techID}7* The Product must contain the full set of public and protected
+classes and interfaces for all the Libraries. Those classes and
+interfaces must contain exactly the set of public and protected methods,
+constructors, and fields defined by the Specifications for those
+Libraries. No subsetting, supersetting, or modifications of the public
+and protected API of the Libraries are allowed except only as
+specifically exempted by these Rules.
+
+*{techID}7.1* If a Product includes Technologies in addition to the
+Technology Under Test, then it must contain the full set of combined
+public and protected classes and interfaces. The API of the Product
+must contain the union of the included Technologies. No further
+modifications to the APIs of the included Technologies are allowed.
+
+ifdef::subset-allowed[]
+*{techID}7.2* The Product may contain a subset of the classes and
+interfaces for the Libraries.
+endif::subset-allowed[]
+
+*{techID}8* Except for tests specifically required by this TCK to be rebuilt
+(if any), the binary Conformance Tests supplied as part of the Test
+Suite or as updated by the Maintenance Lead must be used to certify
+compliance.
+
+*{techID}9* The functional programmatic behavior of any binary class or
+interface must be that defined by the Specifications.
+
+include::rules.inc[]
+
+[[CJAIIBDJ]][[test-appeals-process]]
+
+2.3 Test Appeals Process
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Jakarta has a well established process for managing challenges to its
+TCKs. Any implementor may submit a challenge to one or more tests in the
+{TechnologyShortName} TCK as it relates to their implementation.  Implementor
+means the entity as a whole in charge of producing the final certified release.
+*Challenges filed should represent the consensus of that entity*.
+
+2.3.1 Valid Challenges
+^^^^^^^^^^^^^^^^^^^^^^
+Any test case (e.g., test class, @Test method), test case configuration (e.g., deployment descriptor), test beans, annotations, and other resources considered part of the TCK may be challenged.
+
+The following scenarios are considered in scope for test challenges:
+
+* Claims that a test assertion conflicts with the specification.
+* Claims that a test asserts requirements over and above that of the specification.
+* Claims that an assertion of the specification is not sufficiently implementable.
+* Claims that a test is not portable or depends on a particular implementation.
+
+2.3.2 Invalid Challenges
+^^^^^^^^^^^^^^^^^^^^^^^^
+The following scenarios are considered out of scope for test challenges and will be immediately closed if filed:
+
+* Challenging an implementation’s claim of passing a test.  Certification is an honor system and these issues must be raised directly with the implementation.
+* Challenging the usefulness of a specification requirement.  The challenge process cannot be used to bypass the specification process and raise in question the need or relevance of a specification requirement.
+* Claims the TCK is inadequate or missing assertions required by the specification.  See the Improvement section, which is outside the scope of test challenges.
+* Challenges that do not represent a consensus of the implementing community will be closed until such time that the community does agree or agreement cannot be made.  The test challenge process is not the place for implementations to initiate their own internal discussions.
+* Challenges to tests that are already excluded for any reason.
+* Challenges that an excluded test should not have been excluded and should be re-added should be opened as a new enhancement request
+
+Test challenges must be made in writing via the {TechnologyShortName} specification project issue tracker
+as described in link:#CJAJEAEI[Section 2.3.3, "TCK Test Appeals Steps."]
+
+All tests found to be invalid will be placed on the Exclude List
+for that version of the {TechnologyShortName} TCK.
+
+
+[[CJAJEAEI]][[tck-test-appeals-steps]]
+
+2.3.3 TCK Test Appeals Steps
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+1. Challenges should be filed via the {TechnologyFullName} specification project’s issue tracker using the label `challenge` and include the following information:
+* The relevant specification version and section number(s)
+* The coordinates of the challenged test(s)
+* The exact TCK and exclude list versions
+* The implementation being tested, including name and company
+* The full test name
+* A full description of why the test is invalid and what the correct behavior is believed to be
+* Any supporting material; debug logs, test output, test logs, run scripts, etc.
+
+
+
+2. Specification project evaluates the challenge. +
+Challenges can be resolved by a specification project lead, or a project challenge triage team, after a consensus of the specification project committers is reached or attempts to gain consensus fails.
+Specification projects may exercise lazy consensus, voting or any practice that follows the principles of Eclipse Foundation Development Process.
+The expected timeframe for a response is two weeks or less.
+If consensus cannot be reached by the specification project for a prolonged period of time, the default recommendation is to exclude the tests and address the dispute in a future revision of the specification.
+
+3.  Accepted Challenges. +
+A consensus that a test produces invalid results will result in the exclusion of that test from certification requirements, and an immediate update and release of an official distribution of the TCK including the new exclude list. The associated `challenge` issue must be closed with an `accepted` label to indicate it has been resolved.
+
+4.  Rejected Challenges and Remedy. +
+When a`challenge` issue is rejected, it must be closed with a label of `invalid` to indicate it has been rejected.
+There appeal process for challenges rejected on technical terms is outlined in Escalation Appeal.
+If, however, an implementer feels the TCK challenge process was not followed, an appeal issue should be filed with specification project’s TCK issue tracker using the label `challenge-appeal`.
+A project lead should escalate the issue with the Jakarta EE Specification Committee via email (jakarta.ee-spec@eclipse.org).
+The committee will evaluate the matter purely in terms of due process.
+If the appeal is accepted, the original TCK challenge issue will be reopened and a label of `appealed-challenge` added, along with a discussion of the appeal decision, and the `challenge-appeal` issue with be closed.
+If the appeal is rejected, the `challenge-appeal` issue should closed with a label of `invalid`.
+
+5. Escalation Appeal. +
+If there is a concern that a TCK process issue has not been resolved satisfactorily, the
+https://www.eclipse.org/projects/dev_process/#6_5_Grievance_Handling[Eclipse Development Process Grievance Handling] procedure should be followed to escalate the resolution. Note that this is not a mechanism to attempt to handle implementation specific issues.
+
+
+[[CJAJECIE]][[specifications-for-technology]]
+
+2.4 Specifications for {TechnologyFullName}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The {TechnologyFullName} specification is available from the specification
+project web-site: {SpecificationURL}.
+
+[[CJABAHGI]][[libraries-for-technology]]
+
+2.5 Libraries for {TechnologyFullName}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following is a list of the packages comprising the required class
+libraries for {TechnologyShortName} {TechnologyVersion}:
+
+include::packages.inc[]
+
+For the latest list of packages, also see:
+
+{SpecificationURL}
diff --git a/tck/docs/userguide/src/main/jbake/content/rules.inc b/tck/docs/userguide/src/main/jbake/content/rules.inc
new file mode 100644
index 0000000..b5a250f
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/rules.inc
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////
+NOTE TO WRITERS:
+Most technologies will only need the compatibility rules in rules.adoc.
+Some technologies will need additional rules.  If they're needed,
+remove the comment block delimiters below and update the rules as
+appropriate.  You may need to adjust the rule numbers to avoid gaps.
+
+The first comment block below is additional rules needed by JPA.
+
+The second comment block below is additional rules needed by
+JSP and Servlet.  (And EJB, if it had a standalone TCK.)
+
+The third comment block below is additional rules that apply
+to any technology that defines deployment descriptors.
+
+The fourth comment block is special rules that apply only to JSP.
+
+NOTE: This set of examples is NOT complete, but should be.
+///////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+*{techID}10* The Runtime must report an error when processing a
+Configuration Descriptor that does not conform to the Specifications.
+
+*{techID}11* An error must be reported when processing a configuration
+descriptor that includes a Java Persistence QL expression that does not
+conform to the Specifications.
+
+*{techID}12* The presence of an XML comment in a Configuration
+Descriptor, when processed by the Runtime, must not cause the
+functional programmatic behavior of the Runtime to vary from the
+functional programmatic behavior of the Runtime in the absence of that
+comment.
+///////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+*{techID}10* Each Container must make technically accessible all Java SE
+Runtime interfaces and functionality, as defined by the Specifications,
+to programs running in the Container, except only as specifically
+exempted by these Rules.
+
+*{techID}10.1* Containers may impose security constraints, as defined by
+the Specifications.
+///////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+*{techID}11* A Deployment Tool must report an error when processing a
+Configuration Descriptor that does not conform to the Specifications.
+
+*{techID}12* The presence of an XML comment in a Configuration
+Descriptor, when processed by a Deployment Tool, must not cause the
+functional programmatic behavior of the Deployment Tool to vary from
+the functional programmatic behavior of the Deployment Tool in the
+absence of that comment.
+///////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+*{techID}11* A web Container must report an error, as defined by the
+Specifications, when processing a JSP Page that does not conform to the
+Specifications.
+
+*{techID}12* The presence of a Java language comment or Java language
+directive in a JSP Page that specifies ”java” as the scripting
+language, when processed by a web Container, must not cause the
+functional programmatic behavior of that JSP Page to vary from the
+functional programmatic behavior of that JSP Page in the absence of
+that Java language comment or Java language directive.
+
+*{techID}13* The contents of any fixed template data (defined by the
+Specifications) in a JSP Page, when processed by a web Container, must
+not affect the functional programmatic behavior of that JSP Page,
+except as defined by the Specifications.
+
+*{techID}14* The functional programmatic behavior of a JSP Page that
+specifies ”java” as the scripting language must be equivalent to the
+functional programmatic behavior of the JSP Page Implementation Class
+constructed from that JSP Page.
+///////////////////////////////////////////////////////////////////////
diff --git a/tck/docs/userguide/src/main/jbake/content/tck-packages.inc b/tck/docs/userguide/src/main/jbake/content/tck-packages.inc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/tck-packages.inc
diff --git a/tck/docs/userguide/src/main/jbake/content/title.adoc b/tck/docs/userguide/src/main/jbake/content/title.adoc
new file mode 100644
index 0000000..232172d
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/title.adoc
@@ -0,0 +1,42 @@
+type=page
+status=published
+title=TCK User's Guide for Technology Implementors
+next=preface.html
+prev=toc.html
+~~~~~~
+include::attributes.conf[]
+
+TCK User's Guide for {TechnologyFullName}, Release {TechnologyVersion} for Jakarta EE
+=====================================================================================
+
+[[eclipse-foundation]]
+Eclipse Foundation
+------------------
+
+Technology Compatibility Kit User's Guide for {TechnologyFullName}
+
+Release {TechnologyVersion} for Jakarta EE
+
+{ReleaseDate}
+
+[[sthref1]]
+
+'''''
+
+Technology Compatibility Kit User's Guide for {TechnologyFullName},
+Release {TechnologyVersion} for Jakarta EE
+
+Copyright © {CopyrightDates} Oracle and/or its affiliates. All rights reserved.
+
+This program and the accompanying materials are made available under
+the terms of the Eclipse Public License v. 2.0, which is available at
+http://www.eclipse.org/legal/epl-2.0.
+
+SPDX-License-Identifier: EPL-2.0
+
+Oracle and Java are registered trademarks of Oracle and/or its
+affiliates. Other names may be trademarks of their respective owners.
+
+include::title.inc[]
+
+
diff --git a/tck/docs/userguide/src/main/jbake/content/title.inc b/tck/docs/userguide/src/main/jbake/content/title.inc
new file mode 100644
index 0000000..25bf47e
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/title.inc
@@ -0,0 +1,11 @@
+///////////////////////////////////////////////////////////////////////
+NOTE TO WRITERS:
+This is included at the tail end of the Title page.
+The following section should be customized for the technology.
+This is provided to allow each technology to customize legacy acronym names
+that are used in this TCK. 
+Be sure to customize LegacyAcronym in attributes.conf
+Add additional lines as needed for acronyms found in your TCK user guide.
+///////////////////////////////////////////////////////////////////////
+
+References in this document to {LegacyAcronym} refer to the {TechnologyFullName} unless otherwise noted.
diff --git a/tck/docs/userguide/src/main/jbake/content/using-examples.inc b/tck/docs/userguide/src/main/jbake/content/using-examples.inc
new file mode 100644
index 0000000..d587183
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/using-examples.inc
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////
+NOTE TO WRITERS:
+These CLI examples can be customized as necessary.
+///////////////////////////////////////////////////////////////////////
+
+Start the Junit tests using the following command:
+
+--
+[source,oac_no_warn]
+----
+mvn verify
+----
+--
+
+
+[[GCMCU]]
+
+Example 5-1 {TechnologyShortName} TCK Signature Tests
+
+To run the {TechnologyShortName} TCK signature tests, use the 
+sigtest-maven-plugin in the TCK runner as below.
+
+=======================================================================
+<plugin>
+    <groupId>jakarta.tck</groupId>
+    <artifactId>sigtest-maven-plugin</artifactId>
+    <version>2.2</version>
+    <configuration>
+        <sigfile>path-to-sig-file-provided-with-TCK</sigfile>
+        <packages>jakarta.el</packages>
+        <classes>path-to-api-jar</classes>
+        <report>target/sig-report.txt</report>
+    </configuration>
+    <executions>
+        <execution>
+        <id>sigtest</id>
+        <goals>
+            <goal>check</goal>
+        </goals>
+        <phase>verify</phase>
+        </execution>
+    </executions>
+</plugin>
+=======================================================================
+
+[[GCMBV]]
+
+
+Example 5-2 Single Test Directory
+
+To run a single test directory, enter the following commands:
+
+[source,subs="attributes"]
+----
+mvn verify -Dit.test={singleTestDirectoryExample}.**
+----
+
+[[GCMCA]]
+
+
+Example 5-3 Subset of Test Directories
+
+To run a subset of test directories, enter the following commands:
+
+[source,subs="attributes"]
+----
+mvn verify -Dit.test={subsetTestDirectoryExample}.**
+----
diff --git a/tck/docs/userguide/src/main/jbake/content/using.adoc b/tck/docs/userguide/src/main/jbake/content/using.adoc
new file mode 100644
index 0000000..67cb0b0
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/using.adoc
@@ -0,0 +1,218 @@
+type=page
+status=published
+title=Executing Tests
+next=debug.html
+prev=config.html
+~~~~~~
+include::attributes.conf[]
+Executing Tests
+===============
+
+[[GBFWO]]
+
+
+[[executing-tests]]
+5 Executing Tests
+-----------------
+
+The {TechnologyShortName} TCK uses the Junit 
+framework to execute the tests.
+
+This chapter includes the following topics:
+
+* link:#GBFUZ[Starting the tests]
+* link:#GBFWM[Running a Subset of the Tests]
+* link:#GCLRR[Running the TCK Against your selected CI]
+* link:#GCLRZ[Running the TCK Against a Vendor's Implementation]
+* link:#GBFVK[Test Reports]
+
+
+[NOTE]
+=======================================================================
+
+The instructions in this chapter assume that you have installed and
+configured your test environment as described in
+link:install.html#GBFTP[Chapter 3, "Installation,"] and
+link:config.html#GBFVV[Chapter 4, "Setup and Configuration,"],
+respectively.
+
+=======================================================================
+
+ifdef::rebuild[]
+As explained in link:rebuild.html#GCLIZ[Appendix B, "Packaging the
+Test Applications in Servlet-Compliant WAR
+Files With VI-Specific Information,"] the {TechnologyShortName} TCK
+introduces the concept of repackaging the TCK tests.
+endif::rebuild[]
+
+[NOTE]
+=======================================================================
+
+The Jakarta Expression Language TCK is not depended on any particular build tool to 
+run the tests. It will be convenient and advisable to create a 
+Apache Maven project to setup and run the TCK. This chapter will 
+henceforth use instructions and steps to provide setup with Apache 
+Maven as a build tool.
+
+=======================================================================
+
+
+
+[[GBFUZ]][[starting-javatest]]
+
+5.1 Starting the tests
+~~~~~~~~~~~~~~~~~~~~~~
+
+The {TechnologyShortName} TCK can be run from the command line 
+in your shell environment by executing the TCK jar.
+
+
+[NOTE]
+=======================================================================
+
+The `mvn` command referenced in the following
+two procedures and elsewhere in this guide is the Apache Maven
+build tool, which will need to be downloaded separately.
+
+=======================================================================
+
+
+
+
+[[GBFVW]][[to-start-javatest-in-command-line-mode]]
+
+5.1.1 To Start Tests in Command-Line Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+include::using-examples.inc[]
+
+[[GBFWM]][[running-a-subset-of-the-tests]]
+
+5.2 Running a Subset of the Tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use the following modes to run a subset of the tests:
+
+* link:#GBFWK[Section 5.2.1, "To Run a Subset of Tests in Command-Line Mode"]
+
+
+[[GBFWK]][[to-run-a-subset-of-tests-in-command-line-mode]]
+
+5.2.1 To Run a Subset of Tests in Command-Line Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Start the test run by executing the following command: +
+
+[source,subs="attributes"]
+----
+mvn verify -Dit.test={subsetTestDirectoryExample}.**
+----
+
+The tests in the directory and its subdirectories are run.
+
+[NOTE]
+=======================================================================
+
+Currently there are no Junit test tags(groups) available in the TCK. 
+
+=======================================================================
+
+[[GBFQA]][[to-run-a-group-of-tests-in-command-line-mode]]
+
+5.2.2 To Run a Group of Tests in Command-Line Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Start the test run by executing the following command: +
+
+[source,subs="attributes"]
+----
+mvn verify -Dgroups={groupsExample}
+----
+
+Only the tests in the group +{groupsExample}+ is run. 
+Multiple groups can be separated by comma.
+
+
+[[GBFEP]][[to-exclude-a-group-of-tests-in-command-line-mode]]
+
+5.2.3 To Exclude a Group of Tests in Command-Line Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Start the test run by executing the following command: +
+
+[source,subs="attributes"]
+----
+mvn verify -DexcludedGroups={groupsExample}
+----
+
+The tests in the group +{groupsExample}+ is exclued from the run. 
+Multiple groups can be separated by comma.
+
+[[GBFVK]][[Running-Signature-Test]]
+
+5.3 Running Signature Test
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+sigtest-maven-plugin is used to run the EL signature test. Please refer the 
+sample provided in the platform TCK repository.
+
+[NOTE]
+=======================================================================
+
+Use below configuration while using sigtest-maven-plugin with goal as `check`.
+
+    <configuration>
+        <sigfile>path-to-sig-file-provided-with-TCK</sigfile>
+        <packages>jakarta.el</packages>
+        <classes><path-to-api-jar</classes>
+        <report>sig-report.txt</report>
+    </configuration>
+
+=======================================================================
+
+
+[[GCLRR]][[running-the-tck-against-the-ri]]
+
+5.4 Running the TCK Against another CI
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some test scenarios are designed to ensure that the configuration and deployment of
+all the prebuilt {TechnologyShortName} TCK tests against one Compatible
+Implementation are successful operating with other compatible implementations, and that the TCK is ready for
+compatibility testing against the Vendor and Compatible Implementations.
+
+1.  Verify that you have followed the configuration instructions in
+link:config.html#GBFVU[Section 4.1, "Configuring Your Environment to Run
+the TCK Against the Compatible Implementation."]
+2.  If required, verify that you have completed the steps in
+link:config.html#GCLIW[Section 4.3.2, "Deploying the Prebuilt Archives."]
+3.  Run the tests, as described in link:#GBFUZ[Section 5.1, "Starting
+the tests,"] and, if desired, link:#GBFWM[Section 5.2, "Running a Subset
+of the Tests."]
+
+[[GCLRZ]][[running-the-tck-against-a-vendors-implementation]]
+
+5.5 Running the TCK Against a Vendor's Implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This test scenario is one of the compatibility test phases that all
+Vendors must pass.
+
+1.  Verify that you have followed the configuration instructions in
+link:config.html#GCLHU[Section 4.2, "Configuring Your Environment to
+Repackage and Run the TCK Against the Vendor Implementation."]
+2.  If required, verify that you have completed the steps in
+link:config.html#GCLIL[Section 4.3.3, "Deploying the
+Test Applications Against the Vendor Implementation."]
+3.  Run the tests, as described in link:#GBFUZ[Section 5.1, "Starting
+the tests,"] and, if desired, link:#GBFWM[Section 5.2, "Running a Subset
+of the Tests."]
+
+[[GBFVK]][[test-reports]]
+
+5.6 Test Reports
+~~~~~~~~~~~~~~~~
+
+A set of report files is created for every test run. These report files
+can be found in the target directory that the test is run. After a test run is
+completed, the Junit framework writes  reports for the test run.
diff --git a/tck/docs/userguide/src/main/jbake/content/using.inc b/tck/docs/userguide/src/main/jbake/content/using.inc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/content/using.inc
diff --git a/tck/docs/userguide/src/main/jbake/jbake.properties b/tck/docs/userguide/src/main/jbake/jbake.properties
new file mode 100644
index 0000000..05c7056
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/jbake.properties
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+site.host=http://jbake.org
+render.tags=false
+render.sitemap=false
+render.archive=false
+render.feed=false
+render.index=false
+asciidoctor.option.safe=0
+asciidoctor.attributes.export=true
\ No newline at end of file
diff --git a/tck/docs/userguide/src/main/jbake/templates/footer.ftl b/tck/docs/userguide/src/main/jbake/templates/footer.ftl
new file mode 100644
index 0000000..746cbf1
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/templates/footer.ftl
@@ -0,0 +1,44 @@
+<#-- a footer template fragment included in the page template -->
+<hr />
+
+<table width="90%" id="bottom-nav" cellspacing="0" cellpadding="0">
+	<colgroup>
+		<col width="12%"/>
+		<col width="12%"/>
+		<col width="*"/>
+	</colgroup>
+	<tr>		
+	    <#if content.prev??>
+		<td align="left">
+		<a href="${content.prev}">
+			<span class=" vector-font"><i class="fa fa-arrow-circle-left" aria-hidden="true"></i></span>
+			<span style="position:relative;top:-2px;">Previous</span>
+		</a>
+		</td>
+		</#if>
+
+		<#if content.next??>
+		<td align="left">
+		<a href="${content.next}">
+			<span class="vector-font"><i class="fa fa-arrow-circle-right vector-font" aria-hidden="true"></i></span>
+			<span style="position:relative;top:-2px;">Next</span>
+		</a>
+		</td>
+		</#if>
+
+		<td align="right">
+		<a href="toc.html">
+			<span class="vector-font"><i class="fa fa-list vector-font" aria-hidden="true"></i></span>
+			<span style="position:relative;top:-2px;">Contents</span>
+		</a>
+		</td>
+	</tr>
+</table>
+
+<span id="copyright">
+		<img src="img/eclipse_foundation_logo_tiny.png" height="20px" alt="Eclipse Foundation Logo" align="top"/>&nbsp;			
+		<span >Copyright&nbsp;&copy;&nbsp;2017,&nbsp;2021&nbsp;Oracle&nbsp;and/or&nbsp;its&nbsp;affiliates.&nbsp;All&nbsp;rights&nbsp;reserved.</span>
+</span>
+
+</body>
+</html>
diff --git a/tck/docs/userguide/src/main/jbake/templates/header.ftl b/tck/docs/userguide/src/main/jbake/templates/header.ftl
new file mode 100644
index 0000000..50b72ae
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/templates/header.ftl
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<#-- a header template fragment included in the page template -->
+<html lang="en">
+  <head>
+    <meta charset="utf-8"/>
+    <title><#if (content.title)??><#escape x as x?xml>${content.title}</#escape></#if></title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link href="<#if (content.rootpath)??>${content.rootpath}<#else></#if>css/style.css" rel="stylesheet">
+    <script src="https://use.fontawesome.com/96c4d89611.js"></script>
+  </head>
+  <body>
+<table id="doc-title" cellspacing="0" cellpadding="0">
+  <tr>
+  <td align="left" valign="top">
+  <b>${content.title}</b><br />
+  </td>
+  </tr>
+</table>
+<hr />
+
+<table width="90%" id="top-nav" cellspacing="0" cellpadding="0">
+	<colgroup>
+		<col width="12%"/>
+		<col width="12%"/>
+		<col width="*"/>
+	</colgroup>
+	<tr>
+	    <#if content.prev??>
+		<td align="left">
+		<a href="${content.prev}">
+			<span class="vector-font"><i class="fa fa-arrow-circle-left" aria-hidden="true"></i></span>
+			<span style="position:relative;top:-2px;">Previous</span>
+		</a>
+		</td>
+	    </#if>
+
+	    <#if content.next??>
+		<td align="left">
+		<a href="${content.next}">
+			<span class=" vector-font"><i class="fa fa-arrow-circle-right vector-font" aria-hidden="true"></i></span>
+			<span style="position:relative;top:-2px;">Next</span>
+		</a>
+		</td>
+	    </#if>
+
+		<td align="right">
+		<a href="toc.html">
+			<span class=" vector-font"><i class="fa fa-list vector-font" aria-hidden="true"></i></span>
+			<span style="position:relative;top:-2px;">Contents</span>
+		</a>
+		</td>
+	</tr>
+</table>
+
diff --git a/tck/docs/userguide/src/main/jbake/templates/menu.ftl b/tck/docs/userguide/src/main/jbake/templates/menu.ftl
new file mode 100644
index 0000000..888c03d
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/templates/menu.ftl
@@ -0,0 +1 @@
+<#-- a menu bar template fragment included in the page template -->
\ No newline at end of file
diff --git a/tck/docs/userguide/src/main/jbake/templates/page.ftl b/tck/docs/userguide/src/main/jbake/templates/page.ftl
new file mode 100644
index 0000000..eca51db
--- /dev/null
+++ b/tck/docs/userguide/src/main/jbake/templates/page.ftl
@@ -0,0 +1,8 @@
+<#-- a top level page layout template -->
+
+<#include "header.ftl">
+<#include "menu.ftl">
+
+${content.body}
+
+<#include "footer.ftl">
\ No newline at end of file
diff --git a/tck/docs/userguide/src/theme/jakartaee-theme.yml b/tck/docs/userguide/src/theme/jakartaee-theme.yml
new file mode 100644
index 0000000..6092a2f
--- /dev/null
+++ b/tck/docs/userguide/src/theme/jakartaee-theme.yml
@@ -0,0 +1,299 @@
+#
+# Following is the asciidoctor-pdf default theme [1], with small
+# customizations, mostly for header and footer, marked "EE".
+#
+# [1] https://github.com/asciidoctor/asciidoctor-pdf/blob/master/data/themes/default-theme.yml
+#
+font:
+  catalog:
+    # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols
+    Noto Serif:
+      normal: notoserif-regular-subset.ttf
+      bold: notoserif-bold-subset.ttf
+      italic: notoserif-italic-subset.ttf
+      bold_italic: notoserif-bold_italic-subset.ttf
+    # M+ 1mn supports ASCII and the circled numbers used for conums
+    M+ 1mn:
+      normal: mplus1mn-regular-ascii-conums.ttf
+      bold: mplus1mn-bold-ascii.ttf
+      italic: mplus1mn-italic-ascii.ttf
+      bold_italic: mplus1mn-bold_italic-ascii.ttf
+    # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols
+    # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font
+    M+ 1p Fallback:
+      normal: mplus1p-regular-fallback.ttf
+      bold: mplus1p-regular-fallback.ttf
+      italic: mplus1p-regular-fallback.ttf
+      bold_italic: mplus1p-regular-fallback.ttf
+  fallbacks:
+    - M+ 1p Fallback
+page:
+  background_color: ffffff
+  layout: portrait
+  margin: [0.5in, 0.67in, 0.67in, 0.67in]
+  # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress
+  margin_inner: 0.75in
+  margin_outer: 0.59in
+  #size: A4                                     # EE
+  size: Letter                                  # EE
+base:
+  align: justify
+  # color as hex string (leading # is optional)
+  font_color: 333333
+  # color as RGB array
+  #font_color: [51, 51, 51]
+  # color as CMYK array (approximated)
+  #font_color: [0, 0, 0, 0.92]
+  #font_color: [0, 0, 0, 92%]
+  font_family: Noto Serif
+  # choose one of these font_size/line_height_length combinations
+  #font_size: 14
+  #line_height_length: 20
+  #font_size: 11.25
+  #line_height_length: 18
+  #font_size: 11.2
+  #line_height_length: 16
+  font_size: 10.5
+  #line_height_length: 15
+  # correct line height for Noto Serif metrics
+  line_height_length: 12
+  #font_size: 11.25
+  #line_height_length: 18
+  line_height: $base_line_height_length / $base_font_size
+  font_size_large: round($base_font_size * 1.25)
+  font_size_small: round($base_font_size * 0.85)
+  font_size_min: $base_font_size * 0.75
+  font_style: normal
+  border_color: eeeeee
+  border_radius: 4
+  border_width: 0.5
+# FIXME vertical_rhythm is weird; we should think in terms of ems
+#vertical_rhythm: $base_line_height_length * 2 / 3
+# correct line height for Noto Serif metrics (comes with built-in line height)
+vertical_rhythm: $base_line_height_length
+horizontal_rhythm: $base_line_height_length
+# QUESTION should vertical_spacing be block_spacing instead?
+vertical_spacing: $vertical_rhythm
+link:
+  font_color: 428bca
+# literal is currently used for inline monospaced in prose and table cells
+literal:
+  font_color: b12146
+  font_family: M+ 1mn
+menu_caret_content: " <font size=\"1.15em\"><color rgb=\"b12146\">\u203a</color></font> "
+heading:
+  align: left
+  #font_color: 181818
+  font_color: $base_font_color
+  font_family: $base_font_family
+  font_style: bold
+  # h1 is used for part titles (book doctype) or the doctitle (article doctype)
+  #h1_font_size: floor($base_font_size * 2.6) # EE
+  h1_font_size: floor($base_font_size * 2.5) # EE, squeeze title onto one line
+  # h2 is used for chapter titles (book doctype only)
+  h2_font_size: floor($base_font_size * 2.15)
+  h3_font_size: round($base_font_size * 1.7)
+  h4_font_size: $base_font_size_large
+  h5_font_size: $base_font_size
+  h6_font_size: $base_font_size_small
+  #line_height: 1.4
+  # correct line height for Noto Serif metrics (comes with built-in line height)
+  line_height: 1
+  margin_top: $vertical_rhythm * 0.4
+  margin_bottom: $vertical_rhythm * 0.9
+title_page:
+  align: right
+  logo:
+    top: 10%
+  title:
+    top: 55%
+    font_size: $heading_h1_font_size
+    font_color: 999999
+    line_height: 0.9
+  subtitle:
+    font_size: $heading_h3_font_size
+    font_style: bold_italic
+    line_height: 1
+  authors:
+    margin_top: $base_font_size * 1.25
+    font_size: $base_font_size_large
+    font_color: 181818
+  revision:
+    margin_top: $base_font_size * 1.25
+block:
+  margin_top: 0
+  margin_bottom: $vertical_rhythm
+caption:
+  align: left
+  font_size: $base_font_size * 0.95
+  font_style: italic
+  # FIXME perhaps set line_height instead of / in addition to margins?
+  margin_inside: $vertical_rhythm / 3
+  #margin_inside: $vertical_rhythm / 4
+  margin_outside: 0
+lead:
+  font_size: $base_font_size_large
+  line_height: 1.4
+abstract:
+  font_color: 5c6266
+  font_size: $lead_font_size
+  line_height: $lead_line_height
+  font_style: italic
+  first_line_font_style: bold
+  title:
+    align: center
+    font_color: $heading_font_color
+    font_family: $heading_font_family
+    font_size: $heading_h4_font_size
+    font_style: $heading_font_style
+admonition:
+  column_rule_color: $base_border_color
+  column_rule_width: $base_border_width
+  padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm]
+  #icon:
+  #  tip:
+  #    name: fa-lightbulb-o
+  #    stroke_color: 111111
+  #    size: 24
+  label:
+    text_transform: uppercase
+    font_style: bold
+blockquote:
+  font_color: $base_font_color
+  font_size: $base_font_size_large
+  border_color: $base_border_color
+  border_width: 5
+  # FIXME disable negative padding bottom once margin collapsing is implemented
+  padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2]
+  cite_font_size: $base_font_size_small
+  cite_font_color: 999999
+# code is used for source blocks (perhaps change to source or listing?)
+code:
+  font_color: $base_font_color
+  font_family: $literal_font_family
+  font_size: ceil($base_font_size)
+  padding: $code_font_size
+  line_height: 1.25
+  # line_gap is an experimental property to control how a background color is applied to an inline block element
+  line_gap: 3.8
+  background_color: f5f5f5
+  border_color: cccccc
+  border_radius: $base_border_radius
+  border_width: 0.75
+conum:
+  font_family: M+ 1mn
+  font_color: $literal_font_color
+  font_size: $base_font_size
+  line_height: 4 / 3
+example:
+  border_color: $base_border_color
+  border_radius: $base_border_radius
+  border_width: 0.75
+  background_color: ffffff
+  # FIXME reenable padding bottom once margin collapsing is implemented
+  padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm]
+image:
+  align: left
+prose:
+  margin_top: $block_margin_top
+  margin_bottom: $block_margin_bottom
+sidebar:
+  background_color: eeeeee
+  border_color: e1e1e1
+  border_radius: $base_border_radius
+  border_width: $base_border_width
+  # FIXME reenable padding bottom once margin collapsing is implemented
+  padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25]
+  title:
+    align: center
+    font_color: $heading_font_color
+    font_family: $heading_font_family
+    font_size: $heading_h4_font_size
+    font_style: $heading_font_style
+thematic_break:
+  border_color: $base_border_color
+  border_style: solid
+  border_width: $base_border_width
+  margin_top: $vertical_rhythm * 0.5
+  margin_bottom: $vertical_rhythm * 1.5
+description_list:
+  term_font_style: bold
+  term_spacing: $vertical_rhythm / 4
+  description_indent: $horizontal_rhythm * 1.25
+outline_list:
+  indent: $horizontal_rhythm * 1.5
+  #marker_font_color: 404040
+  # NOTE outline_list_item_spacing applies to list items that do not have complex content
+  item_spacing: $vertical_rhythm / 2
+table:
+  background_color: $page_background_color
+  #head_background_color: <hex value>
+  #head_font_color: $base_font_color
+  head_font_style: bold
+  #body_background_color: <hex value>
+  body_stripe_background_color: f9f9f9
+  foot_background_color: f0f0f0
+  border_color: dddddd
+  border_width: $base_border_width
+  cell_padding: 3
+toc:
+  indent: $horizontal_rhythm
+  line_height: 1.4
+  dot_leader:
+    #content: ". "
+    font_color: a9a9a9
+    #levels: 2 3
+# NOTE in addition to footer, header is also supported
+footer:
+  font_size: $base_font_size_small
+  # NOTE if background_color is set, background and border will span width of page
+  #border_color: dddddd                         # EE
+  #border_width: 0.25                           # EE
+  height: $base_line_height_length * 2.5
+  line_height: 1
+  padding: [$base_line_height_length / 2, 1, 0, 1]
+  vertical_align: top
+  #image_vertical_align: <alignment> or <number>
+  # additional attributes for content:
+  # * {page-count}
+  # * {page-number}
+  # * {document-title}
+  # * {document-subtitle}
+  # * {chapter-title}
+  # * {section-title}
+  # * {section-or-chapter-title}
+  recto:
+    #columns: "<50% =0% >50%"
+    right:
+      #content: '{page-number}'                 # EE
+      #content: '{section-or-chapter-title} | {page-number}'
+      #content: '{document-title} | {page-number}'
+      content: '{document-title}{nbsp}{nbsp}{nbsp} *{page-number}*' # EE
+    #center:
+    #  content: '{page-number}'
+    left:                                       # EE
+      content: '{status}'                       # EE
+  verso:
+    #columns: $footer_recto_columns
+    left:
+      #content: $footer_recto_right_content     # EE
+      #content: '{page-number} | {chapter-title}'
+      content: '*{page-number}* {nbsp}{nbsp}{nbsp}{document-title}' # EE
+    #center:
+    #  content: '{page-number}'
+    right:                                      # EE
+      content: '{status}'                       # EE
+header:                                         # EE
+  font_size: $base_font_size_small              # EE
+  border_color: dddddd                          # EE
+  border_width: 0.25                            # EE
+  height: $base_line_height_length * 2.5        # EE
+  line_height: 1                                # EE
+  padding: [$base_line_height_length / 2, 1, 0, 1] # EE
+  vertical_align: top                           # EE
+  recto:                                        # EE
+    right:                                      # EE
+      content: '{section-or-chapter-title}'     # EE
+  verso:                                        # EE
+    left:                                       # EE
+      content: '{section-or-chapter-title}'     # EE
diff --git a/tck/pom.xml b/tck/pom.xml
new file mode 100644
index 0000000..3731012
--- /dev/null
+++ b/tck/pom.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2024, 2025 Contributors to the Eclipse Foundation.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+     <parent>
+        <groupId>org.eclipse.ee4j</groupId>
+        <artifactId>project</artifactId>
+        <version>1.0.9</version>
+        <relativePath />
+    </parent>
+
+    <groupId>jakarta.tck</groupId>
+    <artifactId>jakarta-expression-language-tck</artifactId>
+    <version>6.1.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <name>Jakarta Expression Language TCK</name>
+    <description>Jakarta Expression Language TCK</description>
+
+    <properties>
+        <maven.compiler.release>17</maven.compiler.release>
+        <jakarta.jakartaee-bom.version>11.0.0-RC1</jakarta.jakartaee-bom.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.junit</groupId>
+                <artifactId>junit-bom</artifactId>
+                <version>5.11.4</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                 <groupId>jakarta.platform</groupId>
+                 <artifactId>jakarta.jakartaee-bom</artifactId>
+                 <version>${jakarta.jakartaee-bom.version}</version>
+                 <type>pom</type>
+                 <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>jakarta.el</groupId>
+            <artifactId>jakarta.el-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.tck</groupId>
+            <artifactId>sigtest-maven-plugin</artifactId>
+            <version>2.6</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${bundle-name}-${project.version}</finalName>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>com/</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>..</directory>
+                <includes>
+                    <include>LICENSE.md</include>
+                </includes>
+                <targetPath>META-INF</targetPath>
+            </resource>
+        </resources>
+
+        <plugins>
+            <!-- Sets minimal Maven version to 3.8.6 -->
+            <plugin>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>enforce-maven</id>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireMavenVersion>
+                                    <version>3.8.6</version>
+                                </requireMavenVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.13.0</version>
+                <configuration>
+                    <release>17</release>
+                </configuration>
+            </plugin>
+            
+            <!-- Configure the jar with the sources. -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar-no-fork</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- Create Javadoc for API jar -->
+            <plugin>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <doclint>none</doclint>
+                </configuration>
+            </plugin>
+
+            <!-- Generate a "consumer pom" for the generated jar -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>flatten-maven-plugin</artifactId>
+                <version>1.6.0</version>
+                <configuration>
+                    <flattenMode>ossrh</flattenMode>
+                </configuration>
+                <executions>
+                    <!-- enable flattening -->
+                    <execution>
+                        <id>flatten</id>
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>flatten</goal>
+                        </goals>
+                    </execution>
+                    <!-- ensure proper cleanup -->
+                    <execution>
+                        <id>flatten.clean</id>
+                        <phase>clean</phase>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>3.7.1</version>
+                <executions>
+                    <execution>
+                        <id>distribution</id>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <phase>package</phase>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>src/main/assembly/assembly.xml</descriptor>
+                            </descriptors>
+                            <escapeString>\</escapeString>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <finalName>${bundle-name}-${project.version}</finalName>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>EFTL</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <properties>
+                <bundle-name>jakarta-expression-language-tck</bundle-name>
+                <license>EFTL</license>
+            </properties>
+        </profile>
+        <profile>
+            <id>EPL</id>
+            <properties>
+                <bundle-name>expression-language-tck</bundle-name>
+                <license>EPL</license>
+            </properties>
+        </profile>
+        <profile>
+            <id>record-signature</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <properties>
+                <bundle-name>jakarta-expression-language-tck</bundle-name>
+                <license>EFTL</license>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>jakarta.tck</groupId>
+                        <artifactId>sigtest-maven-plugin</artifactId>
+                        <version>2.6</version>
+                        <configuration>
+                            <FileName>${project.build.directory}/jakarta.el.sig_${project.parent.version}</FileName>
+                            <packages>jakarta.el</packages>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>generate</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+    </profiles>
+
+</project>
diff --git a/tck/src/main/assembly/assembly.xml b/tck/src/main/assembly/assembly.xml
new file mode 100644
index 0000000..1992fc5
--- /dev/null
+++ b/tck/src/main/assembly/assembly.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+    <id>distribution</id>
+    <baseDirectory>el-tck</baseDirectory>
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <files>
+        <!-- license -->
+        <file>
+            <source>${project.basedir}/src/main/resources/LICENSE_${license}.md</source>
+            <destName>LICENSE.md</destName>
+        </file>
+        <file>
+            <source>${project.basedir}/src/main/resources/jakarta.el.sig_6.0</source>
+            <destName>jakarta.el.sig_6.0</destName>
+        </file>
+    </files>
+    <fileSets>
+        <fileSet>
+            <directory>${project.build.directory}</directory>
+            <outputDirectory>artifacts</outputDirectory>
+            <fileMode>755</fileMode>
+            <includes>
+                <include>**/*.jar</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/docs</directory>
+            <outputDirectory>docs</outputDirectory>
+            <fileMode>755</fileMode>
+            <includes>
+                <include>assertions</include>
+                <include>*.html</include>
+                <include>*.txt</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/docs/userguide/target/generated-docs</directory>
+            <outputDirectory>docs/pdf-usersguide</outputDirectory>
+            <fileMode>755</fileMode>
+            <includes>
+                <include>*.pdf</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/docs/userguide/target/staging</directory>
+            <outputDirectory>docs/html-usersguide</outputDirectory>
+            <fileMode>755</fileMode>
+            <includes>
+                <include>*.html</include>
+                <include>css/**</include>
+                <include>img/**</include>
+            </includes>
+        </fileSet>        
+    </fileSets>
+</assembly>
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/arrayelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/arrayelresolver/ELClientIT.java
new file mode 100644
index 0000000..78dd1aa
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/arrayelresolver/ELClientIT.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2009, 2024 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.arrayelresolver;
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ArrayELResolver;
+import jakarta.el.ELContext;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private static final String[] names = { "doug", "nick", "roger", "ryan",
+      "ed" };
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: arrayELResolverTest
+   * 
+   * @assertion_ids: EL:JAVADOC:1; EL:JAVADOC:3; EL:JAVADOC:4; EL:JAVADOC:5;
+   *                 EL:JAVADOC:6; EL:JAVADOC:7; EL:JAVADOC:8
+   * 
+   * @test_Strategy: Verify that API calls work as expected: arrayELResolver()
+   *                 getValue() getType() setValue() isReadOnly()
+   *                 getCommonPropertyType() getFeatureDescriptors()
+   */
+  @Test
+  public void arrayELResolverTest() throws Exception {
+
+    boolean pass;
+    StringBuffer buf = new StringBuffer();
+    String[] colors = { "red", "blue", "green" };
+
+    try {
+      ArrayELResolver arrayResolver = new ArrayELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, arrayResolver, colors,
+          Integer.valueOf(1), "yellow", buf, false);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: arrayELResolverNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:1; EL:JAVADOC:5; EL:JAVADOC:6; EL:JAVADOC:7;
+   *                 EL:JAVADOC:8; EL:JAVADOC:122; EL:JAVADOC:125;
+   *                 EL:JAVADOC:128; EL:JAVADOC:131
+   * 
+   * @test_Strategy: Verify that the following methods throw a
+   *                 NullPointerException, if context is null:
+   * 
+   *                 getValue() getType() setValue() isReadOnly()
+   */
+  @Test
+  public void arrayELResolverNPETest() throws Exception {
+
+    boolean pass;
+    StringBuffer buf = new StringBuffer();
+
+    ArrayELResolver resolver = new ArrayELResolver();
+
+    try {
+      pass = ResolverTest.testELResolverNPE(resolver, names, Integer.valueOf(1),
+          "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: arrayELResolverPNFETest
+   * 
+   * @assertion_ids: EL:JAVADOC:1; EL:JAVADOC:5; EL:JAVADOC:7; EL:JAVADOC:8;
+   *                 EL:JAVADOC:121; EL:JAVADOC:127; EL:JAVADOC:134
+   * 
+   * @test_Strategy: Verify that the following methods throw a
+   *                 PropertyNotFoundException, if the given index is out of
+   *                 bounds for this array :
+   * 
+   *                 getType() isReadOnly() setValue()
+   */
+  @Test
+  public void arrayELResolverPNFETest() throws Exception {
+
+    boolean pass;
+    StringBuffer buf = new StringBuffer();
+
+    ArrayELResolver resolver = new ArrayELResolver();
+    BareBonesELContext barebonesContext = new BareBonesELContext();
+    ELContext context = barebonesContext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverPNFE(context, resolver, names,
+          Integer.valueOf(10), buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: arrayELResolverIAETest
+   * 
+   * @assertion_ids: EL:JAVADOC:1; EL:JAVADOC:6; EL:JAVADOC:8; EL:JAVADOC:124;
+   *                 EL:JAVADOC:132
+   * 
+   * @test_Strategy: Verify that the following methods throw an
+   *                 IllegalArgumentException, if the property could not be
+   *                 coerced into an integer:
+   * 
+   *                 getValue() setValue()
+   */
+  @Test
+  public void arrayELResolverIAETest() throws Exception {
+
+    boolean pass;
+    StringBuffer buf = new StringBuffer();
+
+    ArrayELResolver resolver = new ArrayELResolver();
+    BareBonesELContext barebonesContext = new BareBonesELContext();
+    ELContext context = barebonesContext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverIAE(context, resolver, names, "GARBAGE",
+          "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.INFO, buf.toString());
+  }
+
+  /**
+   * @testName: arrayELResolverPNWETest
+   * 
+   * @assertion_ids: EL:JAVADOC:2; EL:JAVADOC:8; EL:JAVADOC:127; EL:JAVADOC:133
+   * 
+   * @test_Strategy: Verify that the single-parameter constructor for
+   *                 arrayELResolver can be used to construct a read-only
+   *                 resolver, and that the setValue() method throws a
+   *                 PropertyNotWritableException, if the resolver was
+   *                 constructed in read-only mode.
+   * 
+   *                 ArrayELResolver(boolean) setValue()
+   */
+  @Test
+  public void arrayELResolverPNWETest() throws Exception {
+
+    boolean pass;
+    StringBuffer buf = new StringBuffer();
+
+    ArrayELResolver resolver = new ArrayELResolver(true);
+    BareBonesELContext barebonesContext = new BareBonesELContext();
+    ELContext context = barebonesContext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverPNWE(context, resolver, names,
+          Integer.valueOf(1), "billy", buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /*
+   * @testName: arrayELResolverOBETest
+   * 
+   * @assertion_ids: EL:JAVADOC:1; EL:JAVADOC:6
+   * 
+   * @test_Strategy: Verify that if the index is out of bounds, null is
+   * returned.
+   * 
+   * getValue()
+   */
+  @Test
+  public void arrayELResolverOBETest() throws Exception {
+
+    boolean pass = true;
+
+    StringBuffer buf = new StringBuffer();
+
+    ArrayELResolver resolver = new ArrayELResolver();
+    BareBonesELContext barebonesContext = new BareBonesELContext();
+    ELContext context = barebonesContext.getELContext();
+
+    try {
+      Object value = resolver.getValue(context, names, Integer.valueOf(5));
+
+      if (value != null) {
+        pass = false;
+        buf.append("Expected Value: 'null'").append(ELTestUtil.NL)
+            .append("Received Value: ").append(value.toString());
+      }
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+  }
+
+  /*
+   * @testName: arrayELResolverCCETest
+   * 
+   * @assertion_ids: EL:JAVADOC:1; EL:JAVADOC:8; EL:JAVADOC:130
+   * 
+   * @test_Strategy: Verify that if the class of a specified object prevents it
+   * from being added to the array, a ClassCastException is thrown.
+   * 
+   * setValue()
+   */
+  @Test
+  public void arrayELResolverCCETest() throws Exception {
+
+    boolean pass = false;
+
+    ArrayELResolver resolver = new ArrayELResolver();
+    BareBonesELContext barebonesContext = new BareBonesELContext();
+    ELContext context = barebonesContext.getELContext();
+
+    try {
+      resolver.setValue(context, names, Integer.valueOf(1), Boolean.TRUE);
+
+    } catch (ClassCastException cce) {
+      pass = true;
+
+    } catch (Exception e) {
+      logger.log(Logger.Level.ERROR,
+          "Failed: Exception thrown but was not a " + "ClassCastException");
+      throw new Exception(e);
+    }
+
+    if (!pass) {
+      throw new Exception("Failed: No exception thrown.");
+    }
+  }
+
+
+  /*
+   * @testName: arrayELResolverLengthTest
+   * 
+   * @test_Strategy: Verify that the length of an array is available as a read-only property.
+   */
+  @Test
+  public void arrayELResolverLengthTest() throws Exception {
+
+    boolean pass;
+    StringBuffer buf = new StringBuffer();
+    String[] colors = { "red", "blue", "green" };
+
+    try {
+      ArrayELResolver arrayResolver = new ArrayELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, arrayResolver, colors,
+          "length", "3", buf, true);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/beanelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/beanelresolver/ELClientIT.java
new file mode 100644
index 0000000..9c72c12
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/beanelresolver/ELClientIT.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2009, 2024 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.beanelresolver;
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.SimpleBean;
+
+import jakarta.el.BeanELResolver;
+import jakarta.el.ELContext;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+import java.util.TimeZone;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private SimpleBean sb;
+
+  public ELClientIT(){
+    sb = new SimpleBean();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: beanELResolverTest
+   * 
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:11; EL:JAVADOC:12; EL:JAVADOC:13;
+   *                 EL:JAVADOC:14; EL:JAVADOC:15; EL:JAVADOC:16
+   * 
+   * @test_Strategy: Verify that API calls work as expected: beanELResolver()
+   *                 getValue() getType() setValue() isReadOnly()
+   *                 getCommonPropertyType() getFeatureDescriptors()
+   */
+  @Test
+  public void beanELResolverTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+    sb.setIntention("initial_setting");
+
+    try {
+      BeanELResolver beanResolver = new BeanELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, beanResolver, sb, "intention",
+          "ABC123", buf, false);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: beanELResolverDefaultMethodReadOnlyTest
+   * 
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:11; EL:JAVADOC:12; EL:JAVADOC:13;
+   *                 EL:JAVADOC:14; EL:JAVADOC:15; EL:JAVADOC:16
+   * 
+   * @test_Strategy: Verify that API calls work as expected when accessing
+   *                 read-only properties defined via a default interface method
+   */
+  @Test
+  public void beanELResolverDefaultMethodReadOnlyTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BeanELResolver beanResolver = new BeanELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, beanResolver, sb, "defaultRO",
+         "RO", buf, true);
+    } catch (Exception ex) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Test of a valid expression using a Bean with a read-only " +
+          "property implemented via default methods threw an Exception!" + ELTestUtil.NL +
+          "Received: " + ex.toString() + ELTestUtil.NL);
+
+      ex.printStackTrace();
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  
+  /**
+   * @testName: beanELResolverDefaultMethodReadWriteTest
+   * 
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:11; EL:JAVADOC:12; EL:JAVADOC:13;
+   *                 EL:JAVADOC:14; EL:JAVADOC:15; EL:JAVADOC:16
+   * 
+   * @test_Strategy: Verify that API calls work as expected when accessing
+   *                 writable properties defined via a default interface method
+   */
+  @Test
+  public void beanELResolverDefaultMethodReadWriteTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BeanELResolver beanResolver = new BeanELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, beanResolver, sb, "defaultRW",
+          "RW", buf, false);
+    } catch (Exception ex) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Test of a valid expression using a Bean with a read-write " +
+          "property implemented via default methods threw an Exception!" + ELTestUtil.NL +
+          "Received: " + ex.toString() + ELTestUtil.NL);
+
+      ex.printStackTrace();
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: beanELResolverInvokeTest
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:11; EL:JAVADOC:12; EL:JAVADOC:13;
+   *                 EL:JAVADOC:14; EL:JAVADOC:15; EL:JAVADOC:16; EL:JAVADOC:142
+   * @test_Strategy: Verify that API calls work as expected for
+   *                 BeanELResolver.invoke().
+   */
+  @Test
+  public void beanELResolverInvokeTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BeanELResolver beanResolver = new BeanELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      Class<?>[] types = { String.class, String.class };
+      String[] values = { "Doug", "Donahue" };
+
+      pass = ResolverTest.testELResolverInvoke(context, beanResolver, sb, "isName", types, values, Boolean.FALSE, buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  }// End beanELResolverInvokeTest
+
+  /**
+   * @testName: beanELResolverInvokeVoidTest
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:11; EL:JAVADOC:12; EL:JAVADOC:13;
+   *                 EL:JAVADOC:14; EL:JAVADOC:15; EL:JAVADOC:16
+   * @test_Strategy: Verify that the ELResolver.invoke() API calls work as
+   *                 expected when calling a method that returns void.
+   */
+  @Test
+  public void beanELResolverInvokeVoidTest() throws Exception {
+
+    boolean pass;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BeanELResolver beanResolver = new BeanELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      Class<?>[] types = { String.class, String.class };
+      String[] values = { "Peter", "Pan" };
+
+      Object result = beanResolver.invoke(context, sb, "setFullName", types,
+          values);
+
+      if (null == result) {
+        // validate the new values.
+        pass = ResolverTest.testELResolverInvoke(
+            context, beanResolver, sb, "isName", types, values, Boolean.FALSE, buf);
+      } else {
+        pass = false;
+        buf.append("Unexpected Value returned!" + ELTestUtil.NL
+            + "Expected: null" + ELTestUtil.NL + "Recieved: "
+            + result.getClass().getName());
+      }
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  }// End beanELResolverInvokeVoidTest
+
+  /**
+   * @testName: beanELResolverInvokeMNFETest
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:11; EL:JAVADOC:12; EL:JAVADOC:13;
+   *                 EL:JAVADOC:14; EL:JAVADOC:15; EL:JAVADOC:16; EL:JAVADOC:143
+   * @test_Strategy: Verify that the invoke() method throws
+   *                 MethodNotFoundException if no suitable method can be found.
+   */
+  @Test
+  public void beanELResolverInvokeMNFETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BeanELResolver beanResolver = new BeanELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      Class<?>[] types = { String.class, String.class };
+      String[] values = { "Doug", "Donahue" };
+
+      pass = ResolverTest.testELResolverInvoke(
+          context, beanResolver, sb, "bogus_Method", types, values, Boolean.TRUE, buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  }// End beanELResolverInvokeMNFETest
+
+  /**
+   * @testName: beanELResolverNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:13; EL:JAVADOC:14; EL:JAVADOC:15;
+   *                 EL:JAVADOC:16; EL:JAVADOC:136; EL:JAVADOC:139;
+   *                 EL:JAVADOC:145; EL:JAVADOC:148
+   * 
+   * @test_Strategy: Verify that the following methods throw a
+   *                 NullPointerException, if context is null:
+   * 
+   *                 getType() getValue() isReadOnly() setValue()
+   */
+  @Test
+  public void beanELResolverNPETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+    sb.setIntention("initial_setting");
+
+    BeanELResolver resolver = new BeanELResolver();
+
+    try {
+      pass = ResolverTest.testELResolverNPE(resolver, sb, "intention", "billy",
+          buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: beanELResolverPNFETest
+   * 
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:13; EL:JAVADOC:14; EL:JAVADOC:15;
+   *                 EL:JAVADOC:16; EL:JAVADOC:137; EL:JAVADOC:140;
+   *                 EL:JAVADOC:146; EL:JAVADOC:149
+   * 
+   * @test_Strategy: Verify that the following methods throw a
+   *                 PropertyNotFoundException, if the base is not null and the
+   *                 specified property does not exist.
+   * 
+   *                 getType() isReadOnly() setValue() getValue()
+   */
+  @Test
+  public void beanELResolverPNFETest() throws Exception {
+
+    boolean pass = true;
+
+    StringBuffer buf = new StringBuffer();
+    sb.setIntention("initial_setting");
+
+    BeanELResolver resolver = new BeanELResolver();
+    BareBonesELContext barebonesComtext = new BareBonesELContext();
+    ELContext context = barebonesComtext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverPNFE(context, resolver, sb,
+          "Bogus_Field", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: beanELResolverPNWETest
+   * 
+   * @assertion_ids: EL:JAVADOC:10; EL:JAVADOC:16; EL:JAVADOC:150
+   * 
+   * @test_Strategy: Verify that the single-parameter constructor for
+   *                 beanELResolver can be used to construct a read-only
+   *                 resolver, and that the setValue() method throws a
+   *                 PropertyNotWritableException, if the resolver was
+   *                 constructed in read-only mode.
+   * 
+   *                 BeanELResolver(boolean) setValue()
+   */
+  @Test
+  public void beanELResolverPNWETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    BeanELResolver resolver = new BeanELResolver(true);
+    BareBonesELContext barebonesComtext = new BareBonesELContext();
+    ELContext context = barebonesComtext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverPNWE(context, resolver, sb, "intention",
+          "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+  
+  /**
+   * @testName: beanELResolverMethodVisibilityTest
+   * 
+   * @test_Strategy: Verify that API calls work as expected for a property that is not visible via the implementing
+   *                 class (it is in an internal, non-exported class) but is visible via an interface method:
+   *                 beanELResolver() getValue() getType() setValue() isReadOnly() getCommonPropertyType()
+   *                 getFeatureDescriptors()
+   */
+  @Test
+  public void beanELResolverMethodVisibilityTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+    TimeZone tz = TimeZone.getDefault();
+    
+    try {
+      BeanELResolver beanResolver = new BeanELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, beanResolver, tz, "rawOffset", Integer.valueOf(0), buf, false);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/beannameelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/beannameelresolver/ELClientIT.java
new file mode 100644
index 0000000..902107a
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/beannameelresolver/ELClientIT.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.beannameelresolver;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.SimpleBean;
+
+import jakarta.el.BeanNameELResolver;
+import jakarta.el.BeanNameResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELManager;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: beanNameELResolverTest
+   * 
+   * @assertion_ids: EL:JAVADOC:152; EL:JAVADOC:153; EL:JAVADOC:154;
+   *                 EL:JAVADOC:155; EL:JAVADOC:158; EL:JAVADOC:161;
+   *                 EL:JAVADOC:164
+   * 
+   * @test_Strategy: Verify the following method calls work as expected:
+   *                 getValue() getType() setValue() isReadOnly()
+   *                 getCommonPropertyType() getFeatureDescriptors()
+   */
+  @Test
+  public void beanNameELResolverTest() throws Exception {
+    StringBuffer buf = new StringBuffer();
+    boolean pass = false;
+
+    ELManager elm = new ELManager();
+    BeanNameResolver bnr = new TCKBeanNameResolver();
+    BeanNameELResolver belr = new BeanNameELResolver(bnr);
+
+    elm.addBeanNameResolver(bnr);
+    elm.addELResolver(belr);
+    elm.defineBean("simpleBean", new SimpleBean());
+
+    ELContext context = elm.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolver(context, context.getELResolver(),
+          bnr.getBean("simpleBean"), "intention", "GOLDEN", buf, false);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+
+    logger.log(Logger.Level.INFO, buf.toString());
+  }
+
+  /**
+   * @testName: beanNameELResolverInvokeMNFETest
+   * 
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:11; EL:JAVADOC:12; EL:JAVADOC:13;
+   *                 EL:JAVADOC:14; EL:JAVADOC:15; EL:JAVADOC:16;
+   *                 EL:JAVADOC:143; EL:JAVADOC:237
+   * 
+   * @test_Strategy: Verify that the invoke() method throws
+   *                 MethodNotFoundException if no suitable method can be found.
+   */
+  @Test
+  public void beanNameELResolverInvokeMNFETest() throws Exception {
+    StringBuffer buf = new StringBuffer();
+    boolean pass = false;
+
+    ELManager elm = new ELManager();
+    BeanNameResolver bnr = new TCKBeanNameResolver();
+    BeanNameELResolver belr = new BeanNameELResolver(bnr);
+
+    elm.addBeanNameResolver(bnr);
+    elm.addELResolver(belr);
+    elm.defineBean("simpleBean", new SimpleBean());
+
+    ELContext context = elm.getELContext();
+
+    Class<?>[] types = { String.class, String.class };
+    String[] values = { "Doug", "Donahue" };
+
+    try {
+      pass = ResolverTest.testELResolverInvoke(context, context.getELResolver(),
+          new SimpleBean(), "bogue_method", types, values, true, buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.INFO, buf.toString());
+
+  }// End beanELResolverInvokeMNFETest
+
+  /**
+   * @testName: beanNameELResolverInvokeTest
+   * 
+   * @assertion_ids: EL:JAVADOC:9; EL:JAVADOC:11; EL:JAVADOC:12; EL:JAVADOC:13;
+   *                 EL:JAVADOC:14; EL:JAVADOC:15; EL:JAVADOC:16;
+   *                 EL:JAVADOC:142; EL:JAVADOC:199; EL:JAVADOC:200;
+   *                 EL:JAVADOC:202; EL:JAVADOC:203; EL:JAVADOC:236
+   * 
+   * @test_Strategy: Verify that API calls work as expected for
+   *                 BeanNameELResolver.invoke().
+   */
+  @Test
+  public void beanNameELResolverInvokeTest() throws Exception {
+    StringBuffer buf = new StringBuffer();
+    boolean pass = false;
+
+    ELManager elm = new ELManager();
+    BeanNameResolver bnr = new TCKBeanNameResolver();
+    BeanNameELResolver belr = new BeanNameELResolver(bnr);
+
+    elm.addBeanNameResolver(bnr);
+    elm.addELResolver(belr);
+    elm.defineBean("simpleBean", new SimpleBean());
+
+    ELContext context = elm.getELContext();
+
+    Class<?>[] types = { String.class, String.class };
+    String[] values = { "Doug", "Donahue" };
+
+    try {
+      pass = ResolverTest.testELResolverInvoke(context, context.getELResolver(),
+          new SimpleBean(), "isName", types, values, false, buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.INFO, buf.toString());
+
+  }// End beanELResolverInvokeTest
+
+  /**
+   * @testName: beanNameELResolverGetTypeNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:156
+   * 
+   * @test_Strategy: Validate a NullPointerException is thrown if context is
+   *                 null.
+   */
+  @Test
+  public void beanNameELResolverGetTypeNPETest() throws Exception {
+    BeanNameResolver bnr = new TCKBeanNameResolver();
+    BeanNameELResolver belr = new BeanNameELResolver(bnr);
+
+    ELTestUtil.checkForNPE(belr, "getType",
+        new Class<?>[] { ELContext.class, Object.class, Object.class },
+        new Object[] { null, "Ender", "Wiggins" });
+
+  }// End beanNameELResolverGetTypeNPETest
+
+  /**
+   * @testName: beanNameELResolverGetValueNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:159
+   * 
+   * @test_Strategy: Validate a NullPointerException is thrown if context is
+   *                 null.
+   */
+  @Test
+  public void beanNameELResolverGetValueNPETest() throws Exception {
+    BeanNameResolver bnr = new TCKBeanNameResolver();
+    BeanNameELResolver belr = new BeanNameELResolver(bnr);
+
+    ELTestUtil.checkForNPE(belr, "getValue",
+        new Class<?>[] { ELContext.class, Object.class, Object.class },
+        new Object[] { null, "Ender", "Wiggins" });
+
+  }// End beanNameELResolverGetValueNPETest
+
+  /**
+   * @testName: beanNameELResolverIsReadOnlyNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:162
+   * 
+   * @test_Strategy: Validate a NullPointerException is thrown if context is
+   *                 null.
+   */
+  @Test
+  public void beanNameELResolverIsReadOnlyNPETest() throws Exception {
+    BeanNameResolver bnr = new TCKBeanNameResolver();
+    BeanNameELResolver belr = new BeanNameELResolver(bnr);
+
+    ELTestUtil.checkForNPE(belr, "isReadOnly",
+        new Class<?>[] { ELContext.class, Object.class, Object.class },
+        new Object[] { null, "Ender", "Wiggins" });
+
+  }// End beanNameELResolverIsReadOnlyNPETest
+
+  /**
+   * @testName: beanNameELResolverSetValueNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:165
+   * 
+   * @test_Strategy: Validate a NullPointerException is thrown if context is
+   *                 null.
+   */
+  @Test
+  public void beanNameELResolverSetValueNPETest() throws Exception {
+    BeanNameResolver bnr = new TCKBeanNameResolver();
+    BeanNameELResolver belr = new BeanNameELResolver(bnr);
+
+    ELTestUtil.checkForNPE(belr, "setValue",
+        new Class<?>[] { ELContext.class, Object.class, Object.class,
+            Object.class },
+        new Object[] { null, "Ender", "Valintine", "Wiggins" });
+
+  }// End beanNameELResolverSetValueNPETest
+
+  // -------------------------------------------- private classes
+
+  private static class TCKBeanNameResolver extends BeanNameResolver {
+
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/compositeelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/compositeelresolver/ELClientIT.java
new file mode 100644
index 0000000..8a01bed
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/compositeelresolver/ELClientIT.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.compositeelresolver;
+
+import java.util.Properties;
+
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.SimpleBean;
+
+import jakarta.el.ArrayELResolver;
+import jakarta.el.BeanELResolver;
+import jakarta.el.CompositeELResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELManager;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private static final String[] names = { "doug", "nick", "roger", "ryan",
+      "ed" };
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: compositeELResolverTest
+   * 
+   * @assertion_ids: EL:JAVADOC:24; EL:JAVADOC:25; EL:JAVADOC:26; EL:JAVADOC:27;
+   *                 EL:JAVADOC:28; EL:JAVADOC:29; EL:JAVADOC:30; EL:JAVADOC:31;
+   *                 EL:JAVADOC:34
+   * 
+   * @test_Strategy: Verify that API calls work as expected:
+   *                 CompositeELResolver() add() getValue() getType() setValue()
+   *                 isReadOnly() getCommonPropertyType()
+   *                 getFeatureDescriptors() ELContext.getELResolver()
+   */
+  @Test
+  public void compositeELResolverTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BareBonesELContext compContext = new BareBonesELContext();
+      ELContext context = compContext.getELContext();
+
+      // Create the CompositeELResolver.
+      CompositeELResolver compResolver = (CompositeELResolver) context
+          .getELResolver();
+
+      pass = ResolverTest.testCompositeELResolver(context, compResolver, buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: compositeELResolverInvokeTest
+   * 
+   * @assertion_ids: EL:JAVADOC:24; EL:JAVADOC:25; EL:JAVADOC:181
+   * 
+   * @test_Strategy: Verify that API calls work as expected for
+   *                 BeanELResolver.invoke().
+   */
+  @Test
+  public void compositeELResolverInvokeTest() throws Exception {
+    SimpleBean sb = new SimpleBean();
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BeanELResolver beanResolver = new BeanELResolver();
+      ELManager elm = new ELManager();
+      ELContext context = elm.getELContext();
+
+      // Create the CompositeELResolver.
+      CompositeELResolver compResolver = (CompositeELResolver) context
+          .getELResolver();
+
+      compResolver.add(beanResolver);
+
+      Class<?>[] types = { String.class, String.class };
+      String[] values = { "Doug", "Donahue" };
+
+      pass = ResolverTest.testELResolverInvoke(context, compResolver, sb,
+          "isName", types, values, false, buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  }// End beanELResolverInvokeTest
+
+  /**
+   * @testName: compositeELResolverAddNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:24; EL:JAVADOC:25; EL:JAVADOC:174
+   * 
+   * @test_Strategy: Verify that the CompositeELResolver.add method throws a
+   *                 NullPointerException if the provided resolver is null.
+   */
+  @Test
+  public void compositeELResolverAddNPETest() throws Exception {
+
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BareBonesELContext compContext = new BareBonesELContext();
+      ELContext context = compContext.getELContext();
+      CompositeELResolver compResolver = (CompositeELResolver) context
+          .getELResolver();
+
+      compResolver.add(null);
+
+      buf.append(ELTestUtil.NL + "Tested Failed, CompositeResolver.add(), "
+          + "should have thrown NullPointerException!");
+      pass = false;
+
+    } catch (NullPointerException npe) {
+      logger.log(Logger.Level.INFO, "Expected Exception thrown, when providing a"
+          + " null resolver to Composite.add()");
+
+    } catch (Exception e) {
+      buf.append("test failed with: " + ELTestUtil.NL + "EXPECTED: "
+          + "NullPointerException to be thrown " + ELTestUtil.NL
+          + "RECEIVED: " + e.toString() + "" + ELTestUtil.NL);
+      pass = false;
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: compositeELResolverNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:25; EL:JAVADOC:26; EL:JAVADOC:27; EL:JAVADOC:28;
+   *                 EL:JAVADOC:29; EL:JAVADOC:30; EL:JAVADOC:31;
+   *                 EL:JAVADOC:175; EL:JAVADOC:178; EL:JAVADOC:175;
+   *                 EL:JAVADOC:182; EL:JAVADOC:185
+   * 
+   * @test_Strategy: Verify that API calls work as expected: getValue()
+   *                 getType() setValue() isReadOnly() getCommonPropertyType()
+   *                 getFeatureDescriptors()
+   */
+  @Test
+  public void compositeELResolverNPETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BareBonesELContext compContext = new BareBonesELContext();
+      ELContext context = compContext.getELContext();
+
+      // Create dummy ELResolvers to populate the CompositeELResolver.
+      ArrayELResolver aResolver = new ArrayELResolver();
+      BeanELResolver bResolver = new BeanELResolver();
+
+      // Create the CompositeELResolver & add the dummy ELResolvers to it.
+      CompositeELResolver compResolver = (CompositeELResolver) context
+          .getELResolver();
+      compResolver.add(aResolver);
+      compResolver.add(bResolver);
+
+      pass = ResolverTest.testELResolverNPE(compResolver, names,
+          Integer.valueOf(2), "steve", buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: compositeELResolverPNFETest
+   * 
+   * @assertion_ids: EL:JAVADOC:25; EL:JAVADOC:28; EL:JAVADOC:30; EL:JAVADOC:31;
+   *                 EL:JAVADOC:176; EL:JAVADOC:179; EL:JAVADOC:183;
+   *                 EL:JAVADOC:186
+   * 
+   * @test_Strategy: Verify that API calls throw PropertyNotFoundException as
+   *                 expected: getType() setValue() isReadOnly()
+   */
+  @Test
+  public void compositeELResolverPNFETest() throws Exception {
+
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BareBonesELContext compContext = new BareBonesELContext();
+      ELContext context = compContext.getELContext();
+
+      // Create an ArrayELResolver to populate the CompositeELResolver.
+      ArrayELResolver aResolver = new ArrayELResolver();
+
+      // Create the CompositeELResolver & add the ELResolver to it.
+      CompositeELResolver compResolver = (CompositeELResolver) context
+          .getELResolver();
+      compResolver.add(aResolver);
+
+      pass = ResolverTest.testELResolverPNFE(context, compResolver, names,
+          Integer.valueOf(10), buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: compositeELResolverPNWETest
+   * 
+   * @assertion_ids: EL:JAVADOC:25; EL:JAVADOC:187
+   * 
+   * @test_Strategy: Verify that the setValue() method throws a
+   *                 PropertyNotWritableException, if the resolver was
+   *                 constructed in read-only mode.
+   * 
+   *                 setValue()
+   */
+  @Test
+  public void compositeELResolverPNWETest() throws Exception {
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+    SimpleBean sb = new SimpleBean();
+
+    BareBonesELContext compContext = new BareBonesELContext();
+    ELContext context = compContext.getELContext();
+
+    // Create an ArrayELResolver to populate the CompositeELResolver.
+    BeanELResolver resolver = new BeanELResolver(true);
+
+    // Create the CompositeELResolver & add the ELResolver to it.
+    CompositeELResolver compResolver = (CompositeELResolver) context
+        .getELResolver();
+    compResolver.add(resolver);
+
+    try {
+      pass = ResolverTest.testELResolverPNWE(context, resolver, sb, "intention",
+          "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elcontext/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elcontext/ELClientIT.java
new file mode 100644
index 0000000..92894bd
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elcontext/ELClientIT.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.elcontext;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+
+
+
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELManager;
+import jakarta.el.EvaluationListener;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: elContextPutGetContextTest
+   * @assertion_ids: EL:JAVADOC:33; EL:JAVADOC:39; EL:JAVADOC:328;
+   *                 EL:JAVADOC:326; EL:JAVADOC:321
+   * @test_Strategy: Assert that we get back the expected value from
+   *                 getContext() that we put in with putContext().
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elContextPutGetContextTest() throws Exception {
+    ELManager elm = new ELManager();
+    ELContext elc = elm.getELContext();
+    String testStr = "TCKContext";
+
+    elc.putContext(String.class, testStr);
+    String result = elc.getContext(String.class).toString();
+
+    if (!testStr.equals(result)) {
+      throw new Exception(ELTestUtil.FAIL + " Unexpected Context Returned!"
+          + ELTestUtil.NL + "Expected: " + testStr + ELTestUtil.NL
+          + "Received: " + result);
+    }
+
+  } // end elContextPutGetContextTest
+
+  /**
+   * @testName: elContextGetSetLocaleTest
+   * @assertion_ids: EL:JAVADOC:36; EL:JAVADOC:40; EL:JAVADOC:328;
+   *                 EL:JAVADOC:329
+   * @test_Strategy: Assert that we get back the Locale we set.
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elContextGetSetLocaleTest() throws Exception {
+    ELManager elm = new ELManager();
+    ELContext elc = elm.getELContext();
+
+    String disName = "english";
+    Locale en = new Locale(disName);
+    elc.setLocale(en);
+    String result = elc.getLocale().getDisplayName();
+
+    if (!result.equalsIgnoreCase(disName)) {
+      throw new Exception(ELTestUtil.FAIL + " Unexpected Locale Returned!"
+          + ELTestUtil.NL + "Expected: " + disName + ELTestUtil.NL
+          + "Received: " + result);
+    }
+
+  } // end elContextGetSetLocaleTest
+
+  /**
+   * @testName: elContextIsSetPropertyResolvedTest
+   * @assertion_ids: EL:JAVADOC:38; EL:JAVADOC:41; EL:JAVADOC:328;
+   *                 EL:JAVADOC:329; EL:JAVADOC:322
+   * @test_Strategy: Assert that when we call setPropertyResolved that
+   *                 isPropertyResolved returns true.
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elContextIsSetPropertyResolvedTest() throws Exception {
+    ELManager elm = new ELManager();
+    ELContext elc = elm.getELContext();
+
+    boolean isProp = elc.isPropertyResolved();
+
+    if (isProp) {
+      throw new Exception(
+          ELTestUtil.FAIL + " Unexpected result from isPropertyResolved()!"
+              + ELTestUtil.NL + "Should have been false!");
+    }
+
+    elc.setPropertyResolved(true);
+    isProp = elc.isPropertyResolved();
+
+    if (!isProp) {
+      throw new Exception(
+          ELTestUtil.FAIL + " Unexpected result from isPropertyResolved()!"
+              + ELTestUtil.NL + "Should have been true!");
+    }
+
+  } // end elContextIsSetPropertyResolvedTest
+
+  /**
+   * @testName: elContextPutContextNPETest
+   * @assertion_ids: EL:JAVADOC:33; EL:JAVADOC:198; EL:JAVADOC:328;
+   *                 EL:JAVADOC:329; EL:JAVADOC:327
+   * @test_Strategy: Validate that a NullPointerException is thrown if Class is
+   *                 null or Object is null.
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elContextPutContextNPETest() throws Exception {
+    ELManager elm = new ELManager();
+    ELContext elc = elm.getELContext();
+
+    logger.log(Logger.Level.INFO, "Testing: ELContext.putContext(String.class, null)");
+    ELTestUtil.checkForNPE(elc, "putContext",
+        new Class<?>[] { Class.class, Object.class },
+        new Object[] { String.class, null });
+
+    logger.log(Logger.Level.INFO, "Testing: ELContext.putContext(null, testStrg)");
+    ELTestUtil.checkForNPE(elc, "putContext",
+        new Class<?>[] { Class.class, Object.class },
+        new Object[] { String.class, null });
+
+  } // end elContextPutContextNPETest
+
+  /**
+   * @testName: elContextGetContextNPETest
+   * @assertion_ids: EL:JAVADOC:33; EL:JAVADOC:194; EL:JAVADOC:328;
+   *                 EL:JAVADOC:329; EL:JAVADOC:321
+   * @test_Strategy: Validate that a NullPointerException is thrown if key is
+   *                 null.
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elContextGetContextNPETest() throws Exception {
+    ELManager elm = new ELManager();
+    ELContext elc = elm.getELContext();
+
+    logger.log(Logger.Level.INFO, "Testing: ELContext.getContext(null)");
+    ELTestUtil.checkForNPE(elc, "getContext", new Class<?>[] { Class.class },
+        new Object[] { null });
+
+  } // end elContextGetContextNPETest
+
+  /**
+   * @testName: elContextAddGetListenersTest
+   * @assertion_ids: EL:JAVADOC:33; EL:JAVADOC:191; EL:JAVADOC:197;
+   *                 EL:JAVADOC:328; EL:JAVADOC:329
+   * @test_Strategy: Validate that a NullPointerException is thrown if key is
+   *                 null.
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elContextAddGetListenersTest() throws Exception {
+    ELManager elm = new ELManager();
+    ELContext elc = elm.getELContext();
+
+    EvaluationListener listenerOne = new TCKEvalListener();
+    EvaluationListener listenerTwo = new TCKEvalListener();
+
+    elc.addEvaluationListener(listenerOne);
+    elc.addEvaluationListener(listenerTwo);
+
+    List<EvaluationListener> listeners = elc.getEvaluationListeners();
+
+    if (!(listeners.contains(listenerOne) && listeners.contains(listenerTwo))) {
+      throw new Exception(
+          ELTestUtil.FAIL + " Was unable to find test listeners in List "
+              + "returned form " + "ElContext.getListeners()!");
+    }
+
+  } // end elContextAddGetListenersTest
+
+  // ---------------------------------------------- private classes
+
+  private static class TCKEvalListener extends EvaluationListener {
+    // do nothing this is just for test purposes.
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elprocessor/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elprocessor/ELClientIT.java
new file mode 100644
index 0000000..1897942
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elprocessor/ELClientIT.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.elprocessor;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELProcessor;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: elProcessorDefineFunctionNPETest
+   * @assertion_ids: EL:JAVADOC:220; EL:JAVADOC:216; EL:JAVADOC:219
+   * @test_Strategy: Assert that a NullPointerException is thrown if any of the
+   *                 arguments is null.
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elProcessorDefineFunctionNPETest() throws Exception {
+    ELProcessor elp = new ELProcessor();
+
+    Method meth;
+    try {
+      meth = elp.getClass().getMethod("toString", new Class<?>[] {});
+
+      // Tests for defineFunction(String, String, Method)
+      logger.log(Logger.Level.INFO, 
+          "Testing: ELProcessor.defineFunction(null, " + "function, meth)");
+      ELTestUtil.checkForNPE(elp, "defineFunction",
+          new Class<?>[] { String.class, String.class, Method.class },
+          new Object[] { null, "function", meth });
+
+      logger.log(Logger.Level.INFO, 
+          "Testing: ELProcessor.defineFunction(prefix, " + "null, meth)");
+      ELTestUtil.checkForNPE(elp, "defineFunction",
+          new Class<?>[] { String.class, String.class, Method.class },
+          new Object[] { "prefix", null, meth });
+
+      logger.log(Logger.Level.INFO, 
+          "Testing: ELProcessor.defineFunction(prefix, " + "function, null)");
+      ELTestUtil.checkForNPE(elp, "defineFunction",
+          new Class<?>[] { String.class, String.class, Method.class },
+          new Object[] { "prefix", "function", null });
+
+      // Tests for defineFunction(String, String, String, String)
+      logger.log(Logger.Level.INFO, "Testing: ELProcessor.defineFunction(prefix, "
+          + "function, className, null)");
+      ELTestUtil.checkForNPE(elp, "defineFunction",
+          new Class<?>[] { String.class, String.class, String.class,
+              String.class },
+          new Object[] { "prefix", "function", "className", null });
+
+      logger.log(Logger.Level.INFO, "Testing: ELProcessor.defineFunction(prefix, "
+          + "function, null, method)");
+      ELTestUtil.checkForNPE(elp, "defineFunction",
+          new Class<?>[] { String.class, String.class, String.class,
+              String.class },
+          new Object[] { "prefix", "function", null, "method" });
+
+      logger.log(Logger.Level.INFO, "Testing: ELProcessor.defineFunction(prefix, "
+          + "null, className, method)");
+      ELTestUtil.checkForNPE(elp, "defineFunction",
+          new Class<?>[] { String.class, String.class, String.class,
+              String.class },
+          new Object[] { "prefix", null, "className", "method" });
+
+      logger.log(Logger.Level.INFO, "Testing: ELProcessor.defineFunction(null, "
+          + "function, className, method)");
+      ELTestUtil.checkForNPE(elp, "defineFunction",
+          new Class<?>[] { String.class, String.class, String.class,
+              String.class },
+          new Object[] { null, "function", "className", "method" });
+
+    } catch (SecurityException e) {
+      e.printStackTrace();
+
+    } catch (NoSuchMethodException nsme) {
+      nsme.printStackTrace();
+    }
+
+  } // end elProcessorDefineFunctionNPETest
+
+  /**
+   * @testName: elProcessorDefineFunctionCNFETest
+   * @assertion_ids: EL:JAVADOC:220; EL:JAVADOC:214; EL:JAVADOC:217
+   * @test_Strategy: Assert that a ClassNotFoundException if the specified class
+   *                 does not exists.
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elProcessorDefineFunctionCNFETest() throws Exception {
+    ELProcessor elp = new ELProcessor();
+
+    logger.log(Logger.Level.INFO, "Testing: ELProcessor.defineFunction(null, "
+        + "function, className, method)");
+    ELTestUtil.checkForCNFE(elp, "defineFunction",
+        new Class<?>[] { String.class, String.class, String.class,
+            String.class },
+        new Object[] { "prefix", "function", "bogus", "method" });
+
+  } // end elProcessorDefineFunctionCNFETest
+
+  /**
+   * @testName: elProcessorDefineFunctionNSMETest
+   * @assertion_ids: EL:JAVADOC:220; EL:JAVADOC:215
+   * @test_Strategy: Assert that a NoSuchMethodException if the method (with or
+   *                 without the signature) is not a declared method of the
+   *                 class, or if the method signature is not valid.
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elProcessorDefineFunctionNSMETest() throws Exception {
+    ELProcessor elp = new ELProcessor();
+
+    logger.log(Logger.Level.INFO, "Testing: ELProcessor.defineFunction(null, "
+        + "function, className, method)");
+    ELTestUtil.checkForCNFE(elp, "defineFunction",
+        new Class<?>[] { String.class, String.class, String.class,
+            String.class },
+        new Object[] { "prefix", "function", "java.util.String", "bogus" });
+
+  } // end elProcessorDefineFunctionNSMETest
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elresolver/ELClientIT.java
new file mode 100644
index 0000000..dd42d03
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/elresolver/ELClientIT.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.elresolver;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.elcontext.BarELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.SimpleBean;
+
+import jakarta.el.ArrayELResolver;
+import jakarta.el.BeanELResolver;
+import jakarta.el.CompositeELResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELManager;
+import jakarta.el.ELResolver;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private static final String[] names = { "doug", "nick", "roger", "ryan",
+      "ed" };
+
+  
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: elResolverTest
+   * 
+   * @assertion_ids: EL:JAVADOC:50; EL:JAVADOC:51; EL:JAVADOC:52; EL:JAVADOC:53;
+   *                 EL:JAVADOC:54; EL:JAVADOC:55; EL:JAVADOC:229
+   * 
+   * @test_Strategy: Create an ELContext and get its ELResolver. Verify that API
+   *                 calls work as expected: getValue() getType() setValue()
+   *                 isReadOnly() getCommonPropertyType()
+   *                 getFeatureDescriptors()
+   */
+  @Test
+  public void elResolverTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      BarELContext barContext = new BarELContext();
+      ELContext context = barContext.getELContext();
+
+      if (barContext != null) {
+        ELResolver resolver = barContext.getELResolver();
+        pass = ResolverTest.testELResolver(context, resolver, null, "Bar",
+            "Foo", buf, true);
+      }
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  } // end elResolverTest
+
+  /**
+   * @testName: elResolverNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:233; EL:JAVADOC:239; EL:JAVADOC:242
+   * 
+   * @test_Strategy: Verify that a NullPointerException is thrown as expected
+   *                 for the following methods: getValue() getType() setValue()
+   *                 isReadOnly()
+   * 
+   * @since: 3.0
+   */
+  @Test
+  public void elResolverNPETest() throws Exception {
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    ELContext context = new ELManager().getELContext();
+
+    // Create dummy ELResolvers to populate the CompositeELResolver.
+    ELResolver aResolver = new ArrayELResolver();
+    ELResolver bResolver = new BeanELResolver();
+
+    // Create the CompositeELResolver & add the dummy ELResolvers to it.
+    CompositeELResolver compResolver = (CompositeELResolver) context
+        .getELResolver();
+    compResolver.add(aResolver);
+    compResolver.add(bResolver);
+
+    try {
+      pass = ResolverTest.testELResolverNPE(compResolver, names,
+          Integer.valueOf(2), "steve", buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  }// end elResolverNPETest
+
+  /**
+   * @testName: elResolverPNFETest
+   * 
+   * @assertion_ids: EL:JAVADOC:231; EL:JAVADOC:234; EL:JAVADOC:240
+   * 
+   * @test_Strategy: Verify that API calls throw PropertyNotFoundException as
+   *                 expected: getType() setValue() isReadOnly()
+   */
+  @Test
+  public void elResolverPNFETest() throws Exception {
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+
+    ELContext context = new ELManager().getELContext();
+
+    // Create an ArrayELResolver to populate the CompositeELResolver.
+    ELResolver aResolver = new ArrayELResolver();
+
+    // Create the CompositeELResolver & add the ELResolver to it.
+    CompositeELResolver compResolver = (CompositeELResolver) context
+        .getELResolver();
+    compResolver.add(aResolver);
+
+    try {
+      pass = ResolverTest.testELResolverPNFE(context, compResolver, names,
+          Integer.valueOf(10), buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  }// end elResolverPNFETest
+
+  /**
+   * @testName: elResolverPNWETest
+   * 
+   * @assertion_ids: EL:JAVADOC:50; EL:JAVADOC:244
+   * 
+   * @test_Strategy: Verify that the setValue() method throws a
+   *                 PropertyNotWritableException, if the resolver was
+   *                 constructed in read-only mode.
+   * 
+   *                 setValue()
+   */
+  @Test
+  public void elResolverPNWETest() throws Exception {
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+    SimpleBean sb = new SimpleBean();
+
+    ELContext context = new ELManager().getELContext();
+
+    ELResolver resolver = new BeanELResolver(true);
+    CompositeELResolver compResolver = (CompositeELResolver) context
+        .getELResolver();
+    compResolver.add(resolver);
+
+    try {
+      pass = ResolverTest.testELResolverPNWE(context, resolver, sb, "intention",
+          "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  } // end elResolverPNWETest
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/expression/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/expression/ELClientIT.java
new file mode 100644
index 0000000..931f348
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/expression/ELClientIT.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.expression;
+
+import java.util.Properties;
+
+
+
+import com.sun.ts.tests.el.common.api.expression.ExpressionTest;
+import com.sun.ts.tests.el.common.elcontext.SimpleELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.ResolverType;
+
+import jakarta.el.ELContext;
+import jakarta.el.Expression;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.MethodExpression;
+import jakarta.el.ValueExpression;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /**
+   * @testName: negativeEqualsTest
+   * 
+   * @assertion_ids: EL:JAVADOC:56
+   * 
+   * @test_Strategy: Validate the behavior of Expression API Expression.equals()
+   * 
+   *                 Verify that an Expression cannot equal null, and that a
+   *                 ValueExpression and a MethodExpression cannot be equal.
+   */
+  @Test
+  public void negativeEqualsTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new SimpleELContext()).getELContext();
+
+      // compare Expressions to null
+      ValueExpression vexp1 = expFactory.createValueExpression(context,
+          "${null}", Object.class);
+
+      if (ExpressionTest.equalsTest(vexp1, null, buf)) {
+        pass = false;
+        buf.append("ValueExpression tested equal to null" + ELTestUtil.NL);
+      }
+
+      MethodExpression mexp1 = expFactory.createMethodExpression(context,
+          "null", null, new Class[] {});
+
+      if (ExpressionTest.equalsTest(mexp1, null, buf)) {
+        pass = false;
+        buf.append("MethodExpression tested equal to null" + ELTestUtil.NL);
+      }
+
+      // compare ValueExpressions to MethodExpressions
+      ValueExpression vexp2 = expFactory.createValueExpression(context,
+          "literal", Object.class);
+
+      MethodExpression mexp2 = expFactory.createMethodExpression(context,
+          "literal", null, new Class[] {});
+
+      if (ExpressionTest.equalsTest(vexp2, mexp2, buf)) {
+        pass = false;
+        buf.append("ValueExpression tested equal to " + "MethodExpression"
+            + ELTestUtil.NL);
+      }
+
+      if (ExpressionTest.equalsTest(mexp2, vexp2, buf)) {
+        pass = false;
+        buf.append("MethodExpression tested equal to " + "ValueExpression"
+            + ELTestUtil.NL);
+      }
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  }// End negativeEqualsTest
+
+  /**
+   * @testName: expressionHashCodeTest
+   * 
+   * @assertion_ids: EL:JAVADOC:59
+   * 
+   * @test_Strategy: Validate the if two objects are equal according to the
+   *                 equals(Object) method, then calling the hashCode method on
+   *                 each of the two objects must produce the same integer
+   *                 result.
+   * 
+   */
+  @Test
+  public void expressionHashCodeTest() throws Exception {
+    SimpleELContext simpleContext = new SimpleELContext(
+        ResolverType.VECT_ELRESOLVER);
+
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    ELContext context = simpleContext.getELContext();
+
+    Class<?>[] paramTypes1 = { Object.class };
+
+    String exprStr1 = "#{vect.add}";
+
+    Expression mexp1 = expFactory.createMethodExpression(context, exprStr1,
+        boolean.class, paramTypes1);
+
+    Expression mexp2 = expFactory.createMethodExpression(context, exprStr1,
+        boolean.class, paramTypes1);
+
+    if (!mexp1.equals(mexp2)) {
+      throw new Exception("Failed: equals check failed!");
+
+    }
+
+    if (!(mexp1.hashCode() == mexp2.hashCode())) {
+      throw new Exception("Failed: hashCode check failed!");
+    }
+
+  }// End expressionHashCodeTest
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/expressionfactory/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/expressionfactory/ELClientIT.java
new file mode 100644
index 0000000..0b251d8
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/expressionfactory/ELClientIT.java
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.expressionfactory;
+
+import java.util.Properties;
+
+
+
+import com.sun.ts.tests.el.common.elcontext.SimpleELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.ExprEval;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.MethodExpression;
+import jakarta.el.ValueExpression;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+  
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: newInstanceTest
+   * 
+   * @assertion_ids: EL:JAVADOC:119; EL:JAVADOC:120
+   * @test_Strategy: Verify that an ExpressionFactory can be instantiated with
+   *                 the newInstance() API.
+   */
+  @Test
+  public void newInstanceTest() throws Exception {
+
+    try {
+      ExpressionFactory.newInstance();
+      ExpressionFactory.newInstance(null);
+
+      Properties props = new Properties();
+      props.setProperty("jakarta.el.cacheSize", "128M");
+      ExpressionFactory.newInstance(props);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+  }
+
+  /**
+   * @testName: createValueExpressionTest
+   * 
+   * @assertion_ids: EL:JAVADOC:63
+   * @test_Strategy: Verify that the ExpressionFactory can handle the types of
+   *                 input specified in the javadoc when invoking the
+   *                 createValueExpression(ELContext, String, Class) method.
+   */
+  @Test
+  public void createValueExpressionTest() throws Exception {
+
+    boolean pass = true;
+
+    String[] exprStr = {
+
+        // $ delimiter
+        "${employee.lastname}",
+
+        // # delimiter
+        "#{employee.lastname}",
+
+        // literal text
+        "John Doe",
+
+        // multiple expressions using the same delimiter
+        "${employee.firstname}${employee.lastname}",
+        "#{employee.firstname}#{employee.lastname}",
+
+        // mixed literal text and expressions using the same delimiter
+        "Name: ${employee.firstname}${employee.lastname}",
+        "Name: #{employee.firstname}#{employee.lastname}"
+
+    };
+
+    ValueExpression vexp = null;
+
+    try {
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      SimpleELContext context = new SimpleELContext();
+
+      for (int i = 0; i < exprStr.length; ++i) {
+        try {
+          vexp = expFactory.createValueExpression(context, exprStr[i],
+              Object.class);
+        } catch (NullPointerException npe) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, ELTestUtil.FAIL + exprStr[i]);
+          ELTestUtil.printStackTrace(npe);
+          continue;
+        } catch (ELException ee) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, ELTestUtil.FAIL + exprStr[i]);
+          ELTestUtil.printStackTrace(ee);
+          continue;
+        }
+
+        if (!vexp.getExpressionString().equals(exprStr[i])) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, "Failed. Expression string mismatch.");
+          logger.log(Logger.Level.ERROR, "Expected: " + exprStr[i]);
+          logger.log(Logger.Level.ERROR, "Received: " + vexp.getExpressionString());
+        }
+      }
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+  }
+
+  /**
+   * @testName: createValueExpression2Test
+   * 
+   * @assertion_ids: EL:JAVADOC:64
+   * @test_Strategy: Verify the functionality of the
+   *                 createValueExpression(Object, Class) method.
+   */
+  @Test
+  public void createValueExpression2Test() throws Exception {
+
+    boolean pass = true;
+
+    // test cases mix coercable and non-coercable object/type
+    // instances
+    ObjectAndType[] testCases = {
+        new ObjectAndType("some string", String.class),
+        new ObjectAndType(null, String.class),
+        new ObjectAndType(Integer.valueOf(1), String.class),
+        new ObjectAndType(Double.valueOf(1.5d), Integer.class),
+        new ObjectAndType("10000", Long.class),
+        new ObjectAndType(Integer.valueOf(1), Boolean.class),
+        new ObjectAndType(Boolean.TRUE, Character.class),
+        new ObjectAndType(Integer.valueOf(1), Class.class) };
+
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+
+    for (int i = 0; i < testCases.length; ++i) {
+      try {
+        expFactory.createValueExpression(testCases[i].obj, testCases[i].type);
+      } catch (Exception e) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Exception: Test Case " + i);
+        ELTestUtil.printStackTrace(e);
+      }
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+  }
+
+  /**
+   * @testName: createValueExpressionELExceptionTest
+   * 
+   * @assertion_ids: EL:JAVADOC:63
+   * @test_Strategy: Verify that
+   *                 ExpressionFactory.createValueExpression(ELContext, String,
+   *                 Class) throws an ELException for mixed delimiter
+   *                 expressions and expressions with syntactical errors.
+   */
+  @Test
+  public void createValueExpressionELExceptionTest() throws Exception {
+
+    boolean pass = true;
+
+    String[] exprStr = {
+
+        // $ delimiter with missing bracket
+        "${employee.lastname",
+
+        // # delimiter with incomplete [] operation
+        "#{employee[lastname}",
+
+        // invalid operation
+        "${ 5 ! 3 }",
+
+        // binary operation with missing operand
+        "${ 5 + }",
+
+        // multiple expressions with mixed delimiters
+        "${employee.firstname}#{employee.lastname}",
+        "#{employee.firstname}${employee.lastname}",
+
+        // mixed literal text and expressions with mixed delimiters
+        "Name: ${employee.firstname}#{employee.lastname}",
+        "Name: #{employee.firstname}${employee.lastname}"
+
+    };
+
+    try {
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      SimpleELContext context = new SimpleELContext();
+
+      for (int i = 0; i < exprStr.length; ++i) {
+        try {
+          expFactory.createValueExpression(context, exprStr[i], Object.class);
+        } catch (ELException ee) {
+          continue;
+        } catch (NullPointerException npe) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, ELTestUtil.FAIL + exprStr[i]);
+          ELTestUtil.printStackTrace(npe);
+          continue;
+        }
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Failed. No ELException thrown when calling");
+        logger.log(Logger.Level.ERROR, "createValueExpression() with parameter " + exprStr[i]);
+      }
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+  }
+
+  /**
+   * @testName: createMethodExpressionTest
+   * 
+   * @assertion_ids: EL:JAVADOC:62
+   * @test_Strategy: Verify that the ExpressionFactory can handle the types of
+   *                 input specified in the javadoc when invoking the
+   *                 createMethodExpression(ELContext, String, Class) method,
+   *                 with the restriction that only expressions that share the
+   *                 same syntax as an lvalue are allowed (EL Spec 1.2.1.2).
+   */
+  @Test
+  public void createMethodExpressionTest() throws Exception {
+
+    boolean pass = true;
+
+    String[] exprStr = {
+
+        // $ delimiter
+        "${add}", "${vect.add}", "${vect[add]}",
+
+        // # delimiter
+        "#{add}", "#{vect.add}", "#{vect[add]}",
+
+        // literal text
+        "add" };
+
+    MethodExpression mexp = null;
+    Class<?>[] paramTypes = {};
+
+    try {
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      SimpleELContext context = new SimpleELContext();
+
+      for (int i = 0; i < exprStr.length; ++i) {
+        try {
+          mexp = expFactory.createMethodExpression(context, exprStr[i],
+              Object.class, paramTypes);
+        } catch (NullPointerException npe) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, ELTestUtil.FAIL + exprStr[i]);
+          ELTestUtil.printStackTrace(npe);
+          continue;
+        } catch (ELException ee) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, ELTestUtil.FAIL + exprStr[i]);
+          ELTestUtil.printStackTrace(ee);
+          continue;
+        }
+
+        if (!mexp.getExpressionString().equals(exprStr[i])) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, "Failed. Expression string mismatch.");
+          logger.log(Logger.Level.ERROR, "Expected: " + exprStr[i]);
+          logger.log(Logger.Level.ERROR, "Received: " + mexp.getExpressionString());
+        }
+      }
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+  }
+
+  /**
+   * @testName: createMethodExpressionELExceptionTest
+   * 
+   * @assertion_ids: EL:JAVADOC:63; EL:JAVADOC:253
+   * 
+   * @test_Strategy: Verify that ExpressionFactory.createMethodExpression()
+   *                 throws an ELException for expressions with syntactical
+   *                 errors, and for expressions that are not lvalues.
+   */
+  @Test
+  public void createMethodExpressionELExceptionTest() throws Exception {
+
+    boolean pass = true;
+
+    String[] exprStr = {
+
+        // $ delimiter with missing bracket
+        "${vect.add",
+
+        // # delimiter with incomplete [] operation
+        "#{vect[add}",
+
+        // Expressions that are not lvalues
+        // constant value
+        "${ 5 }",
+
+        // unary operation
+        "${ -A }",
+
+        // binary operation
+        "${ A + B }",
+
+        // multiple expressions
+        "${vect.remove}${vect.add}", "#{vect.remove}#{vect.add}",
+        "${vect.remove}#{vect.add}", "#{vect.remove}${vect.add}"
+
+    };
+
+    Class<?>[] paramTypes = {};
+
+    try {
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      SimpleELContext context = new SimpleELContext();
+
+      for (int i = 0; i < exprStr.length; ++i) {
+        try {
+          expFactory.createMethodExpression(context, exprStr[i], Object.class,
+              paramTypes);
+        } catch (ELException ee) {
+          continue;
+        } catch (NullPointerException npe) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, ELTestUtil.FAIL + exprStr[i]);
+          ELTestUtil.printStackTrace(npe);
+          continue;
+        }
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Failed. No ELException thrown when calling");
+        logger.log(Logger.Level.ERROR, "createMethodExpression() with parameter " + exprStr[i]);
+      }
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+  }
+
+  /**
+   * @testName: createExpressionNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:62; EL:JAVADOC:63; EL:JAVADOC:64;
+   *                 EL:JAVADOC:253; EL:JAVADOC:254; EL:JAVADOC:256
+   * 
+   * @test_Strategy: Verify that ExpressionFactory.createValueExpression() and
+   *                 ExpressionFactory.createMethodExpression() throw a
+   *                 NullPointerException under the conditions stated in the
+   *                 javadoc.
+   */
+  @Test
+  public void createExpressionNPETest() throws Exception {
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    SimpleELContext context = new SimpleELContext();
+
+    logger.log(Logger.Level.INFO, "Testing: ELContext.createValueExpression(context, "
+        + "function, null)");
+    ELTestUtil.checkForNPE(expFactory, "createValueExpression",
+        new Class<?>[] { ELContext.class, String.class, Class.class },
+        new Object[] { context, "function", null });
+
+    logger.log(Logger.Level.INFO, 
+        "Testing: ELContext.createValueExpression(instance, " + "null)");
+    ELTestUtil.checkForNPE(expFactory, "createValueExpression",
+        new Class<?>[] { Object.class, Class.class },
+        new Object[] { "function", null });
+
+    logger.log(Logger.Level.INFO, "Testing: ELContext.createMethodExpression(context, "
+        + "instance, returnTypes, null)");
+    ELTestUtil.checkForNPE(expFactory, "createMethodExpression",
+        new Class<?>[] { ELContext.class, String.class, Class.class,
+            Class[].class },
+        new Object[] { context, "${foo}", Object.class, null });
+
+  }
+
+  /**
+   * @testName: coerceToTypeTest
+   * 
+   * @assertion_ids: EL:JAVADOC:61
+   * @test_Strategy: Verify that the coerceToType() method coerces an object to
+   *                 a specific type according to the EL type conversion rules.
+   */
+  @Test
+  public void coerceToTypeTest() throws Exception {
+
+    boolean pass = true;
+
+    ObjectAndType[] testCases = {
+        new ObjectAndType("some string", String.class),
+        new ObjectAndType(null, String.class),
+        new ObjectAndType(Integer.valueOf(1), String.class),
+        new ObjectAndType(Double.valueOf(1.5d), String.class),
+        new ObjectAndType(Boolean.FALSE, String.class),
+        new ObjectAndType(Double.valueOf(1.5d), Integer.class),
+        new ObjectAndType(Integer.valueOf(1), Float.class),
+        new ObjectAndType("10000", Long.class),
+        new ObjectAndType("no value", Boolean.class),
+        new ObjectAndType(null, null) };
+
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+
+    for (int i = 0; i < testCases.length; ++i) {
+      try {
+        Object coercedObj = expFactory.coerceToType(testCases[i].obj,
+            testCases[i].type);
+        if (coercedObj == null) {
+          if (!(testCases[i].type == null || testCases[i].obj == null)) {
+            pass = false;
+            logger.log(Logger.Level.ERROR, "Failed: Test Case " + i);
+          }
+
+        } else if (!ExprEval.compareClass(coercedObj, testCases[i].type)) {
+          pass = false;
+          logger.log(Logger.Level.ERROR, "Failed: Test Case " + i);
+        }
+      } catch (Exception e) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Exception: Test Case " + i);
+        ELTestUtil.printStackTrace(e);
+      }
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+  }
+
+  /**
+   * @testName: coerceToTypeELExceptionTest
+   * 
+   * @assertion_ids: EL:JAVADOC:61; EL:JAVADOC:251
+   * 
+   * @test_Strategy: Verify that the coerceToType() method throws an ELException
+   *                 for invalid type conversions.
+   */
+  @Test
+  public void coerceToTypeELExceptionTest() throws Exception {
+
+    boolean pass = true;
+
+    ObjectAndType[] testCases = {
+        new ObjectAndType(Integer.valueOf(1), Boolean.class),
+        new ObjectAndType(Boolean.FALSE, Long.class),
+        new ObjectAndType(Boolean.TRUE, Character.class),
+        new ObjectAndType(true, Float.class),
+        new ObjectAndType("non-numeric string", Long.class),
+        new ObjectAndType(Integer.valueOf(1), Class.class) };
+
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+
+    for (int i = 0; i < testCases.length; ++i) {
+      try {
+        expFactory.coerceToType(testCases[i].obj, testCases[i].type);
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Test Case " + i + " did not cause an exception");
+      } catch (ELException elx) {
+        pass = true;
+
+      } catch (Exception e) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Test Case " + i + " threw an exception");
+        logger.log(Logger.Level.ERROR, "but it was not an ELException");
+        ELTestUtil.printStackTrace(e);
+      }
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+  }
+
+  private static class ObjectAndType {
+
+    public Object obj;
+
+    public Class<?> type;
+
+    public ObjectAndType(Object obj, Class<?> type) {
+      this.obj = obj;
+      this.type = type;
+    }
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/functionmapper/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/functionmapper/ELClientIT.java
new file mode 100644
index 0000000..ce735ed
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/functionmapper/ELClientIT.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.functionmapper;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.elcontext.FuncMapperELContext;
+
+import jakarta.el.FunctionMapper;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+  
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+
+  /**
+   * @testName: functionMapperTest
+   * 
+   * @assertion_ids: EL:JAVADOC:35; EL:JAVADOC:67
+   * @test_Strategy: Validate the behavior of ELContext.getFunctionMapper()
+   *                 FunctionMapper.resolveFunction()
+   */
+  @Test
+  public void functionMapperTest() throws Exception {
+
+    String expected = "public static java.lang.Integer "
+        + "java.lang.Integer.valueOf"
+        + "(java.lang.String) throws java.lang.NumberFormatException";
+
+    FuncMapperELContext context = new FuncMapperELContext();
+    FunctionMapper funcMapper = context.getFunctionMapper();
+    logger.log(Logger.Level.TRACE, "FunctionMapper is " + funcMapper.toString());
+
+    if (funcMapper.resolveFunction("foo", "bar") != null) {
+      logger.log(Logger.Level.ERROR, "Expected call to resolveFunction() to unassigned "
+          + "function to return null" + ELTestUtil.NL
+          + "Instead call returned: "
+          + funcMapper.resolveFunction("foo", "bar").getName()
+          + ELTestUtil.NL);
+
+      throw new Exception("Resolved unassigned function");
+    }
+
+    Method method = funcMapper.resolveFunction("Int", "val");
+    if (method == null) {
+      logger.log(Logger.Level.ERROR, "Expected call to resolveFunction() to resolvable "
+          + "function to return a non-null value" + ELTestUtil.NL);
+
+      throw new Exception("Incorrect resolution: null method");
+    } else {
+      String methodSignature = method.toString();
+      if (!methodSignature.equals(expected)) {
+        logger.log(Logger.Level.ERROR, "Method Signature of resolved function is " + "invalid"
+            + ELTestUtil.NL + "Expected value:" + expected
+            + ELTestUtil.NL);
+
+        throw new Exception("Incorrect resolution: wrong method Signature");
+      }
+    }
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/lambdaexpression/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/lambdaexpression/ELClientIT.java
new file mode 100644
index 0000000..7079b17
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/lambdaexpression/ELClientIT.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.lambdaexpression;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.LambdaExpression;
+import jakarta.el.StandardELContext;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+
+  /**
+   * @testName: invokeNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:406
+   * 
+   * @test_Strategy: Throws a NullPointerException if elContext is null.
+   */
+  @Test
+  public void invokeNPETest() throws Exception {
+    List<String> params = new ArrayList<String>();
+    params.add("one");
+    LambdaExpression le = new LambdaExpression(params, null);
+
+    ELTestUtil.checkForNPE(le, "invoke",
+        new Class<?>[] { ELContext.class, Object[].class },
+        new Object[] { null, new Object[] { "one" } });
+  }// End invokeNPETest
+
+  /**
+   * @testName: invokeELETest
+   * 
+   * @assertion_ids: EL:JAVADOC:408
+   * 
+   * @test_Strategy: Throws a ELException if not enough arguments are provided.
+   */
+  @Test
+  public void invokeELETest() throws Exception {
+    StringBuffer buff = new StringBuffer();
+    boolean pass = false;
+    List<String> params = new ArrayList<String>();
+    params.add("one");
+
+    LambdaExpression le = new LambdaExpression(params, null);
+    try {
+      le.invoke(new StandardELContext(ExpressionFactory.newInstance()),
+          new Object[] {});
+      buff.append(ELTestUtil.FAIL + " No Exception thrown!" + ELTestUtil.NL
+          + "Expected an ELException to be thrown!");
+    } catch (ELException ele) {
+      logger.log(Logger.Level.INFO, ELTestUtil.PASS);
+      pass = true;
+    } catch (Exception e) {
+      logger.log(Logger.Level.INFO, ELTestUtil.FAIL + ELTestUtil.NL + "Expected: ELException"
+          + ELTestUtil.NL + "Received: " + e.getClass().getSimpleName());
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+  }// End invokeELETest
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/listelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/listelresolver/ELClientIT.java
new file mode 100644
index 0000000..f49cf44
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/listelresolver/ELClientIT.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.listelresolver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELContext;
+import jakarta.el.ListELResolver;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private List<String> names;
+
+  public ELClientIT(){
+    names = new ArrayList<String>();
+    names.add("doug");
+    names.add("nick");
+    names.add("ryan");
+  }
+
+  
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /**
+   * @testName: listELResolverTest
+   * 
+   * @assertion_ids: EL:JAVADOC:68; EL:JAVADOC:69; EL:JAVADOC:70; EL:JAVADOC:71;
+   *                 EL:JAVADOC:72; EL:JAVADOC:73; EL:JAVADOC:75
+   * 
+   * @test_Strategy: Verify that API calls work as expected: ListELResolver()
+   *                 getValue() getType() setValue() isReadOnly()
+   *                 getCommonPropertyType() getFeatureDescriptors()
+   */
+  @Test
+  public void listELResolverTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      ListELResolver listResolver = new ListELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, listResolver, names,
+          Integer.valueOf(1), "ed", buf, false);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: listELResolverNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:70; EL:JAVADOC:71; EL:JAVADOC:72; EL:JAVADOC:73;
+   *                 EL:JAVADOC:75; EL:JAVADOC:276; EL:JAVADOC:279;
+   *                 EL:JAVADOC:282; EL:JAVADOC:285
+   * 
+   * @test_Strategy: Verify that the following methods throw a
+   *                 NullPointerException, if context is null:
+   * 
+   *                 getType() getValue() isReadOnly() setValue()
+   */
+  @Test
+  public void listELResolverNPETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+    ListELResolver resolver = new ListELResolver();
+
+    try {
+      pass = ResolverTest.testELResolverNPE(resolver, names, Integer.valueOf(1),
+          "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: listELResolverPNFETest
+   * 
+   * @assertion_ids: EL:JAVADOC:70; EL:JAVADOC:72; EL:JAVADOC:73; EL:JAVADOC:75;
+   *                 EL:JAVADOC:275; EL:JAVADOC:281; EL:JAVADOC:288
+   * @test_Strategy: Verify that the following methods throw a
+   *                 PropertyNotFoundException, if the given index is out of
+   *                 bounds for this list:
+   * 
+   *                 getType() isReadOnly() setValue()
+   */
+  @Test
+  public void listELResolverPNFETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    ListELResolver resolver = new ListELResolver();
+    BareBonesELContext barebonesComtext = new BareBonesELContext();
+    ELContext context = barebonesComtext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverPNFE(context, resolver, names,
+          Integer.valueOf(10), buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: listELResolverIAETest
+   * 
+   * @assertion_ids: EL:JAVADOC:71; EL:JAVADOC:73; EL:JAVADOC:75;
+   *                 EL:JAVADOC:278; EL:JAVADOC:286
+   * 
+   * @test_Strategy: Verify that the following methods throw an
+   *                 IllegalArgumentException, if the property could not be
+   *                 coerced into an integer:
+   * 
+   *                 getValue() setValue()
+   */
+  @Test
+  public void listELResolverIAETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    ListELResolver resolver = new ListELResolver();
+    BareBonesELContext barebonesComtext = new BareBonesELContext();
+    ELContext context = barebonesComtext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverIAE(context, resolver, names, "GARBAGE",
+          "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: listELResolverPNWETest
+   * 
+   * @assertion_ids: EL:JAVADOC:74; EL:JAVADOC:75; EL:JAVADOC:287
+   * 
+   * @test_Strategy: Verify that the single-parameter constructor for
+   *                 listELResolver can be used to construct a read-only
+   *                 resolver, and that the setValue() method throws a
+   *                 PropertyNotWritableException, if the resolver was
+   *                 constructed in read-only mode.
+   * 
+   *                 ListELResolver(boolean) setValue()
+   */
+  @Test
+  public void listELResolverPNWETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    ListELResolver resolver = new ListELResolver(true);
+    BareBonesELContext barebonesComtext = new BareBonesELContext();
+    ELContext context = barebonesComtext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverPNWE(context, resolver, names,
+          Integer.valueOf(1), "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/mapelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/mapelresolver/ELClientIT.java
new file mode 100644
index 0000000..4858507
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/mapelresolver/ELClientIT.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.mapelresolver;
+
+import java.util.HashMap;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELContext;
+import jakarta.el.MapELResolver;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private HashMap<String, String> animals;
+
+  public ELClientIT(){
+    animals = new HashMap<String, String>();
+    animals.put("dog", "retriever");
+    animals.put("fish", "bass");
+    animals.put("bird", "parrot");
+  }
+
+  
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+
+  /**
+   * @testName: mapELResolverTest
+   * 
+   * @assertion_ids: EL:JAVADOC:76; EL:JAVADOC:77; EL:JAVADOC:78; EL:JAVADOC:79;
+   *                 EL:JAVADOC:80; EL:JAVADOC:81; EL:JAVADOC:83
+   * @test_Strategy: Verify that API calls work as expected: MapELResolver()
+   *                 getValue() getType() setValue() isReadOnly()
+   *                 getCommonPropertyType() getFeatureDescriptors()
+   */
+  @Test
+  public void mapELResolverTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      MapELResolver mapResolver = new MapELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, mapResolver, animals, "dog",
+          "labador", buf, false);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: mapELResolverNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:78; EL:JAVADOC:79; EL:JAVADOC:80; EL:JAVADOC:81;
+   *                 EL:JAVADOC:83; EL:JAVADOC:293; EL:JAVADOC:295;
+   *                 EL:JAVADOC:298; EL:JAVADOC:290
+   * 
+   * @test_Strategy: Verify that the following methods throw a
+   *                 NullPointerException, if context is null:
+   * 
+   *                 getType() getValue() isReadOnly() setValue()
+   */
+  @Test
+  public void mapELResolverNPETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    MapELResolver resolver = new MapELResolver();
+
+    try {
+      pass = ResolverTest.testELResolverNPE(resolver, animals, "dog", "billy",
+          buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: mapELResolverPNWETest
+   * 
+   * @assertion_ids: EL:JAVADOC:82; EL:JAVADOC:83; EL:JAVADOC:301
+   * 
+   * @test_Strategy: Verify that the single-parameter constructor for
+   *                 mapELResolver can be used to construct a read-only
+   *                 resolver, and that the setValue() method throws a
+   *                 PropertyNotWritableException, if the resolver was
+   *                 constructed in read-only mode.
+   * 
+   *                 MapELResolver(boolean) setValue()
+   */
+  @Test
+  public void mapELResolverPNWETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    MapELResolver resolver = new MapELResolver(true);
+    BareBonesELContext barebonesComtext = new BareBonesELContext();
+    ELContext context = barebonesComtext.getELContext();
+
+    try {
+      pass = ResolverTest.testELResolverPNWE(context, resolver, animals, "dog",
+          "billy", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodexpression/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodexpression/ELClientIT.java
new file mode 100644
index 0000000..e7a9de7
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodexpression/ELClientIT.java
@@ -0,0 +1,703 @@
+/*
+ * Copyright (c) 2009, 2021 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.methodexpression;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.api.expression.ExpressionTest;
+import com.sun.ts.tests.el.common.elcontext.SimpleELContext;
+import com.sun.ts.tests.el.common.elcontext.VarMapperELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.MethodsBean;
+import com.sun.ts.tests.el.common.util.ResolverType;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.MethodExpression;
+import jakarta.el.MethodNotFoundException;
+import jakarta.el.PropertyNotFoundException;
+import jakarta.el.ValueExpression;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private static final String NL = System.getProperty("line.seperator", "\n");
+
+  private Properties testProps;
+
+  public ELClientIT(){
+    this.testProps=System.getProperties();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: positiveMethodExpressionTest
+   * 
+   * @assertion_ids: EL:JAVADOC:84; EL:JAVADOC:85; EL:JAVADOC:58; EL:JAVADOC:60
+   * @test_Strategy: Validate the behavior of MethodExpression API
+   *                 MethodExpression.getMethodInfo() MethodExpression.invoke()
+   *                 Expression.isLiteralText() Expression.getExpressionString()
+   */
+  @Test
+  public void positiveMethodExpressionTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+
+    boolean pass1, pass2, pass3, pass4;
+
+    try {
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+
+      SimpleELContext simpleContext = new SimpleELContext(
+          ResolverType.VECT_ELRESOLVER);
+      ELContext context = simpleContext.getELContext();
+
+      // case 1: non-null return value
+      Object[] params1 = new Object[] { "new member" };
+      Class<?>[] paramTypes1 = { Object.class };
+      String exprStr1 = "#{vect.add}";
+
+      MethodExpression mexp1 = expFactory.createMethodExpression(context,
+          exprStr1, boolean.class, paramTypes1);
+      pass1 = ExpressionTest.testMethodExpression(mexp1, context, exprStr1,
+          params1, Boolean.TRUE, false, buf);
+
+      // case 2: null return value
+      Object[] params2 = new Object[] { Integer.valueOf(0), "new member" };
+      Class<?>[] paramTypes2 = { int.class, Object.class };
+      String exprStr2 = "#{vect.add}";
+
+      MethodExpression mexp2 = expFactory.createMethodExpression(context,
+          exprStr2, null, paramTypes2);
+      pass2 = ExpressionTest.testMethodExpression(mexp2, context, exprStr2,
+          params2, null, false, buf);
+
+      // case 3: literal expression returning String
+      Object[] params3 = null;
+      Class<?>[] paramTypes3 = {};
+      String exprStr3 = "true";
+
+      MethodExpression mexp3 = expFactory.createMethodExpression(context,
+          exprStr3, String.class, paramTypes3);
+      pass3 = ExpressionTest.testMethodExpression(mexp3, context, exprStr3,
+          params3, "true", true, buf);
+
+      // case 4: literal expression returning non-String value
+      Object[] params4 = null;
+      Class<?>[] paramTypes4 = {};
+      String exprStr4 = "true";
+
+      MethodExpression mexp4 = expFactory.createMethodExpression(context,
+          exprStr4, Boolean.class, paramTypes4);
+      pass4 = ExpressionTest.testMethodExpression(mexp4, context, exprStr4,
+          params4, Boolean.TRUE, true, buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!(pass1 && pass2 && pass3 && pass4))
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+  }
+
+  /**
+   * @testName: negativeMethodExpressionTest
+   * 
+   * @assertion_ids: EL:JAVADOC:84; EL:JAVADOC:85; EL:JAVADOC:302;
+   *                 EL:JAVADOC:306; EL:JAVADOC:303; EL:JAVADOC:307;
+   *                 EL:JAVADOC:309; EL:JAVADOC:310; EL:JAVADOC:304;
+   *                 EL:JAVADOC:308
+   * 
+   * @test_Strategy: Validate the behavior of MethodExpression API
+   *                 MethodExpression.getMethodInfo() MethodExpression.invoke()
+   */
+  @Test
+  public void negativeMethodExpressionTest() throws Exception {
+
+    boolean pass = true;
+
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+
+    SimpleELContext simpleContext = new SimpleELContext(
+        ResolverType.VECT_ELRESOLVER);
+    ELContext context = simpleContext.getELContext();
+
+    Object[] params = new Object[] { "new member" };
+    Class<?>[] paramTypes = { Object.class };
+
+    // case 1: NullPointerException. Null ELContext passed to methods.
+    String exprStr1 = "#{vect.add}";
+
+    MethodExpression mexp1 = expFactory.createMethodExpression(context,
+        exprStr1, boolean.class, paramTypes);
+    try {
+      mexp1.getMethodInfo(null);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() with null ELContext "
+          + "parameter did not" + NL);
+      logger.log(Logger.Level.ERROR, " cause an exception to be thrown" + NL);
+
+    } catch (NullPointerException npe) {
+      // do nothing test passed!
+      logger.log(Logger.Level.INFO, "Expected Exception Thrown, when Null ELContext "
+          + "passed to getMethodInfo(): " + npe.getClass().getSimpleName());
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() with null ELContext "
+          + "threw the wrong Exception!" + NL + "Expected: NullPointerException"
+          + NL + "Received: " + e.toString() + NL);
+
+      e.printStackTrace();
+    }
+
+    try {
+      mexp1.invoke(null, params);
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to invoke() with null ELContext parameter did " + "not" + NL);
+      logger.log(Logger.Level.ERROR, " cause an exception to be thrown" + NL);
+
+    } catch (NullPointerException npe) {
+      // Do nothing test passed!
+      logger.log(Logger.Level.INFO, "Expected Exception Thrown, when Null ELContext "
+          + "passed to invoke(): " + npe.getClass().getSimpleName());
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to invoke() with null ELContext "
+          + "throw the wrong Exception!" + NL + "Expected: NullPointerException"
+          + NL + "Received: " + e.toString() + NL);
+
+      e.printStackTrace();
+    }
+
+    // case 2: MethodNotFoundException. Property found, but
+    // method does not exist.
+    String exprStr2 = "#{vect.noSuchMethod}";
+
+    MethodExpression mexp2 = expFactory.createMethodExpression(context,
+        exprStr2, boolean.class, paramTypes);
+    try {
+      mexp2.getMethodInfo(context);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() for non-existent method did "
+          + "not cause" + NL);
+      logger.log(Logger.Level.ERROR, " an exception to be thrown" + NL);
+
+    } catch (MethodNotFoundException mnfe) {
+      // do nothing test passed!
+      logger.log(Logger.Level.INFO, "Expected Exception Thrown, when method does not "
+          + "exists for getMethodInfo(): " + mnfe.getClass().getSimpleName());
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to getMethodInfo() for non-existent method threw the wrong "
+              + "exception!" + NL + "Expected: MethodNotFoundException" + NL
+              + "Received: " + e.toString() + NL);
+
+      e.printStackTrace();
+    }
+
+    try {
+      mexp2.invoke(context, params);
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to invoke() for non-existent method did not " + "cause" + NL);
+      logger.log(Logger.Level.ERROR, " an exception to be thrown" + NL);
+
+    } catch (MethodNotFoundException mnfe) {
+      // do thing test passed!
+      logger.log(Logger.Level.INFO, "Expected Exception Thrown, when method does not "
+          + "exists for invoke(): " + mnfe.getClass().getSimpleName());
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to getMethodInfo() for non-existent method threw the wrong "
+              + "exception!" + NL + "Expected: MethodNotFoundException" + NL
+              + "Received: " + e.toString() + NL);
+
+      e.printStackTrace();
+    }
+
+    // case 3: PropertyNotFoundException: No such property in ELContext.
+    String exprStr3 = "#{wect.add}";
+
+    MethodExpression mexp3 = expFactory.createMethodExpression(context,
+        exprStr3, boolean.class, paramTypes);
+
+    try {
+      mexp3.getMethodInfo(context);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() for non-existent property "
+          + "did not cause" + NL);
+      logger.log(Logger.Level.ERROR, " an exception to be thrown" + NL);
+
+    } catch (PropertyNotFoundException pnfe) {
+      // Do nothing test passed!
+      logger.log(Logger.Level.INFO, 
+          "Expected Exception Thrown, No such property in " + "ELContext"
+              + "for getMethodInfo(): " + pnfe.getClass().getSimpleName());
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to getMethodInfo() for non-existent property threw the wrong "
+              + "exception!" + NL + "Expected: PropertyNotFoundException" + NL
+              + "Received: " + e.toString() + NL);
+
+      e.printStackTrace();
+    }
+
+    try {
+      mexp3.invoke(context, params);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to invoke() for non-existent property did " + "not "
+          + "cause" + NL);
+      logger.log(Logger.Level.ERROR, " an exception to be thrown" + NL);
+
+    } catch (PropertyNotFoundException pnfe) {
+      // Do nothing test passed!
+      logger.log(Logger.Level.INFO, "Expected Exception Thrown, No such property in "
+          + "ELContext" + "for invoke(): " + pnfe.getClass().getSimpleName());
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to invoke() for non-existent property threw " + "the wrong "
+              + "exception!" + NL + "Expected: PropertyNotFoundException" + NL
+              + "Received: " + e.toString() + NL);
+
+      e.printStackTrace();
+    }
+
+    // case 4: ELException: Call to invoke() with string literal.
+    // Expected return type is void.
+    String exprStr4 = "literal";
+
+    MethodExpression mexp4 = expFactory.createMethodExpression(context,
+        exprStr4, void.class, paramTypes);
+
+    try {
+      mexp4.invoke(context, params);
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to invoke() for string literal with expected " + "return" + NL);
+      logger.log(Logger.Level.ERROR, 
+          " value of void did not cause an exception to be " + "thrown" + NL);
+
+    } catch (ELException ee) {
+      // Do nothing test passed!
+      logger.log(Logger.Level.INFO, "Expected Exception Thrown. Call to invoke() with "
+          + "string literal ELContext for invoke()." + NL
+          + "Expected return type is void: " + ee.getClass().getSimpleName());
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to invoke() for string literal with expected return"
+          + NL + "value of void caused the wrong exception to be thrown!" + NL
+          + "Expected: ELException: " + NL + "Received: " + e.toString());
+
+      e.printStackTrace();
+    }
+
+    // case 5: ELException: Call to invoke() with string literal.
+    // Expected return type can't be coerced.
+    String exprStr5 = "literal";
+
+    MethodExpression mexp5 = expFactory.createMethodExpression(context,
+        exprStr5, Double.class, paramTypes);
+
+    try {
+      mexp5.invoke(context, params);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to invoke() for string literal with "
+          + "non-coercable expected " + NL);
+      logger.log(Logger.Level.ERROR, 
+          "return value did not cause an exception to be " + "thrown" + NL);
+
+    } catch (ELException ee) {
+      // Do nothing test passed!
+      logger.log(Logger.Level.INFO, "Expected Exception Thrown. Call to invoke() with "
+          + "string literal ELContext for " + "invoke()." + NL
+          + "Expected return type can't be coerced: "
+          + ee.getClass().getSimpleName());
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to invoke() for string literal with non-coercable expected "
+              + NL + "return value caused the wrong exception to be thrown!"
+              + NL + "Expected: ELException: " + NL + "Received: "
+              + e.toString());
+
+      e.printStackTrace();
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL);
+
+  }
+
+  /*
+   * @testName: methodExpressionSerializableTest
+   * 
+   * @assertion_ids: EL:SPEC:44
+   * 
+   * @test_Strategy: Validate that MethodExpression implements Serializable and
+   * that a MethodExpression can be manually serialized and deserialized.
+   */
+  @Test
+  public void methodExpressionSerializableTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+    Class<?>[] paramTypes = { Object.class };
+    String exprStr = "#{vect.add}";
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new SimpleELContext()).getELContext();
+
+      // Setup eval-expression
+      MethodExpression evalmexp = expFactory.createMethodExpression(context,
+          exprStr, Boolean.class, paramTypes);
+      logger.log(Logger.Level.TRACE, 
+          "Eval Method Expression For Testing: " + evalmexp.toString() + NL);
+
+      // Setup literal-expression
+      MethodExpression literalmexp = expFactory.createMethodExpression(context,
+          "vect.add", Boolean.class, paramTypes);
+      logger.log(Logger.Level.TRACE, "Literal Method Expression For Testing: "
+          + literalmexp.toString() + NL);
+
+      // Test both eval & literal expressions.
+      if (!(ExpressionTest.expressionSerializableTest(evalmexp, buf)
+          && ExpressionTest.expressionSerializableTest(literalmexp, buf))) {
+        pass = false;
+      }
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    else
+      logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /*
+   * @testName: methodExpressionMatchingExactPreferredTest
+   * 
+   * @assertion_ids: EL:SPEC:80
+   * 
+   * @test_Strategy: Validate that MethodExpression identifies the correct
+   * method for the given parameters and that exact type matches are always
+   * preferred.
+   */
+  @Test
+  public void methodExpressionMatchingExactPreferredTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+    String exprStr = "#{bean.targetA('text')}"; 
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new VarMapperELContext(testProps)).getELContext();
+      
+      MethodsBean bean = new MethodsBean();
+      ValueExpression ve = expFactory.createValueExpression(bean, MethodsBean.class);
+      context.getVariableMapper().setVariable("bean", ve);
+
+      // Single String arg so should match to "String"
+      MethodExpression me = expFactory.createMethodExpression(context, exprStr, String.class, null);
+      if (!ExpressionTest.testMethodExpression(me, context, exprStr, null, "String", false, buf)) {
+        pass = false;
+      }
+    } catch (Exception ex) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() with valid method expression "
+          + "threw an Exception!" + NL + "Received: " + ex.toString() + NL);
+
+      ex.printStackTrace();
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    else
+      logger.log(Logger.Level.TRACE, buf.toString());
+  }
+  
+  /*
+   * @testName: methodExpressionMatchingOverloadBeatsCoercionTest
+   * 
+   * @assertion_ids: EL:SPEC:80
+   * 
+   * @test_Strategy: Validate that MethodExpression identifies the correct
+   * method for the given parameters and that overloading is preferred to
+   * coercion.
+   */
+  @Test
+  public void methodExpressionMatchingOverloadBeatsCoercionTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+    String exprStr = "#{bean.targetB('1')}"; 
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new VarMapperELContext(testProps)).getELContext();
+      
+      MethodsBean bean = new MethodsBean();
+      ValueExpression ve = expFactory.createValueExpression(bean, MethodsBean.class);
+      context.getVariableMapper().setVariable("bean", ve);
+
+      MethodExpression me = expFactory.createMethodExpression(context, exprStr, String.class, null);
+      if (!ExpressionTest.testMethodExpression(me, context, exprStr, null, "CharSequence", false, buf)) {
+        pass = false;
+      }
+    } catch (Exception ex) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() with valid method expression "
+          + "threw an Exception!" + NL + "Received: " + ex.toString() + NL);
+
+      ex.printStackTrace();
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    else
+      logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /*
+   * @testName: methodExpressionMatchingOverloadBeatsExactVarArgsTest
+   * 
+   * @assertion_ids: EL:SPEC:80
+   * 
+   * @test_Strategy: Validate that MethodExpression identifies the correct
+   * method for the given parameters and that any match without varags is
+   * preferred to all matches with varrags
+   */
+  @Test
+  public void methodExpressionMatchingOverloadBeatsExactVarArgsTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+    String exprStr = "#{bean.targetC('aaa','bbb')}"; 
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new VarMapperELContext(testProps)).getELContext();
+      
+      MethodsBean bean = new MethodsBean();
+      ValueExpression ve = expFactory.createValueExpression(bean, MethodsBean.class);
+      context.getVariableMapper().setVariable("bean", ve);
+
+      MethodExpression me = expFactory.createMethodExpression(context, exprStr, String.class, null);
+      if (!ExpressionTest.testMethodExpression(me, context, exprStr, null, "CharSequence-CharSequence", false, buf)) {
+        pass = false;
+      }
+    } catch (Exception ex) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() with valid method expression "
+          + "threw an Exception!" + NL + "Received: " + ex.toString() + NL);
+
+      ex.printStackTrace();
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    else
+      logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /*
+   * @testName: methodExpressionMatchingCoercionBeatsExactVarArgsTest
+   * 
+   * @assertion_ids: EL:SPEC:80
+   * 
+   * @test_Strategy: Validate that MethodExpression identifies the correct
+   * method for the given parameters and that any match without varags is
+   * preferred to all matches with varrags
+   */
+  @Test
+  public void methodExpressionMatchingCoercionBeatsExactVarArgsTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+    String exprStr = "#{bean.targetD('1','1')}"; 
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new VarMapperELContext(testProps)).getELContext();
+      
+      MethodsBean bean = new MethodsBean();
+      ValueExpression ve = expFactory.createValueExpression(bean, MethodsBean.class);
+      context.getVariableMapper().setVariable("bean", ve);
+
+      MethodExpression me = expFactory.createMethodExpression(context, exprStr, String.class, null);
+      if (!ExpressionTest.testMethodExpression(me, context, exprStr, null, "Long-Long", false, buf)) {
+        pass = false;
+      }
+    } catch (Exception ex) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() with valid method expression "
+          + "threw an Exception!" + NL + "Received: " + ex.toString() + NL);
+
+      ex.printStackTrace();
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    else
+      logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /*
+   * @testName: methodExpressionMatchingVarArgsTest
+   * 
+   * @assertion_ids: EL:SPEC:80
+   * 
+   * @test_Strategy: Validate that MethodExpression identifies the correct
+   * method for the given parameters and that varags will be matched if no other
+   * suitable match is available
+   */
+  @Test
+  public void methodExpressionMatchingVarArgsTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+    String exprStr = "#{bean.targetD('aaa','bbb')}"; 
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new VarMapperELContext(testProps)).getELContext();
+      
+      MethodsBean bean = new MethodsBean();
+      ValueExpression ve = expFactory.createValueExpression(bean, MethodsBean.class);
+      context.getVariableMapper().setVariable("bean", ve);
+
+      MethodExpression me = expFactory.createMethodExpression(context, exprStr, String.class, null);
+      if (!ExpressionTest.testMethodExpression(me, context, exprStr, null, "String-Strings", false, buf)) {
+        pass = false;
+      }
+    } catch (Exception ex) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() with valid method expression "
+          + "threw an Exception!" + NL + "Received: " + ex.toString() + NL);
+
+      ex.printStackTrace();
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    else
+      logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /*
+   * @testName: methodExpressionMatchingAmbiguousTest
+   * 
+   * @assertion_ids: EL:SPEC:80
+   * 
+   * @test_Strategy: Validate that MethodExpression does not match a method when
+   * the match is ambiguous and that a MethodNotFoundException is thrown
+   */
+  @Test
+  public void methodExpressionMatchingAmbiguousTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+    String exprStr = "#{bean.targetE('1234',1234)}"; 
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new VarMapperELContext(testProps)).getELContext();
+      
+      MethodsBean bean = new MethodsBean();
+      ValueExpression ve = expFactory.createValueExpression(bean, MethodsBean.class);
+      context.getVariableMapper().setVariable("bean", ve);
+
+      MethodExpression me = expFactory.createMethodExpression(context, exprStr, String.class, null);
+      me.getMethodInfo(context);
+      pass = false;
+    } catch (MethodNotFoundException mnfe) {
+      pass = true;
+    } catch (Exception ex) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getMethodInfo() with ambiguous method expression "
+          + "threw the wrong Exception!" + NL + "Expected: MethodNotFoundException"
+          + NL + "Received: " + ex.toString() + NL);
+
+      ex.printStackTrace();
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    else
+      logger.log(Logger.Level.TRACE, buf.toString());
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodinfo/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodinfo/ELClientIT.java
new file mode 100644
index 0000000..19d6f75
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodinfo/ELClientIT.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.methodinfo;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.api.expression.ExpressionTest;
+import com.sun.ts.tests.el.common.elcontext.SimpleELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.ResolverType;
+
+import jakarta.el.ELContext;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.MethodExpression;
+import jakarta.el.MethodInfo;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: methodInfoTest
+   * 
+   * @assertion_ids: EL:JAVADOC:411;EL:JAVADOC:412;EL:JAVADOC:413
+   * @test_Strategy: Validate the behavior of MethodInfo MethodInfo class
+   *                 methods: MethodInfo.getName() MethodInfo.getReturnType()
+   *                 MethodInfo.getParamTypes()
+   */
+  @Test
+  public void methodInfoTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+
+    boolean pass1, pass2, pass3, pass4 = false;
+
+    try {
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+
+      SimpleELContext simpleContext = new SimpleELContext(
+          ResolverType.VECT_ELRESOLVER);
+      ELContext context = simpleContext.getELContext();
+
+      // case 1: non-null return value
+      Class<?>[] paramTypes1 = { Object.class };
+      MethodExpression mexp1 = expFactory.createMethodExpression(context,
+          "#{vect.add}", boolean.class, paramTypes1);
+      MethodInfo minfo1 = mexp1.getMethodInfo(context);
+      pass1 = ExpressionTest.testMethodInfo(minfo1, "add", boolean.class, 1,
+          paramTypes1, buf);
+
+      // case 2: null return value
+      Class<?>[] paramTypes2 = { int.class, Object.class };
+
+      MethodExpression mexp2 = expFactory.createMethodExpression(context,
+          "#{vect.add}", null, paramTypes2);
+      MethodInfo minfo2 = mexp2.getMethodInfo(context);
+      pass2 = ExpressionTest.testMethodInfo(minfo2, "add", void.class, 2,
+          paramTypes2, buf);
+
+      // case 3: literal expression returning String
+      Class<?>[] paramTypes3 = {};
+
+      MethodExpression mexp3 = expFactory.createMethodExpression(context,
+          "true", String.class, paramTypes3);
+      MethodInfo minfo3 = mexp3.getMethodInfo(context);
+      pass3 = ExpressionTest.testMethodInfo(minfo3, "true", String.class, 0,
+          paramTypes3, buf);
+
+      // case 4: literal expression returning non-String value
+      Class<?>[] paramTypes4 = {};
+
+      MethodExpression mexp4 = expFactory.createMethodExpression(context,
+          "true", Boolean.class, paramTypes4);
+      MethodInfo minfo4 = mexp4.getMethodInfo(context);
+      pass4 = ExpressionTest.testMethodInfo(minfo4, "true", Boolean.class, 0,
+          paramTypes4, buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!(pass1 && pass2 && pass3 && pass4))
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodreference/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodreference/ELClientIT.java
new file mode 100644
index 0000000..ddd2a9e
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/methodreference/ELClientIT.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2021 Contributors to the Eclipse Foundation.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package com.sun.ts.tests.el.api.jakarta_el.methodreference;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.Fault;
+import com.sun.ts.tests.el.common.api.expression.ExpressionTest;
+import com.sun.ts.tests.el.common.elcontext.VarMapperELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.MethodsBean;
+
+import jakarta.el.ELContext;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.MethodExpression;
+import jakarta.el.MethodInfo;
+import jakarta.el.MethodNotFoundException;
+import jakarta.el.MethodReference;
+import jakarta.el.PropertyNotFoundException;
+import jakarta.el.ValueExpression;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private static final String NL = System.getProperty("line.seperator", "\n");
+
+  private Properties testProps;
+
+  public ELClientIT(){
+    this.testProps = System.getProperties();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: methodReferenceTest
+   * 
+   * @assertion_ids: EL:JAVADOC:87; EL:JAVADOC:88; EL:JAVADOC:89
+   * @test_Strategy: Validate the behavior of MethodReference class methods:
+   *                 MethodReference.getBase() MethodReference.getMethodInfo()
+   *                 MethodReference.getAnnotations()
+   *                 MethodReference.getEvaluatedParameters
+   */
+  @Test
+  public void methodReferenceTest() throws Fault {
+
+    StringBuffer buf = new StringBuffer();
+
+    boolean pass1, pass2, pass3, pass4;
+
+    try {
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      ELContext context = (new VarMapperELContext(testProps)).getELContext();
+      
+      MethodsBean bean = new MethodsBean();
+      ValueExpression ve = expFactory.createValueExpression(bean, MethodsBean.class);
+      context.getVariableMapper().setVariable("bean", ve);
+
+      // case 1: non-null return value
+      MethodExpression mexp1 = expFactory.createMethodExpression(
+          context, "#{bean.targetF('aaa',1234)}", String.class, null);
+      MethodInfo minfo1 = mexp1.getMethodInfo(context);
+      MethodReference mref1 = mexp1.getMethodReference(context);
+      pass1 = ExpressionTest.testMethodReference(mref1, bean, minfo1,
+          new Class<?>[] { Deprecated.class },
+          new Object[] { "aaa", Long.valueOf(1234) },
+          buf);
+
+      // case 2: NPE
+      try {
+        mexp1.getMethodReference(null);
+        pass2 = false;
+        buf.append("Did not get expected NullPointerException for null context." + NL);
+      } catch (NullPointerException npe) {
+        pass2 = true;
+      }
+
+      // case 3: PNFE
+      MethodExpression mexp3 = expFactory.createMethodExpression(
+          context, "#{noSuchBean.method()}", String.class, null);
+      try {
+        mexp3.getMethodReference(context);
+        pass3 = false;
+        buf.append("Did not get expected PropertyNotFoundException return for unknown bean." + NL);
+      } catch (PropertyNotFoundException pnfe) {
+        pass3 = true;
+      }
+
+      // case 4: MNFE
+      MethodExpression mexp4 = expFactory.createMethodExpression(
+          context, "#{bean.noSuchMethod()}", String.class, null);
+      try {
+        mexp4.getMethodReference(context);
+        pass4 = false;
+        buf.append("Did not get expected MethodNotFoundException return for unknown bean." + NL);
+      } catch (MethodNotFoundException mnfe) {
+        pass4 = true;
+      }
+      
+    } catch (Exception ex) {
+      logger.log(Logger.Level.ERROR, "Test getMethodReference threw an Exception!" + ELTestUtil.NL +
+          "Received: " + ex.toString() + ELTestUtil.NL);
+      ex.printStackTrace();
+      throw new Fault(ex);
+    }
+
+    if (!(pass1 && pass2 && pass3 && pass4))
+      throw new Fault(ELTestUtil.FAIL + NL + buf.toString());
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/optionalelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/optionalelresolver/ELClientIT.java
new file mode 100644
index 0000000..83c69a6
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/optionalelresolver/ELClientIT.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package com.sun.ts.tests.el.api.jakarta_el.optionalelresolver;
+
+import java.lang.System.Logger;
+import java.util.Optional;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.BeanELResolver;
+import jakarta.el.CompositeELResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.MethodNotFoundException;
+import jakarta.el.OptionalELResolver;
+import jakarta.el.PropertyNotWritableException;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : " + testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : " + testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: optionalELResolverEmptyNullTest
+   *
+   * @test_Strategy: Verify that API calls work as expected for: getValue() getType() setValue() isReadOnly()
+   * getCommonPropertyType() when the base object is an empty Optional and the property is null
+   */
+  @Test
+  public void optionalELResolverEmptyNullTest() throws Exception {
+
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+    Object testObject = Optional.empty();
+    
+    pass = testOptionalELResolverProperty(buf, testObject, null, null);
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+  
+  /**
+   * @testName: optionalELResolverEmptyNonNullTest
+   *
+   * @test_Strategy: Verify that API calls work as expected for: getValue() getType() setValue() isReadOnly()
+   * getCommonPropertyType() when the base object is an empty Optional and the property is non-null
+   */
+  @Test
+  public void optionalELResolverEmptyNonNullTest() throws Exception {
+
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+    Object testObject = Optional.empty();
+    
+    pass = testOptionalELResolverProperty(buf, testObject, "property", null);
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: optionalELResolverObjectNullTest
+   *
+   * @test_Strategy: Verify that API calls work as expected for: getValue() getType() setValue() isReadOnly()
+   * getCommonPropertyType() when the base object is an non-empty Optional and the property is null
+   */
+  @Test
+  public void optionalELResolverObjectNullTest() throws Exception {
+
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+    TestBean testBean = new TestBean("data");
+    Object testObject = Optional.of(testBean);
+    
+    pass = testOptionalELResolverProperty(buf, testObject, null, testBean);
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: optionalELResolverObjectNonNullTest
+   *
+   * @test_Strategy: Verify that API calls work as expected for: getValue() getType() setValue() isReadOnly()
+   * getCommonPropertyType() when the base object is an non-empty Optional and the property is non-null
+   */
+  @Test
+  public void optionalELResolverObjectNonNullTest() throws Exception {
+
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+    TestBean testBean = new TestBean("data");
+    Object testObject = Optional.of(testBean);
+    
+    pass = testOptionalELResolverProperty(buf, testObject, "propertyA", "data");
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  public static boolean testOptionalELResolverProperty(StringBuffer buf, Object base, Object property, Object expectedValue) {
+    boolean pass = true;
+    
+    BareBonesELContext barebonesContext = new BareBonesELContext();
+    
+    // OptionalELResolver depends on BeanELResolver to resolve properties of an object wrapped in an Optional
+    ELResolver resolver = barebonesContext.getELResolver();
+    BeanELResolver beanResolver = new BeanELResolver();
+    OptionalELResolver optionalResolver = new OptionalELResolver();
+    ((CompositeELResolver) resolver).add(optionalResolver);
+    ((CompositeELResolver) resolver).add(beanResolver);
+    
+    ELContext context = barebonesContext.getELContext();
+
+    // getValue()
+    Object result = resolver.getValue(context, base, property);
+    if (expectedValue == null && result != null || expectedValue != null && !expectedValue.equals(result)) {
+      buf.append("getValue(): Expected [" + expectedValue + "] but got [" + result + "]");
+      pass = false;
+    }
+    
+    // getType()
+    result = resolver.getType(context, base, property);
+    if (result != null) {
+      pass = false;
+    }
+    
+    // setValue()
+    try {
+      resolver.setValue(context, base, property, "anything");
+      pass = false;
+    } catch (PropertyNotWritableException pnwe) {
+      // Expected
+    }
+    
+    // isReadOnly()
+    boolean bResult = resolver.isReadOnly(context, base, property);
+    if (!bResult) {
+      pass = false;
+    }
+    
+    // getCommonPropertyType()
+    result = resolver.getCommonPropertyType(context, base);
+    if (result != Object.class) {
+      pass = false;
+    }
+
+    return pass;
+  }
+  
+  @Test
+  public void optionalELResolverEmptyInvoke() throws Exception {
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+    Object testObject = Optional.empty();
+    
+    pass = testOptionalELResolverInvoke(buf, testObject, "doSomething", null);
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+  
+  @Test
+  public void optionalELResolverEmptyInvokeInvalid() throws Exception {
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+    Object testObject = Optional.empty();
+    
+    pass = testOptionalELResolverInvoke(buf, testObject, "unknownMethod", null);
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+  
+  @Test
+  public void optionalELResolverObjectInvoke() throws Exception {
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+    TestBean testBean = new TestBean("data");
+    Object testObject = Optional.of(testBean);
+    
+    pass = testOptionalELResolverInvoke(buf, testObject, "doSomething", TestBean.DATA);
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+  
+  @Test
+  public void optionalELResolverObjectInvokeInvalid() throws Exception {
+    boolean pass = true;
+    StringBuffer buf = new StringBuffer();
+    TestBean testBean = new TestBean("data");
+    Object testObject = Optional.of(testBean);
+    
+    try {
+      testOptionalELResolverInvoke(buf, testObject, "unknownMethod", null);
+      pass = false;
+      buf.append("invoke(): Expected MethodNotFoundException but no exception was thrown"); 
+    } catch (MethodNotFoundException mnfe) {
+      // Expected (so pass is not set to false)
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+  
+  public static boolean testOptionalELResolverInvoke(StringBuffer buf, Object base, Object method, Object expectedValue) {
+    boolean pass = true;
+    
+    BareBonesELContext barebonesContext = new BareBonesELContext();
+    
+    // OptionalELResolver depends on BeanELResolver to invoke methods of an object wrapped in an Optional
+    ELResolver resolver = barebonesContext.getELResolver();
+    BeanELResolver beanResolver = new BeanELResolver();
+    OptionalELResolver optionalResolver = new OptionalELResolver();
+    ((CompositeELResolver) resolver).add(optionalResolver);
+    ((CompositeELResolver) resolver).add(beanResolver);
+    ELContext context = barebonesContext.getELContext();
+
+    // invoke()
+    Object result = resolver.invoke(context, base, method, null, null);
+    if (expectedValue == null && result != null || expectedValue != null && !expectedValue.equals(result)) {
+      buf.append("invoke(): Expected [" + expectedValue + "] but got [" + result + "]");
+      pass = false;
+    }
+    
+    return pass;
+  }
+  
+  public static class TestBean {
+    private static final String DATA = "interesting data"; 
+    private final String propertyA; 
+    public TestBean(String propertyA) {
+      this.propertyA = propertyA;
+    }
+    public String getPropertyA() {
+      return propertyA;
+    }
+    public String doSomething() {
+      return DATA;
+    }
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/recordelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/recordelresolver/ELClientIT.java
new file mode 100644
index 0000000..8d9306d
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/recordelresolver/ELClientIT.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2024 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package com.sun.ts.tests.el.api.jakarta_el.recordelresolver;
+
+import java.lang.System.Logger;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELContext;
+import jakarta.el.RecordELResolver;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : " + testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : " + testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: recordELResolverTest
+   *
+   * @test_Strategy: Verify that API calls work as expected for: arrayELResolver() getValue() getType() setValue()
+   * isReadOnly() getCommonPropertyType() getFeatureDescriptors(). Records should behave similarly to read-only beans.
+   */
+  @Test
+  public void recordELResolverTest() throws Exception {
+
+    boolean pass;
+    StringBuffer buf = new StringBuffer();
+    TestRecord testRecord = new TestRecord("valueA", "valueB");
+
+    try {
+      RecordELResolver recordResolver = new RecordELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, recordResolver, testRecord, "propertyA", "newValue", buf, true);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+  
+  
+  public record TestRecord(String propertyA, String propertyB) { }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/resourcebundleelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/resourcebundleelresolver/ELClientIT.java
new file mode 100644
index 0000000..c1c4963
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/resourcebundleelresolver/ELClientIT.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.resourcebundleelresolver;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELContext;
+import jakarta.el.ResourceBundleELResolver;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private TckResourceBundle tckrb;
+
+  public ELClientIT(){
+    tckrb = new TckResourceBundle();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: resourceBundleELResolverTest
+   *
+   * @assertion_ids: EL:JAVADOC:103; EL:JAVADOC:104; EL:JAVADOC:105;
+   *                 EL:JAVADOC:106; EL:JAVADOC:107; EL:JAVADOC:108;
+   *                 EL:JAVADOC:109
+   *
+   * @test_Strategy: Verify that API calls work as expected:
+   *                 ResourceBundleELResolver() setValue() getValue() getType()
+   *                 isReadOnly() getCommonPropertyType()
+   *                 getFeatureDescriptors()
+   */
+  @Test
+  public void resourceBundleELResolverTest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    try {
+      ResourceBundleELResolver rsbResolver = new ResourceBundleELResolver();
+      BareBonesELContext barebonesContext = new BareBonesELContext();
+      ELContext context = barebonesContext.getELContext();
+
+      pass = ResolverTest.testELResolver(context, rsbResolver, tckrb, "Dinner",
+          "DINNER", buf, true);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: resourceBundleELResolverNPETest
+   *
+   * @assertion_ids: EL:JAVADOC:106; EL:JAVADOC:105; EL:JAVADOC:107;
+   *                 EL:JAVADOC:108; EL:JAVADOC:109; EL:JAVADOC:313;
+   *                 EL:JAVADOC:314; EL:JAVADOC:316; EL:JAVADOC:317
+   *
+   * @test_Strategy: Verify that the following methods throw a
+   *                 NullPointerException, if context is null:
+   *
+   *                 getValue() getType() setValue() isReadOnly()
+   */
+  @Test
+  public void resourceBundleELResolverNPETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    ResourceBundleELResolver resolver = new ResourceBundleELResolver();
+
+    try {
+      pass = ResolverTest.testELResolverNPE(resolver, tckrb, "brunch", "BRUNCH",
+          buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  /**
+   * @testName: resourceBundleELResolverPNWETest
+   *
+   * @assertion_ids: EL:JAVADOC:108; EL:JAVADOC:109; EL:JAVADOC:318
+   *
+   * @test_Strategy: Verify that the following methods throw a
+   *                 PropertyNotWritableException, since
+   *                 ResourceBundleELResolvers are non-writable.
+   *
+   *                 setValue()
+   */
+  @Test
+  public void resourceBundleELResolverPNWETest() throws Exception {
+
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    BareBonesELContext barebonesContext = new BareBonesELContext();
+    ELContext context = barebonesContext.getELContext();
+    ResourceBundleELResolver rsbResolver = new ResourceBundleELResolver();
+
+    try {
+      pass = ResolverTest.testELResolverPNWE(context, rsbResolver, tckrb,
+          "snack", "SNACK", buf);
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    logger.log(Logger.Level.TRACE, buf.toString());
+  }
+
+  private static class TckResourceBundle extends ResourceBundle
+      implements Serializable {
+
+    private static final String KEYS = "Breakfast Lunch Dinner";
+
+    public Object handleGetObject(String key) {
+      if ("Breakfast".equals(key))
+        return "BREAKFAST";
+      if ("Lunch".equals(key))
+        return "LUNCH";
+      if ("Dinner".equals(key))
+        return "DINNER";
+
+      return null;
+    }
+
+    public Enumeration getKeys() {
+      StringTokenizer keyTokenizer = new StringTokenizer(KEYS);
+
+      return keyTokenizer;
+
+    }
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/staticfieldelresolver/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/staticfieldelresolver/ELClientIT.java
new file mode 100644
index 0000000..10ba487
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/staticfieldelresolver/ELClientIT.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.staticfieldelresolver;
+
+import java.util.Iterator;
+import java.util.Properties;
+
+
+
+import com.sun.ts.tests.el.common.api.resolver.ResolverTest;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELClass;
+import jakarta.el.ELContext;
+import jakarta.el.ELManager;
+import jakarta.el.PropertyNotFoundException;
+import jakarta.el.PropertyNotWritableException;
+import jakarta.el.StaticFieldELResolver;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: staticFieldELResolverTest
+   * 
+   * @assertion_ids: EL:JAVADOC:330; EL:JAVADOC:331; EL:JAVADOC:332;
+   *                 EL:JAVADOC:335; EL:JAVADOC:338; EL:JAVADOC:341;
+   *                 EL:JAVADOC:343; EL:JAVADOC:346; EL:JAVADOC:189;
+   *                 EL:JAVADOC:204
+   * 
+   * 
+   * @test_Strategy: Verify the following method calls work as expected:
+   *                 getValue() getType() setValue() isReadOnly()
+   *                 getCommonPropertyType() 
+   */
+  @Test
+  public void staticFieldELResolverTest() throws Exception {
+    StringBuffer buf = new StringBuffer();
+    boolean pass = true;
+
+    ELManager elm = new ELManager();
+    StaticFieldELResolver resolver = new StaticFieldELResolver();
+    elm.addELResolver(resolver);
+    ELContext context = elm.getELContext();
+
+    Object base = new ELClass(TCKELClass.class);
+    Object property = "firstName";
+    Object value = "Ender";
+
+    // setValue()
+    context.setPropertyResolved(false);
+    try {
+      resolver.setValue(context, base, property, value);
+      buf.append(ELTestUtil.FAIL + ELTestUtil.NL
+          + "Expected PropertyNotWritableException to be "
+          + "thrown when calling setValue()!" + ELTestUtil.NL
+          + "No exception was thown!" + ELTestUtil.NL);
+      pass = false;
+
+    } catch (PropertyNotWritableException pnwe) {
+      buf.append(ELTestUtil.PASS + ELTestUtil.NL
+          + "PropertyNotWritableException Thrown as expected for "
+          + "setValue()!" + ELTestUtil.NL);
+    } catch (Exception e) {
+      buf.append(ELTestUtil.FAIL + ELTestUtil.NL
+          + "Wrong Exception Thrownfor setValue()!" + ELTestUtil.NL
+          + "Expected: PropertyNotWritableException" + ELTestUtil.NL
+          + "Received: " + e.getClass().getSimpleName() + ELTestUtil.NL);
+    }
+
+    // getValue()
+    context.setPropertyResolved(false);
+    Object valueRetrieved = resolver.getValue(context, base, property);
+    if (!context.isPropertyResolved()) {
+      buf.append("getValue() did not resolve" + ELTestUtil.NL);
+      pass = false;
+    }
+
+    if (valueRetrieved != value) {
+      buf.append("Invalid value from getValue():" + ELTestUtil.NL
+          + "Value expected: " + value.toString() + ELTestUtil.NL
+          + "Value retrieved: " + valueRetrieved.toString()
+          + ELTestUtil.NL);
+      pass = false;
+    }
+
+    // getType()
+    context.setPropertyResolved(false);
+    Class<?> type = resolver.getType(context, base, property);
+    if (!context.isPropertyResolved()) {
+      buf.append("getType() did not resolve" + ELTestUtil.NL);
+      pass = false;
+    } else if (type != null) {
+      buf.append("getType() returns " + type.getName() + " rather than null" + ELTestUtil.NL);
+      pass = false;
+    } else {
+      buf.append("getType() returns null" + ELTestUtil.NL + "as expected." + ELTestUtil.NL);
+    }
+
+    // isReadOnly
+    context.setPropertyResolved(false);
+    boolean nonWritable = resolver.isReadOnly(context, base, property);
+    if (!context.isPropertyResolved()) {
+      buf.append("isReadOnly() did not resolve" + ELTestUtil.NL);
+      pass = false;
+
+    } else if (!nonWritable) {
+      buf.append("isReadOnly() returned unexpected value: " + ELTestUtil.NL
+          + "Expected: false" + ELTestUtil.NL + "Received: " + nonWritable
+          + ELTestUtil.NL);
+      pass = false;
+
+    } else {
+      buf.append("isReadOnly() returns false as expected" + ELTestUtil.NL);
+    }
+
+    // getCommonPropertyType()
+    context.setPropertyResolved(false);
+    Class<?> commonPropertyType = (resolver.getCommonPropertyType(context,
+        base));
+    buf.append("getCommonPropertyType() returns " + commonPropertyType.getName()
+        + ELTestUtil.NL);
+
+    // getFeatureDescriptors() commenting below as the method is deprecated in EL 6.0
+    // context.setPropertyResolved(false);
+    // Iterator<?> i = resolver.getFeatureDescriptors(context, base);
+
+    // if (i == null) {
+    //   buf.append("getFeatureDescriptors() returns null" + ELTestUtil.NL);
+    // }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + ELTestUtil.NL + buf.toString());
+    }
+
+  } // End staticFieldELResolverTest
+
+  /**
+   * @testName: staticFieldResolverInvokeMNFETest
+   * 
+   * @assertion_ids: EL:JAVADOC:339; EL:JAVADOC:189; EL:JAVADOC:204
+   * 
+   * @test_Strategy: Verify that the invoke() method throws
+   *                 MethodNotFoundException if no suitable method can be found.
+   */
+  @Test
+  public void staticFieldResolverInvokeMNFETest() throws Exception {
+    StringBuffer buf = new StringBuffer();
+    boolean pass = false;
+
+    ELManager elm = new ELManager();
+    StaticFieldELResolver resolver = new StaticFieldELResolver();
+    elm.addELResolver(resolver);
+    ELContext context = elm.getELContext();
+
+    Class<?>[] types = { String.class, String.class };
+    String[] values = { "Doug", "Donahue" };
+
+    try {
+      pass = ResolverTest.testELResolverInvoke(context, context.getELResolver(),
+          new ELClass(TCKELClass.class), "bogue_method", types, values, true,
+          buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+    logger.log(Logger.Level.INFO, buf.toString());
+
+  }// End staticFieldResolverInvokeMNFETest
+
+  /**
+   * @testName: staticFieldELResolverInvokeTest
+   * 
+   * @assertion_ids: EL:JAVADOC:338; EL:JAVADOC:189; EL:JAVADOC:204
+   * 
+   * @test_Strategy: Verify that API calls work as expected for
+   *                 BeanNameELResolver.invoke().
+   */
+  @Test
+  public void staticFieldELResolverInvokeTest() throws Exception {
+    StringBuffer buf = new StringBuffer();
+    boolean pass = false;
+
+    ELManager elm = new ELManager();
+    StaticFieldELResolver resolver = new StaticFieldELResolver();
+    elm.addELResolver(resolver);
+    ELContext context = elm.getELContext();
+
+    Class<?>[] types = { String.class };
+    String[] values = { "Ender" };
+
+    try {
+      pass = ResolverTest.testELResolverInvoke(context, context.getELResolver(),
+          new ELClass(TCKELClass.class), "isName", types, values, false, buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+
+    logger.log(Logger.Level.INFO, buf.toString());
+
+  }// End staticFieldELResolverInvokeTest
+
+  /**
+   * @testName: staticFieldELResolverNPETest
+   * 
+   * @assertion_ids: EL:JAVADOC:333; EL:JAVADOC:336; EL:JAVADOC:342;
+   *                 EL:JAVADOC:344; EL:JAVADOC:189
+   * 
+   * @test_Strategy: Verify that the following methods throw a
+   *                 NullPointerException, if context is null:
+   * 
+   *                 getType() getValue() isReadOnly() setValue()
+   */
+  @Test
+  public void staticFieldELResolverNPETest() throws Exception {
+    boolean pass = false;
+    StringBuffer buf = new StringBuffer();
+
+    ELManager elm = new ELManager();
+    StaticFieldELResolver resolver = new StaticFieldELResolver();
+    elm.addELResolver(resolver);
+
+    try {
+      pass = ResolverTest.testELResolverNPE(resolver,
+          new ELClass(TCKELClass.class), "intention", "billy", buf);
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+
+    logger.log(Logger.Level.TRACE, buf.toString());
+
+  } // End staticFieldELResolverNPETest
+
+  /**
+   * @testName: staticFieldResolverInvokePNFETest
+   * 
+   * @assertion_ids: EL:JAVADOC:334; EL:JAVADOC:337
+   * 
+   * @test_Strategy: Verify that the invoke() method throws
+   *                 PropertyNotFoundException the specified class does not
+   *                 exist, or if the field is not a public static filed of the
+   *                 class, or if the field is inaccessible.
+   */
+  @Test
+  public void staticFieldResolverInvokePNFETest() throws Exception {
+
+    Object base = new ELClass(TCKELClass.class);
+
+    // Test for non static field
+    testForPNFE("notStatic", base);
+
+    // Test for Private static field
+    testForPNFE("privStatic", base);
+
+    // Test for non existent Class
+    testForPNFE("privStatic", "bogus");
+
+  }// End staticFieldResolverInvokePNFETest
+
+  // ------------------------- private methods
+
+  private void testForPNFE(String property, Object base) {
+    StringBuffer buf = new StringBuffer();
+
+    ELManager elm = new ELManager();
+    StaticFieldELResolver resolver = new StaticFieldELResolver();
+    elm.addELResolver(resolver);
+    ELContext context = elm.getELContext();
+
+    // getType()
+    try {
+      resolver.getType(context, base, property);
+      buf.append(ELTestUtil.FAIL + " getType() did not throw any exception."
+          + ELTestUtil.NL + "Expected: PropertyNotFoundException "
+          + ELTestUtil.NL);
+
+    } catch (PropertyNotFoundException pnfe) {
+      buf.append(ELTestUtil.PASS);
+
+    } catch (Exception e) {
+      buf.append(ELTestUtil.FAIL + "Wrong Exception thrown for getType()!"
+          + ELTestUtil.NL + " Expected: PropertyNotFoundException"
+          + ELTestUtil.NL + "Received: " + e.getClass().getSimpleName());
+    }
+
+    // getValue()
+    try {
+      resolver.getValue(context, base, property);
+      buf.append(ELTestUtil.FAIL + " getValue() did not throw any exception."
+          + ELTestUtil.NL + "Expected: PropertyNotFoundException "
+          + ELTestUtil.NL);
+
+    } catch (PropertyNotFoundException pnfe) {
+      buf.append(ELTestUtil.PASS);
+
+    } catch (Exception e) {
+      buf.append(ELTestUtil.FAIL + "Wrong Exception thrown getValue()!"
+          + ELTestUtil.NL + " Expected: PropertyNotFoundException"
+          + ELTestUtil.NL + "Received: " + e.getClass().getSimpleName());
+    }
+
+  }// End testForPNFE
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/staticfieldelresolver/TCKELClass.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/staticfieldelresolver/TCKELClass.java
new file mode 100644
index 0000000..01324d9
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/staticfieldelresolver/TCKELClass.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.staticfieldelresolver;
+
+public class TCKELClass {
+  public static String firstName = "Ender";
+
+  public static String lastName = "Wiggins";
+
+  // Not writable from StaticFieldELResolver
+  public String notStatic = "notStatic";
+
+  private static String privStatic = "privStatic";
+
+  /**
+   * 
+   * @param firstName
+   *          - first name @String
+   * @param lastName
+   *          - last Name
+   * @return true is full name matches the given firstName + " " + lastName
+   *         pattern.
+   */
+  public static boolean isName(String name) {
+    boolean result = Boolean.FALSE;
+
+    if (name.equals(firstName)) {
+      result = true;
+    }
+
+    return result;
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/valueexpression/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/valueexpression/ELClientIT.java
new file mode 100644
index 0000000..f10d364
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/valueexpression/ELClientIT.java
@@ -0,0 +1,548 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.valueexpression;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+
+
+
+import com.sun.ts.tests.el.common.api.expression.ExpressionTest;
+import com.sun.ts.tests.el.common.elcontext.BareBonesELContext;
+import com.sun.ts.tests.el.common.elcontext.SimpleELContext;
+import com.sun.ts.tests.el.common.elcontext.VRContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.PropertyNotFoundException;
+import jakarta.el.ValueExpression;
+import jakarta.el.ValueReference;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private Hashtable<Class<?>, Object> testValueTable;
+
+  private Properties testProps;
+
+  public ELClientIT(){
+    this.initializeTable();
+    this.testProps=System.getProperties();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: positiveValueExpressionTest
+   * @assertion_ids: EL:JAVADOC:110; EL:JAVADOC:111; EL:JAVADOC:112;
+   *                 EL:JAVADOC:113; EL:JAVADOC:114; EL:JAVADOC:60;
+   *                 EL:JAVADOC:58
+   * @test_Strategy: Validate the behavior of ValueExpression API
+   *                 ValueExpression.getValue() ValueExpression.setValue()
+   *                 ValueExpression.getType() ValueExpression.getExpectedType()
+   *                 ValueExpression.isReadOTestUtil.NEW_LINEy()
+   *                 Expression.isLiteralText() Expression.getExpressionString()
+   */
+  @Test
+  public void positiveValueExpressionTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+
+    boolean pass1, pass2, pass3, pass4;
+
+    try {
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+
+      ELContext context = (new SimpleELContext()).getELContext();
+      ELResolver resolver = context.getELResolver();
+      resolver.setValue(context, null, "foo", "bar");
+
+      // string variable
+      // readOTestUtil.NEW_LINEy() and isLiteralText() expected to return false
+      buf.append("Testing expression 1 " + ELTestUtil.NL);
+      String exprStr1 = "${foo}";
+      ValueExpression vexp1 = expFactory.createValueExpression(context,
+          exprStr1, String.class);
+      pass1 = ExpressionTest.testValueExpression(vexp1, context, exprStr1,
+          String.class, "bar", false, false, buf);
+
+      // literal expression
+      // readOTestUtil.NEW_LINEy() and isLiteralText() expected to return true
+      buf.append("Testing expression 2 " + ELTestUtil.NL);
+      String exprStr2 = "foo";
+      ValueExpression vexp2 = expFactory.createValueExpression(context,
+          exprStr2, String.class);
+      pass2 = ExpressionTest.testValueExpression(vexp2, context, exprStr2,
+          String.class, "foo", true, true, buf);
+
+      // expression that is not an l-value
+      // readOTestUtil.NEW_LINEy() expected to return true
+      // isLiteralText() expected to return false
+      buf.append("Testing expression 3 " + ELTestUtil.NL);
+      String exprStr3 = "#{1 + 1}";
+      ValueExpression vexp3 = expFactory.createValueExpression(context,
+          exprStr3, Integer.class);
+      pass3 = ExpressionTest.testValueExpression(vexp3, context, exprStr3,
+          Integer.class, Integer.valueOf(2), true, false, buf);
+
+      // Expression test for ValueReference.
+      buf.append("Testing expression 4 " + ELTestUtil.NL);
+      pass4 = true;
+
+      ELContext contextTwo = new VRContext(testProps);
+      String exprStr4 = "#{worker.lastName}";
+
+      ValueExpression vexp4 = expFactory.createValueExpression(contextTwo,
+          exprStr4, String.class);
+
+      ValueReference vr = vexp4.getValueReference(contextTwo);
+
+      if (vr == null) {
+        pass4 = false;
+        buf.append("ValueRefernce should have return a non null " + "value.");
+      } else {
+        Object base = vr.getBase();
+
+        if (base != null) {
+          String baseName = base.getClass().getSimpleName();
+          if (!"Worker".equals(baseName)) {
+            buf.append("Unexpected Base Value!" + ELTestUtil.NL
+                + "Expected: Worker" + ELTestUtil.NL + "Received: "
+                + baseName);
+            pass4 = false;
+          }
+        }
+      }
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+    }
+
+    if ((pass1 && pass2 && pass3 && pass4)) {
+      logger.log(Logger.Level.TRACE, buf.toString());
+
+    } else {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+  }
+
+  /**
+   * @testName: negativeValueExpressionTest
+   * @assertion_ids: EL:JAVADOC:111; EL:JAVADOC:112; EL:JAVADOC:113;
+   *                 EL:JAVADOC:114; EL:JAVADOC:368; EL:JAVADOC:371;
+   *                 EL:JAVADOC:372; EL:JAVADOC:375; EL:JAVADOC:376;
+   *                 EL:JAVADOC:378; EL:JAVADOC:379; EL:JAVADOC:380
+   * 
+   * @test_Strategy: Validate the behavior of ValueExpression API
+   *                 ValueExpression.getValue() ValueExpression.setValue()
+   *                 ValueExpression.getType()
+   *                 ValueExpression.isReadOTestUtil.NEW_LINEy()
+   * 
+   *                 If the ELContext parameter for these methods is null, a
+   *                 NullPointerException is thrown. If the ELContext parameter
+   *                 is not the same as the one with which the ValueExpression
+   *                 was created, a PropertyNotFoundException is thrown.
+   */
+  @Test
+  public void negativeValueExpressionTest() throws Exception {
+
+    boolean pass = true;
+
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    ELContext simpleContext = (new SimpleELContext()).getELContext();
+    ELContext emptyContext = (new BareBonesELContext()).getELContext();
+
+    ELResolver resolver = simpleContext.getELResolver();
+
+    try {
+      resolver.setValue(simpleContext, null, "foo", "bar");
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    String exprStr = "${foo}";
+
+    ValueExpression vexp = expFactory.createValueExpression(simpleContext,
+        exprStr, String.class);
+
+    // NullPointerException
+    try {
+      vexp.getValue(null);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getValue() with null ELContext parameter "
+          + "did not" + ELTestUtil.NL + " cause an exception to be thrown"
+          + ELTestUtil.NL);
+
+    } catch (NullPointerException npe) {
+      pass = true;
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getValue() with null ELContext "
+          + "parameter caused an exception to be thrown, but it was not a"
+          + ELTestUtil.NL + " NullPointerException: " + e.toString()
+          + ELTestUtil.NL);
+    }
+
+    try {
+      vexp.setValue(null, "foo");
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to setValue() with null ELContext parameter "
+          + "did not" + ELTestUtil.NL + " cause an exception to be thrown"
+          + ELTestUtil.NL);
+
+    } catch (NullPointerException npe) {
+      pass = true;
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to setValue() with null ELContext "
+          + "parameter caused" + ELTestUtil.NL
+          + " an exception to be thrown, but it was not a" + ELTestUtil.NL
+          + " NullPointerException: " + e.toString() + ELTestUtil.NL);
+    }
+
+    try {
+      vexp.isReadOnly(null);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to isReadOTestUtil.NEW_LINEy() with null ELContext "
+          + "parameter did not" + ELTestUtil.NL
+          + " cause an exception to be thrown" + ELTestUtil.NL);
+
+    } catch (NullPointerException npe) {
+      pass = true;
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to isReadOTestUtil.NEW_LINEy() with null ELContext "
+          + "parameter caused" + ELTestUtil.NL
+          + "an exception to be thrown, but it was not a" + ELTestUtil.NL
+          + "NullPointerException: " + e.toString() + ELTestUtil.NL);
+    }
+
+    try {
+      vexp.getType(null);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getType() with null ELContext parameter "
+          + "did not" + ELTestUtil.NL + "cause an exception to be thrown"
+          + ELTestUtil.NL);
+
+    } catch (NullPointerException npe) {
+      pass = true;
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getType() with null ELContext parameter "
+          + "caused" + ELTestUtil.NL
+          + "an exception to be thrown, but it was not a" + ELTestUtil.NL
+          + "NullPointerException: " + e.toString() + ELTestUtil.NL);
+    }
+
+    // PropertyNotFoundException
+    try {
+      vexp.setValue(emptyContext, "foo");
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to setValue() for non-existent property did "
+          + "not cause" + ELTestUtil.NL + "an exception to be thrown"
+          + ELTestUtil.NL);
+
+    } catch (PropertyNotFoundException pnfe) {
+      pass = true;
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to setValue() for non-existent property "
+          + "caused an exception to be thrown, but it was not a"
+          + ELTestUtil.NL + "PropertyNotFoundException: " + e.toString()
+          + ELTestUtil.NL);
+    }
+
+    try {
+      vexp.getValue(emptyContext);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getValue() for non-existent property did "
+          + "not cause an exception to be thrown" + ELTestUtil.NL);
+
+    } catch (PropertyNotFoundException pnfe) {
+      pass = true;
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getValue() for non-existent property "
+          + "caused an exception to be thrown, but it was not a PropertyNotFoundException: "
+          + ELTestUtil.NL + e.toString() + ELTestUtil.NL);
+    }
+
+    try {
+      vexp.isReadOnly(emptyContext);
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to isReadOTestUtil.NEW_LINEy() for non-existent property did "
+              + "not cause an exception to be thrown" + ELTestUtil.NL);
+
+    } catch (PropertyNotFoundException pnfe) {
+      pass = true;
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, 
+          "Call to isReadOTestUtil.NEW_LINEy() for non-existent property "
+              + "caused an exception to be thrown, but it was not a"
+              + " PropertyNotFoundException: " + ELTestUtil.NL
+              + e.toString() + ELTestUtil.NL);
+    }
+
+    try {
+      vexp.getType(emptyContext);
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getType() for non-existent property did not "
+          + "cause an exception to be thrown" + ELTestUtil.NL);
+
+    } catch (PropertyNotFoundException pnfe) {
+      pass = true;
+
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Call to getType() for non-existent property "
+          + "caused an exception to be thrown, but it was not a"
+          + ELTestUtil.NL + " PropertyNotFoundException: " + e.toString()
+          + ELTestUtil.NL);
+    }
+
+    if (!pass) {
+      throw new Exception(ELTestUtil.FAIL);
+    }
+  }
+
+  /**
+   * @testName: valueExpressionSerializableTest
+   * 
+   * @assertion_ids: EL:SPEC:44
+   * 
+   * @test_Strategy: Validate that ValueExpression implements Serializable and
+   *                 that a ValueExpression can be manually serialized and
+   *                 deserialized.
+   */
+  @Test
+  public void valueExpressionSerializableTest() throws Exception {
+
+    boolean pass;
+
+    StringBuffer buf = new StringBuffer();
+    Enumeration<?> keys = testValueTable.keys();
+    Class<?> testClass;
+    Object testValue;
+
+    while (keys.hasMoreElements()) {
+      pass = true;
+      testClass = (Class<?>) keys.nextElement();
+      testValue = testValueTable.get(testClass);
+
+      try {
+        ExpressionFactory expFactory = ExpressionFactory.newInstance();
+        ELContext context = (new SimpleELContext()).getELContext();
+
+        // Set eval-expression.
+        ValueExpression evalvexp = expFactory.createValueExpression(context,
+            "${" + testValue + "}", testClass);
+        logger.log(Logger.Level.TRACE, "Eval Value Expression For Testing: "
+            + evalvexp.toString() + ELTestUtil.NL);
+
+        // Set literal-expression
+        ValueExpression literalvexp = expFactory.createValueExpression(context,
+            "\"" + testValue + "\"", testClass);
+        logger.log(Logger.Level.TRACE, "Literal Value Expression For Testing: "
+            + literalvexp.toString() + ELTestUtil.NL);
+
+        // Set Composite Expression
+        ValueExpression compositevexp = expFactory.createValueExpression(
+            context, "#{" + testValue + "}" + " " + testValue, testClass);
+        logger.log(Logger.Level.TRACE, "Composite Value Expression For Testing: "
+            + compositevexp.toString() + ELTestUtil.NL);
+
+        // Test eval, literal, & composite expressions.
+        if (!(ExpressionTest.expressionSerializableTest(evalvexp, buf)
+            && ExpressionTest.expressionSerializableTest(literalvexp, buf)
+            && ExpressionTest.expressionSerializableTest(compositevexp, buf))) {
+          pass = false;
+          break;
+        }
+
+      } catch (Exception ex) {
+        throw new Exception(ex);
+
+      }
+
+      if (pass) {
+        logger.log(Logger.Level.TRACE, buf.toString());
+      } else {
+        throw new Exception(ELTestUtil.FAIL + buf.toString());
+      }
+    }
+  }
+
+  /*
+   * The HashTable is of this format.
+   * 
+   * Key = Test Class Value = Test Value
+   */
+  private void initializeTable() {
+    testValueTable = new Hashtable<Class<?>, Object>();
+
+    testValueTable.put(String.class, "SERIAL");
+    testValueTable.put(Integer.class, Integer.valueOf("123"));
+    testValueTable.put(Boolean.class, Boolean.TRUE);
+  }
+
+  /**
+   * @testName: valueExpressionEqualsTest
+   * 
+   * @assertion_ids: EL:JAVADOC:56
+   * 
+   * @test_Strategy: Validate that ValueExpression implements equals() and that
+   *                 the behavior is as expected
+   */
+  @Test
+  public void valueExpressionEqualsTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+
+    boolean pass = true;
+
+    try {
+
+      ExpressionFactory expFactory = ExpressionFactory.newInstance();
+      SimpleELContext context = new SimpleELContext();
+      ELResolver resolver = context.getELResolver();
+
+      // case 1: Expressions of the same type and equal value, but
+      // different parsed representations are NOT equal.
+      String exprStr1 = "${foo}";
+      String exprStr2 = "${bar}";
+      resolver.setValue(context, null, "foo", "SOME VALUE");
+      resolver.setValue(context, null, "bar", "SOME VALUE");
+
+      ValueExpression vexp1 = expFactory.createValueExpression(context,
+          exprStr1, String.class);
+      ValueExpression vexp2 = expFactory.createValueExpression(context,
+          exprStr2, String.class);
+
+      buf.append("vexp1 has value " + (String) vexp1.getValue(context)
+          + ELTestUtil.NL);
+      buf.append("vexp2 has value " + (String) vexp2.getValue(context)
+          + ELTestUtil.NL);
+
+      if (ExpressionTest.equalsTest(vexp1, vexp2, buf)) {
+        pass = false;
+        buf.append(
+            "Failed: case 1: same type and equal value" + ELTestUtil.NL);
+      }
+
+      // case 2: White space is ignored
+      String exprStr3 = "${A+B+C}";
+      String exprStr4 = "${ A + B	+		C	}";
+
+      ValueExpression vexp3 = expFactory.createValueExpression(context,
+          exprStr3, Object.class);
+      ValueExpression vexp4 = expFactory.createValueExpression(context,
+          exprStr4, Object.class);
+
+      if (!ExpressionTest.equalsTest(vexp3, vexp4, buf)) {
+        buf.append("Failed: case 2: white space" + ELTestUtil.NL);
+        pass = false;
+      }
+
+      // case 3: Equivalent Operators
+      String exprStr5 = "${A < B}";
+      String exprStr6 = "${A lt B}";
+
+      ValueExpression vexp5 = expFactory.createValueExpression(context,
+          exprStr5, Object.class);
+      ValueExpression vexp6 = expFactory.createValueExpression(context,
+          exprStr6, Object.class);
+
+      if (!ExpressionTest.equalsTest(vexp5, vexp6, buf)) {
+        buf.append("Failed: case 3: equivalent operators" + ELTestUtil.NL);
+        pass = false;
+      }
+
+      // case 4: Reversed operands
+      String exprStr7 = "${A + B}";
+      String exprStr8 = "${B + A}";
+
+      ValueExpression vexp7 = expFactory.createValueExpression(context,
+          exprStr7, Object.class);
+      ValueExpression vexp8 = expFactory.createValueExpression(context,
+          exprStr8, Object.class);
+
+      if (ExpressionTest.equalsTest(vexp7, vexp8, buf)) {
+        buf.append("Failed: case 4: reversed operands" + ELTestUtil.NL);
+        pass = false;
+      }
+
+      // case 5: '$' and '#' delimiters are parsed the same
+      String exprStr9 = "${A}";
+      String exprStr10 = "#{A}";
+
+      ValueExpression vexp9 = expFactory.createValueExpression(context,
+          exprStr9, Object.class);
+      ValueExpression vexp10 = expFactory.createValueExpression(context,
+          exprStr10, Object.class);
+
+      if (!ExpressionTest.equalsTest(vexp9, vexp10, buf)) {
+        buf.append("Failed: case 5: delimiters" + ELTestUtil.NL);
+        pass = false;
+      }
+
+    } catch (Exception ex) {
+      throw new Exception(ex);
+
+    }
+
+    if (pass) {
+      logger.log(Logger.Level.TRACE, buf.toString());
+    } else {
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+    }
+
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/valueexpression/Worker.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/valueexpression/Worker.java
new file mode 100644
index 0000000..e1a0818
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/valueexpression/Worker.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.valueexpression;
+
+public class Worker {
+  private String firstName = "Doug";
+
+  private String lastName = "Donahue";
+
+  /**
+   * @return the lastName
+   */
+  public String getLastName() {
+    return lastName;
+  }
+
+  /**
+   * @param lastName
+   *          the lastName to set
+   */
+  public void setLastName(String lastName) {
+    this.lastName = lastName;
+  }
+
+  /**
+   * @return the firstName
+   */
+  public String getFirstName() {
+    return firstName;
+  }
+
+  /**
+   * @param firstName
+   *          the firstName to set
+   */
+  public void setFirstName(String firstName) {
+    this.firstName = firstName;
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/variablemapper/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/variablemapper/ELClientIT.java
new file mode 100644
index 0000000..4e13c10
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/api/jakarta_el/variablemapper/ELClientIT.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id: $
+ */
+
+package com.sun.ts.tests.el.api.jakarta_el.variablemapper;
+
+import java.util.Properties;
+
+
+
+import com.sun.ts.tests.el.common.elcontext.VarMapperELContext;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ExpressionFactory;
+import jakarta.el.ValueExpression;
+import jakarta.el.VariableMapper;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private Properties testProps;
+
+  public ELClientIT() {
+    this.testProps=System.getProperties();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: variableMapperTest
+   * 
+   * @assertion_ids: EL:JAVADOC:37; EL:JAVADOC:116; EL:JAVADOC:117
+   * @test_Strategy: Validate the behavior of ELContext.getVariableMapper()
+   *                 VariableMapper.resolveVariable()
+   *                 VariableMapper.setVariable()
+   */
+  @Test
+  public void variableMapperTest() throws Exception {
+
+    StringBuffer buf = new StringBuffer();
+
+    boolean pass = true;
+    
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    VarMapperELContext context = new VarMapperELContext(testProps);
+    VariableMapper varMapper = context.getVariableMapper();
+    logger.log(Logger.Level.TRACE, "VariableMapper is " + varMapper.toString());
+
+    if (varMapper.resolveVariable("foo") != null) {
+      pass = false;
+      buf.append("Expected call to resolveVariable() to unassigned "
+          + "variable to return null" + ELTestUtil.NL
+          + "Instead call returned " + varMapper.resolveVariable("foo")
+          + ELTestUtil.NL);
+    }
+
+    ValueExpression vexp1 = expFactory.createValueExpression(context, "${bar}",
+        String.class);
+    ValueExpression vexp2 = varMapper.setVariable("foo", vexp1);
+
+    if (vexp2 != null) {
+      pass = false;
+      buf.append("Expected call to setVariable() to return null "
+          + "for previously unassigned variable" + ELTestUtil.NL
+          + "Instead return value was " + vexp2 + ELTestUtil.NL);
+    }
+
+    ValueExpression vexp3 = varMapper.resolveVariable("foo");
+
+    if (!vexp3.equals(vexp1)) {
+      pass = false;
+      buf.append("Expected call to resolveVariable() to assigned "
+          + "variable to return " + vexp1.toString() + ELTestUtil.NL
+          + "Instead call returned " + vexp3.toString() + ELTestUtil.NL);
+    }
+
+    ValueExpression vexp4 = varMapper.setVariable("foo", null);
+
+    if (!vexp4.equals(vexp1)) {
+      pass = false;
+      buf.append("Expected call to resolveVariable() to assigned "
+          + "variable to return " + vexp1.toString() + ELTestUtil.NL
+          + "Instead call returned " + vexp4.toString() + ELTestUtil.NL);
+    }
+
+    ValueExpression vexp5 = varMapper.resolveVariable("foo");
+
+    if (vexp5 != null) {
+      pass = false;
+      buf.append("Expected call to resolveVariable() to return null"
+          + " after unassignment" + ELTestUtil.NL
+          + "Instead return value was " + vexp5 + ELTestUtil.NL);
+    }
+
+    if (!pass)
+      throw new Exception(ELTestUtil.FAIL + buf.toString());
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/api/expression/ExpressionTest.java b/tck/src/main/java/com/sun/ts/tests/el/common/api/expression/ExpressionTest.java
new file mode 100644
index 0000000..6148785
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/api/expression/ExpressionTest.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2009, 2021 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.api.expression;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.annotation.Annotation;
+
+import jakarta.el.ELContext;
+import jakarta.el.Expression;
+import jakarta.el.MethodExpression;
+import jakarta.el.MethodInfo;
+import jakarta.el.MethodReference;
+import jakarta.el.PropertyNotWritableException;
+import jakarta.el.ValueExpression;
+
+public class ExpressionTest {
+
+  // Set New Line from system prop, if not defined used "\n as default."
+  private static final String NLINE = System.getProperty("line.separator",
+      "\n");
+
+  private ExpressionTest() {
+  }
+
+  public static boolean testMethodInfo(MethodInfo minfo, String expectedName,
+      Class expectedReturnType, int expectedNumParams,
+      Class[] expectedParamTypes, StringBuffer buf) {
+
+    boolean pass = true;
+    String name = minfo.getName();
+    Class returnType = minfo.getReturnType();
+    Class[] paramTypes = minfo.getParamTypes();
+    int numParams = paramTypes.length;
+
+    if (!name.equals(expectedName)) {
+      buf.append("Did not get expected method name." + NLINE);
+      buf.append("Expected name = " + expectedName + NLINE);
+      buf.append("Computed name = " + name + NLINE);
+      pass = false;
+    }
+    if (!returnType.equals(expectedReturnType)) {
+      buf.append("Did not get expected return type." + NLINE);
+      buf.append(
+          "Expected return type = " + expectedReturnType.getName() + NLINE);
+      buf.append("Computed return type = " + returnType.getName() + NLINE);
+      pass = false;
+    }
+    if (numParams != expectedNumParams) {
+      buf.append("Did not get expected number of parameters." + NLINE);
+      buf.append(
+          "Expected number of parameters = " + expectedNumParams + NLINE);
+      buf.append("Computed number of parameters = " + numParams + NLINE);
+      pass = false;
+    } else {
+      for (int i = 0; i < numParams; ++i) {
+        if (!(paramTypes[i].equals(expectedParamTypes[i]))) {
+          buf.append("Did not get expected parameter type." + NLINE);
+          buf.append("Expected parameter type = "
+              + expectedParamTypes[i].getName() + NLINE);
+          buf.append(
+              "Computed parameter type = " + paramTypes[i].getName() + NLINE);
+          pass = false;
+        }
+      }
+    }
+    return pass;
+  }
+
+  public static boolean testMethodReference(MethodReference mref,
+      Object expectedBase, MethodInfo expectedMethodInfo,
+      Class<?>[] expectedAnnotationTypes,
+      Object[] expectedParamValues, StringBuffer buf) {
+
+    boolean pass = true;
+    
+    Object base = mref.getBase();
+    MethodInfo minfo = mref.getMethodInfo();
+    Annotation[] annotations = mref.getAnnotations();
+    Object[] parameterValues = mref.getEvaluatedParameters();
+    
+    if (base == null) {
+      buf.append("Did not get expected base object." + NLINE);
+      buf.append("Expected base = " + expectedBase + NLINE);
+      buf.append("Computed name = null" + NLINE);
+      pass = false;
+    } else if (!base.equals(expectedBase)) {
+      buf.append("Did not get expected base object." + NLINE);
+      buf.append("Expected base = " + expectedBase + NLINE);
+      buf.append("Computed base = " + base + NLINE);
+      pass = false;
+    }
+
+    if (minfo == null) {
+      buf.append("Did not get expected MethodInfo object." + NLINE);
+      buf.append("Expected MethodInfo = " + expectedMethodInfo + NLINE);
+      buf.append("Computed MethodInfo = null" + NLINE);
+      pass = false;
+    } else if (!minfo.equals(expectedMethodInfo)) {
+      buf.append("Did not get expected base object." + NLINE);
+      buf.append("Expected MethodInfo = " + expectedMethodInfo + NLINE);
+      buf.append("Computed MethodInfo = " + minfo + NLINE);
+      pass = false;
+    }
+
+    if (annotations == null) {
+      buf.append("Did not get expected annotation array." + NLINE);
+      buf.append("Computed array was null" + NLINE);
+      pass = false;
+    } else if (annotations.length != expectedAnnotationTypes.length) {
+      buf.append("Did not get expected number of annotations." + NLINE);
+      buf.append("Expected annotation array length = " + expectedAnnotationTypes.length + NLINE);
+      buf.append("Computed annotation array length = " + annotations.length + NLINE);
+      pass = false;
+    } else {
+      for (int i = 0; i < annotations.length; i++) {
+        if (!annotations[i].annotationType().equals(expectedAnnotationTypes[i])) {
+          buf.append("Did not get expected annotation type for array index = " + i + NLINE);
+          buf.append("Expected type = " + expectedAnnotationTypes[i] + NLINE);
+          buf.append("Computed type = " + annotations[i].getClass() + NLINE);
+          pass = false;
+        }
+      }
+    }
+
+    if (parameterValues == null) {
+      buf.append("Did not get expected parameter value array." + NLINE);
+      buf.append("Computed array was null" + NLINE);
+      pass = false;
+    } else if (parameterValues.length != expectedParamValues.length) {
+      buf.append("Did not get expected number of parameter values." + NLINE);
+      buf.append("Expected annotation array length = " + expectedParamValues.length + NLINE);
+      buf.append("Computed annotation array length = " + parameterValues.length + NLINE);
+      pass = false;
+    } else {
+      for (int i = 0; i < parameterValues.length; i++) {
+        if (!parameterValues[i].equals(expectedParamValues[i])) {
+          buf.append("Did not get expected parameter value for array index = " + i + NLINE);
+          buf.append("Expected type = " + expectedParamValues[i] + NLINE);
+          buf.append("Computed type = " + parameterValues[i] + NLINE);
+          pass = false;
+        }
+      }
+    }
+
+    return pass;
+  }
+
+  public static boolean testValueExpression(ValueExpression vexp,
+      ELContext context, String exprStr, Class expectedType,
+      Object expectedValue, boolean expectedReadOnly,
+      boolean expectedLiteralText, StringBuffer buf) {
+
+    boolean pass = true;
+
+    // getValue()
+    Object retrievedValue = vexp.getValue(context);
+    if (!retrievedValue.equals(expectedValue)) {
+      pass = false;
+      buf.append("getValue() does not return expected value" + NLINE);
+      buf.append("Expected value = " + expectedValue.toString() + NLINE);
+      buf.append("Computed value = " + retrievedValue.toString() + NLINE);
+    }
+
+    // setValue()
+    try {
+      vexp.setValue(context, "blue");
+      String newValue = (String) vexp.getValue(context);
+      if (expectedReadOnly) {
+        pass = false;
+        buf.append("setValue() succeeded on a read-only value" + NLINE);
+      } else if (!newValue.equals("blue")) {
+        pass = false;
+        buf.append(
+            "Did not get correct set value for " + "ValueExpression." + NLINE);
+        buf.append("Expected value = " + "blue" + NLINE);
+        buf.append("Computed value = " + newValue + NLINE);
+      }
+    } catch (PropertyNotWritableException pnwe) {
+      if (!expectedReadOnly) {
+        pass = false;
+        buf.append(
+            "setValue() threw " + "PropertyNotWritableException" + NLINE);
+        buf.append("on a writable value" + NLINE);
+      } else {
+        buf.append(
+            "PropertyNotWritableException caught as " + "expected." + NLINE);
+      }
+    }
+
+    // getType()
+    Class type = vexp.getType(context);
+    String typeName = (type == null) ? "null" : type.getName();
+    buf.append("Type retrieved is " + typeName + NLINE);
+
+    // getExpectedType()
+    Class retrievedType = vexp.getExpectedType();
+    if (!(retrievedType.equals(expectedType))) {
+      pass = false;
+      buf.append(
+          "getExpectedType() does not return expected " + "type" + NLINE);
+      buf.append("Expected type = " + expectedType.toString() + NLINE);
+      buf.append("Computed type = " + retrievedType.toString() + NLINE);
+    }
+
+    // isReadOnly()
+    if ((vexp.isReadOnly(context)) != expectedReadOnly) {
+      pass = false;
+      buf.append("isReadOnly() did not return " + expectedReadOnly + NLINE);
+    }
+
+    // isLiteralText()
+    if ((vexp.isLiteralText()) != expectedLiteralText) {
+      pass = false;
+      buf.append(
+          "isLiteralText() did not return " + expectedLiteralText + NLINE);
+    }
+
+    // getExpressionString()
+    String retrievedStr = vexp.getExpressionString();
+    if (!retrievedStr.equals(exprStr)) {
+      pass = false;
+      buf.append(
+          "getExpressionString() does not return expected " + "string" + NLINE);
+      buf.append("Expected string = " + exprStr + NLINE);
+      buf.append("Computed string = " + retrievedStr + NLINE);
+    }
+
+    return pass;
+  }
+
+  public static boolean testMethodExpression(MethodExpression mexp,
+      ELContext context, String exprStr, Object[] params,
+      Object expectedReturnValue, boolean expectedLiteralText,
+      StringBuffer buf) {
+
+    boolean pass = true;
+
+    // getMethodInfo()
+    try {
+      MethodInfo minfo = mexp.getMethodInfo(context);
+    } catch (Exception e) {
+      pass = false;
+      buf.append("getMethodInfo() threw an unexpected exception" + NLINE);
+      buf.append(e.getMessage() + NLINE);
+    }
+
+    // invoke()
+    try {
+      Object returnValue = mexp.invoke(context, params);
+      if (returnValue == null) {
+        if (expectedReturnValue != null) {
+          pass = false;
+          buf.append("invoke() unexpectedly returned null" + NLINE);
+        }
+      } else if (expectedReturnValue == null) {
+        pass = false;
+        buf.append(
+            "invoke() unexpectedly returned non-null " + "value" + NLINE);
+      } else if (!returnValue.equals(expectedReturnValue)) {
+        pass = false;
+        buf.append(
+            "invoke() returned an object of wrong type or " + "value" + NLINE);
+        buf.append(
+            "Expected return value: " + expectedReturnValue.toString() + NLINE);
+        buf.append("Computed return value: " + returnValue.toString() + NLINE);
+      }
+    } catch (Exception e) {
+      pass = false;
+      buf.append("invoke() threw an unexpected exception" + NLINE);
+      buf.append(e.getMessage() + NLINE);
+    }
+
+    // isLiteralText()
+    if ((mexp.isLiteralText()) != expectedLiteralText) {
+      pass = false;
+      buf.append(
+          "isLiteralText() did not return " + expectedLiteralText + NLINE);
+    }
+
+    // getExpressionString()
+    String retrievedStr = mexp.getExpressionString();
+    if (!retrievedStr.equals(exprStr)) {
+      pass = false;
+      buf.append(
+          "getExpressionString() does not return expected " + "string" + NLINE);
+      buf.append("Expected string = " + exprStr + NLINE);
+      buf.append("Computed string = " + retrievedStr + NLINE);
+    }
+
+    return pass;
+  }
+
+  public static boolean equalsTest(Expression exp1, Expression exp2,
+      StringBuffer buf) {
+
+    String e1str = exp1.getExpressionString();
+    String e2str = (exp2 == null) ? null : exp2.getExpressionString();
+
+    buf.append("Testing equality: " + e1str + " and " + e2str + NLINE);
+
+    if (!exp1.equals(exp2)) {
+      if (exp2 != null) {
+        buf.append("Expression " + e1str + " is not equal to " + "Expression "
+            + e2str + NLINE);
+      }
+      return false;
+    } else {
+      int hcode1 = exp1.hashCode();
+      int hcode2 = exp2.hashCode();
+
+      if (hcode1 != hcode2) {
+        buf.append("Expressions " + e1str + " and " + e2str + " are "
+            + "equal, but their" + NLINE);
+        buf.append("hashcodes aren't the same." + NLINE);
+        buf.append("Hashcode for " + e1str + ": " + hcode1 + NLINE);
+        buf.append("Hashcode for " + e2str + ": " + hcode2 + NLINE);
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  public static boolean expressionSerializableTest(Expression exp,
+      StringBuffer buf) {
+
+    ObjectOutputStream out = null;
+    ObjectInputStream in = null;
+    Expression desexp = null;
+    ByteArrayOutputStream bos = null;
+
+    // Serialize the Expression.
+    try {
+      bos = new ByteArrayOutputStream();
+      out = new ObjectOutputStream(bos);
+      out.writeObject(exp);
+    } catch (IOException ioe) {
+      buf.append(
+          "Failed to serialize the Expression!" + NLINE + ioe.toString());
+      return false;
+    } finally {
+      if (out != null) {
+        try {
+          out.close();
+        } catch (Exception close) {
+          // Do not fail the test if close does not happen.
+        }
+      }
+    }
+
+    // Deserialize the Expression.
+    try {
+      byte[] byteBuf = bos.toByteArray();
+      in = new ObjectInputStream(new ByteArrayInputStream(byteBuf));
+      desexp = (Expression) in.readObject();
+    } catch (IOException ioe) {
+      buf.append(
+          "Failed to deserialize the Expression!" + NLINE + ioe.toString());
+      return false;
+    } catch (ClassNotFoundException cnfe) {
+      buf.append("Could not find class of serialized Expression" + NLINE
+          + cnfe.toString());
+      return false;
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (Exception close) {
+          // Do not fail the test if close does not happen.
+        }
+      }
+    }
+
+    // Test Expression After Serialization
+    if (!equalsTest(desexp, exp, buf)) {
+      buf.append("'getExpressionString' after serialization took " + "place."
+          + NLINE + "Expected: " + exp.getExpressionString() + NLINE
+          + "Received: " + desexp.getExpressionString() + NLINE);
+      return false;
+    }
+
+    return true;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/api/resolver/BarELResolver.java b/tck/src/main/java/com/sun/ts/tests/el/common/api/resolver/BarELResolver.java
new file mode 100644
index 0000000..a941c60
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/api/resolver/BarELResolver.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2018, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.common.api.resolver;
+
+import java.util.Iterator;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ELResolver;
+import jakarta.el.PropertyNotWritableException;
+
+public class BarELResolver extends ELResolver {
+
+  public Object getValue(ELContext context, Object base, Object property)
+      throws ELException {
+    Object result = null;
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null) {
+      // Resolving first variable (e.g. ${Bar}).
+      // We only handle "Bar"
+      String propertyName = (String) property;
+      if (propertyName.equals("Bar")) {
+        result = "Foo";
+        context.setPropertyResolved(true);
+      }
+    }
+    return result;
+  }
+
+  public Class getType(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null && property instanceof String
+        && property.toString().equals("Bar")) {
+      context.setPropertyResolved(true);
+    }
+
+    // we never set a value
+    return null;
+  }
+
+  public void setValue(ELContext context, Object base, Object property,
+
+      Object value) throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null && property instanceof String
+        && property.toString().equals("Bar")) {
+      context.setPropertyResolved(true);
+      throw new PropertyNotWritableException();
+    }
+  }
+
+  public boolean isReadOnly(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null && property instanceof String
+        && property.toString().equals("Bar")) {
+      context.setPropertyResolved(true);
+    }
+
+    return true;
+  }
+
+  public Iterator getFeatureDescriptors(ELContext context, Object base) {
+    if (context == null)
+      throw new NullPointerException();
+    return null;
+  }
+
+  public Class getCommonPropertyType(ELContext context, Object base) {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null)
+      return String.class;
+    return null;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/api/resolver/ResolverTest.java b/tck/src/main/java/com/sun/ts/tests/el/common/api/resolver/ResolverTest.java
new file mode 100644
index 0000000..104b7a7
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/api/resolver/ResolverTest.java
@@ -0,0 +1,542 @@
+/*
+ * Copyright (c) 2009, 2024 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+package com.sun.ts.tests.el.common.api.resolver;
+
+import java.util.Objects;
+
+import jakarta.el.BeanELResolver;
+import jakarta.el.CompositeELResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.MethodNotFoundException;
+import jakarta.el.PropertyNotFoundException;
+import jakarta.el.PropertyNotWritableException;
+
+public class ResolverTest {
+  private static final String NL = System.getProperty("line.separator", "\n");
+
+  /**
+   * Private as this class will only have static methods and members.
+   */
+  private ResolverTest() {
+  }
+
+  public static boolean testCompositeELResolver(ELContext elContext,
+      CompositeELResolver compResolver, StringBuffer buf) {
+
+    boolean pass = true;
+
+    // add()
+    BarELResolver barResolver = new BarELResolver();
+    try {
+      compResolver.add(barResolver);
+      buf.append("add() tested successfully" + NL);
+
+    } catch (Exception e) {
+      buf.append("add() method Test Failed");
+      pass = false;
+    }
+
+    // setValue()
+    elContext.setPropertyResolved(false);
+    compResolver.setValue(elContext, null, "Nothing", "rien");
+    if (!elContext.isPropertyResolved()) {
+      buf.append(
+          "setValue() tested successfully on non-existent " + "property" + NL);
+    } else {
+      buf.append("setValue() set property resolved on non-existent "
+          + "property" + NL);
+      pass = false;
+    }
+
+    elContext.setPropertyResolved(false);
+    try {
+      compResolver.setValue(elContext, null, "Bar", "rien");
+      pass = false;
+    } catch (PropertyNotWritableException pnwe) {
+      buf.append(
+          "setValue() tested successfully on non-writable " + "property" + NL);
+      buf.append("PropertyNotWritableException caught as expected" + NL);
+    }
+
+    // getValue()
+    elContext.setPropertyResolved(false);
+    String result = (String) compResolver.getValue(elContext, null, "Bar");
+    if (!elContext.isPropertyResolved()) {
+      buf.append("getValue() did not resolve" + NL);
+      pass = false;
+    } else if (!result.equals("Foo")) {
+      buf.append("Invalid value from BarELResolver: " + result + NL);
+      pass = false;
+    } else {
+      buf.append("getValue() tested successfully" + NL);
+    }
+
+    // getType()
+    elContext.setPropertyResolved(false);
+    Class<?> type = compResolver.getType(elContext, null, "Bar");
+    if (!elContext.isPropertyResolved()) {
+      buf.append("getType() did not resolve" + NL);
+      pass = false;
+    } else if (type != null) {
+      buf.append("getType() returns " + type.getName() + NL);
+      buf.append("not expected result for non-writable property" + NL);
+      pass = false;
+    } else {
+      buf.append("getType() returns null as expected for non-writable "
+          + "property" + NL);
+    }
+
+    // isReadOnly
+    elContext.setPropertyResolved(false);
+    boolean nonWritable = compResolver.isReadOnly(elContext, null, "Bar");
+    if (!elContext.isPropertyResolved()) {
+      buf.append("isReadOnly() did not resolve" + NL);
+      pass = false;
+    } else if (!nonWritable) {
+      buf.append("isReadOnly() did not return true" + NL);
+      pass = false;
+    } else {
+      buf.append("isReadOnly() returns true as expected" + NL);
+    }
+
+    // getCommonPropertyType()
+    elContext.setPropertyResolved(false);
+    Class<?> commonPropertyType = (compResolver.getCommonPropertyType(elContext, null));
+    buf.append("getCommonPropertyType() returns ");
+    buf.append(commonPropertyType.getName() + NL);
+
+    return pass;
+  }
+
+  public static boolean testELResolver(ELContext elContext, ELResolver resolver,
+      Object base, Object property, Object value, StringBuffer buf,
+      boolean readOnly) {
+
+    boolean pass = true;
+
+    // setValue()
+    elContext.setPropertyResolved(false);
+    try {
+      resolver.setValue(elContext, base, property, value);
+      if (readOnly) {
+        buf.append("setValue() failed on non-writable property");
+        pass = false;
+      } else {
+        buf.append(
+            "setValue() tested successfully on writable " + "property" + NL);
+      }
+
+    } catch (PropertyNotWritableException pnwe) {
+      if (readOnly) {
+        buf.append("setValue() tested successfully on non-writable "
+            + "property" + NL);
+        buf.append("PropertyNotWritableException caught as expected" + NL);
+      } else {
+        buf.append("setValue() failed on non-writable property" + NL);
+        buf.append("Unexpected PropertyNotWritableException caught" + NL);
+        pass = false;
+      }
+    }
+
+    // getValue()
+    elContext.setPropertyResolved(false);
+    Object valueRetrieved = resolver.getValue(elContext, base, property);
+    if (!elContext.isPropertyResolved()) {
+      buf.append("getValue() did not resolve" + NL);
+      pass = false;
+    }
+
+    if (!readOnly && !Objects.equals(valueRetrieved, value)) {
+      if (valueRetrieved == null) {
+        buf.append("null value returned from getValue() method call!" + NL);
+        pass = false;
+      } else {
+        buf.append("Invalid value from getValue():" + NL);
+        buf.append("Value expected: " + value.toString() + NL);
+        buf.append("Value retrieved: " + valueRetrieved.toString() + NL);
+        pass = false;
+      }
+    } else {
+      buf.append("getValue() tested successfully" + NL);
+      if (!readOnly) {
+        buf.append("Value expected: " + value.toString() + NL);
+        buf.append("Value retrieved: " + valueRetrieved.toString() + NL);
+      }
+    }
+
+    // getType()
+    elContext.setPropertyResolved(false);
+    Class<?> type = resolver.getType(elContext, base, property);
+    if (!elContext.isPropertyResolved()) {
+      buf.append("getType() did not resolve" + NL);
+      pass = false;
+    } else if (type != null) {
+      buf.append("getType() returns " + type.getName() + NL);
+      if (readOnly) {
+        buf.append("result not expected!" + NL);
+        pass = false;
+      } else {
+        buf.append("non-null as expected" + NL);
+      }
+    } else {
+      buf.append("getType() returns null " + NL);
+      if (!readOnly) {
+        buf.append("result not expected!" + NL);
+        pass = false;
+      } else {
+        buf.append("as expected" + NL);
+      }
+    }
+
+    // isReadOnly
+    elContext.setPropertyResolved(false);
+    boolean nonWritable = resolver.isReadOnly(elContext, base, property);
+    if (!elContext.isPropertyResolved()) {
+      buf.append("isReadOnly() did not resolve" + NL);
+      pass = false;
+    } else if (nonWritable != readOnly) {
+      buf.append("isReadOnly() returned unexpected value: " + nonWritable + NL);
+      pass = false;
+    } else {
+      buf.append("isReadOnly() returns " + readOnly + " as expected" + NL);
+    }
+
+    // getCommonPropertyType()
+    elContext.setPropertyResolved(false);
+    Class<?> commonPropertyType = (resolver.getCommonPropertyType(elContext, base));
+    buf.append("getCommonPropertyType() returns ");
+    buf.append(commonPropertyType.getName() + "" + NL);
+
+    return pass;
+  }
+
+  /**
+   * Test the ELResolver.invoke() mthod.
+   * 
+   * @param elContext
+   *          - elContext
+   * @param resolver
+   *          - el Resolver to be tested.
+   * @param beanName
+   *          - The javabean to be used.
+   * @param methodName
+   *          - The method in the javabean to call.
+   * @param types
+   *          - The @class types of the aurgs for the method.
+   * @param values
+   *          - The args that you want to pass into the method.
+   * @param negTest
+   *          - Is this a negetive test or not(true, false).
+   * @param buf
+   *          - String buffer used to capture loggig info.
+   * @return
+   */
+  public static boolean testELResolverInvoke(ELContext elContext,
+      ELResolver resolver, Object beanName, Object methodName, Class<?>[] types,
+      Object[] values, Boolean negTest, StringBuffer buf) {
+
+    boolean pass = true;
+
+    // invoke
+    elContext.setPropertyResolved(false);
+    try {
+      Boolean nameMatch = (Boolean) resolver.invoke(elContext, beanName,
+          methodName, types, values);
+
+      if (!nameMatch.booleanValue()) {
+        buf.append("invoke() did not Run properly." + NL);
+        pass = false;
+      }
+
+    } catch (MethodNotFoundException mnfe) {
+      if (negTest.booleanValue()) {
+        buf.append("Test Passed  invoke() threw MethodNotFoundException");
+      } else {
+        pass = false;
+        mnfe.printStackTrace();
+      }
+    } catch (Exception e) {
+      pass = false;
+      e.printStackTrace();
+    }
+
+    return pass;
+  }
+
+
+  // --- Start Negative Method Tests ---
+  public static boolean testELResolverNPE(ELResolver resolver, Object base,
+      Object property, Object value, StringBuffer buf) {
+
+    boolean pass = true;
+
+    // getType()
+    try {
+      resolver.getType(null, base, property);
+      pass = false;
+      buf.append("getType test failed with: " + NL
+          + "EXPECTED: NullPointerException to be thrown " + NL
+          + "RECEIVED: NO EXCEPTION THROWN AT ALL! " + NL);
+    } catch (Exception e) {
+      if (!(e instanceof NullPointerException)) {
+        buf.append("getType test failed with: " + NL + "EXPECTED: "
+            + "NullPointerException to be thrown " + NL + "RECEIVED: "
+            + e.toString() + NL);
+        pass = false;
+
+      } else {
+        buf.append("getType() test Passed: throws "
+            + "NullPointerException as expected " + NL);
+      }
+    }
+
+    // getValue
+    try {
+      resolver.getValue(null, base, property);
+      buf.append("Test Failed  getValue() did not throw any exception." + NL
+          + "Expected: NullPointerException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof NullPointerException)) {
+        buf.append("Test Failed  getValue() threw the wrong exception " + NL
+            + "Expected: NullPointerException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append("Test Passed  getValue() threw NullPointerException " + NL);
+      }
+    }
+
+    // setValue()
+    try {
+      resolver.setValue(null, base, property, value);
+      buf.append("Test Failed  setValue() did not throw any exception." + NL
+          + "Expected: NullPointerException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof NullPointerException)) {
+        buf.append("Test Failed  setValue() threw the wrong exception " + NL
+            + "Expected: NullPointerException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append("Test Passed  setValue() threw NullPointerException " + NL);
+      }
+    }
+
+    // isReadOnly()
+    try {
+      resolver.isReadOnly(null, base, property);
+      buf.append("Test Failed  isReadOnly() did not throw any exception." + NL
+          + "Expected: NullPointerException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof NullPointerException)) {
+        buf.append("Test Failed  isReadOnly() threw the wrong exception " + NL
+            + "Expected: NullPointerException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append(
+            "Test Passed  isReadOnly() NullPointerException " + "thrown " + NL);
+      }
+    }
+
+    return pass;
+  }
+
+  public static boolean testELResolverPNFE(ELContext elcontext,
+      ELResolver resolver, Object base, Object property, StringBuffer buf) {
+
+    boolean pass = true;
+
+    // getType()
+    try {
+      resolver.getType(elcontext, base, property);
+      buf.append("Test Failed  getType() did not throw any exception." + NL
+          + "Expected: PropertyNotFoundException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof PropertyNotFoundException)) {
+        buf.append("Test Failed  getType() threw the wrong exception " + NL
+            + "Expected: PropertyNotFoundException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append("Test Passed  getType() threw "
+            + "PropertyNotFoundException " + NL);
+      }
+    }
+
+    // isReadOnly()
+    try {
+      resolver.isReadOnly(elcontext, base, property);
+      buf.append("Test Failed  isReadOnly() did not throw any exception." + NL
+          + "Expected: PropertyNotFoundException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof PropertyNotFoundException)) {
+        buf.append("Test Failed  isReadOnly() threw the wrong exception " + NL
+            + "Expected: PropertyNotFoundException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append("Test Passed  isReadOnly() threw "
+            + "PropertyNotFoundException " + NL);
+      }
+    }
+
+    // setValue()
+    try {
+      resolver.setValue(elcontext, base, property, "arbitrary value");
+      buf.append("Test Failed  setValue() did not throw any exception." + NL
+          + "Expected: PropertyNotFoundException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof PropertyNotFoundException)) {
+        buf.append("Test Failed  setValue() threw the wrong exception " + NL
+            + "Expected: PropertyNotFoundException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append("Test Passed  setValue() threw "
+            + "PropertyNotFoundException " + NL);
+      }
+    }
+
+    if (!(resolver instanceof BeanELResolver)) {
+      return pass;
+    }
+
+    // getValue()
+    try {
+      resolver.getValue(elcontext, base, property);
+      buf.append("Test Failed  getValue() did not throw any exception." + NL
+          + "Expected: PropertyNotFoundException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof PropertyNotFoundException)) {
+        buf.append("Test Failed  getValue() threw the wrong exception " + NL
+            + "Expected: PropertyNotFoundException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append("Test Passed  getValue() threw "
+            + "PropertyNotFoundException " + NL);
+      }
+    }
+
+    return pass;
+  }
+
+  public static boolean testELResolverIAE(ELContext elcontext,
+      ELResolver resolver, Object base, Object property, Object value,
+      StringBuffer buf) {
+
+    boolean pass = true;
+
+    // getValue()
+    try {
+      resolver.getValue(elcontext, base, value);
+      buf.append("Test Failed  getValue() did not throw any exception." + NL
+          + "Expected: IllegalArgumentException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof IllegalArgumentException)) {
+        buf.append("Test Failed  getValue() threw the wrong exception " + NL
+            + "Expected: IllegalArgumentException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append("Test Passed  getValue() threw "
+            + "IllegalArgumentException " + NL);
+      }
+    }
+
+    // setValue()
+    try {
+      resolver.setValue(elcontext, base, property, value);
+      buf.append("Test Failed  setValue() did not throw any exception." + NL
+          + "Expected: IllegalArgumentException " + NL);
+
+      pass = false;
+    } catch (Exception e) {
+      if (!(e instanceof IllegalArgumentException)) {
+        buf.append("Test Failed  setValue() threw the wrong exception "
+            + "Expected: IllegalArgumentException " + NL + "Received: "
+            + e.toString());
+
+        pass = false;
+      } else {
+        buf.append("Test Passed  setValue() threw "
+            + "IllegalArgumentException " + NL);
+      }
+    }
+
+    return pass;
+  }
+
+  public static boolean testELResolverPNWE(ELContext elcontext,
+      ELResolver resolver, Object base, Object property, Object value,
+      StringBuffer buf) {
+
+    boolean pass = true;
+
+    // setValue()
+    try {
+      resolver.setValue(elcontext, base, property, value);
+      buf.append("Test Failed  setValue() did not throw any exception." + NL
+          + "Expected: PropertyNotWritableException " + NL);
+      pass = false;
+
+    } catch (Exception e) {
+      if (!(e instanceof PropertyNotWritableException)) {
+        buf.append("Test Failed  setValue() threw the wrong exception " + NL
+            + "Expected: PropertyNotWritableException " + NL + "Received: "
+            + e.toString());
+        pass = false;
+
+      } else {
+        buf.append("Test Passed  setValue() threw "
+            + "PropertyNotWritableException " + NL);
+      }
+    }
+
+    return pass;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/BarELContext.java b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/BarELContext.java
new file mode 100644
index 0000000..07a6de7
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/BarELContext.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.elcontext;
+
+import com.sun.ts.tests.el.common.api.resolver.BarELResolver;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.FunctionMapper;
+import jakarta.el.VariableMapper;
+
+/* This ELContext contains only a simple EL resolver used to
+   resolve expressions handled by the BarELResolver.
+*/
+
+public class BarELContext extends ELContext {
+
+  private final ELResolver elResolver;
+
+  /*
+   * Constructor.
+   */
+  public BarELContext() {
+    this.elResolver = new BarELResolver();
+  }
+
+  public ELResolver getELResolver() {
+    return (ELResolver) elResolver;
+  }
+
+  public ELContext getELContext() {
+    return (ELContext) (this);
+  }
+
+  public VariableMapper getVariableMapper() {
+    return null;
+  }
+
+  public FunctionMapper getFunctionMapper() {
+    return null;
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/BareBonesELContext.java b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/BareBonesELContext.java
new file mode 100644
index 0000000..a2d6f38
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/BareBonesELContext.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.elcontext;
+
+import jakarta.el.CompositeELResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.FunctionMapper;
+import jakarta.el.VariableMapper;
+
+/* This ELContext contains only a single CompositeELResolver
+   for use in testing the ELResolver API.
+*/
+
+public class BareBonesELContext extends ELContext {
+
+  private final ELResolver elResolver;
+
+  /*
+   * Constructor.
+   */
+  public BareBonesELContext() {
+    this.elResolver = new CompositeELResolver();
+  }
+
+  public ELResolver getELResolver() {
+    return (ELResolver) elResolver;
+  }
+
+  public ELContext getELContext() {
+    return (ELContext) (this);
+  }
+
+  public VariableMapper getVariableMapper() {
+    return null;
+  }
+
+  public FunctionMapper getFunctionMapper() {
+    return null;
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/FuncMapperELContext.java b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/FuncMapperELContext.java
new file mode 100644
index 0000000..7974df4
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/FuncMapperELContext.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.elcontext;
+
+import com.sun.ts.tests.el.common.elresolver.FunctionELResolver;
+import com.sun.ts.tests.el.common.functionmapper.TCKFunctionMapper;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.FunctionMapper;
+import jakarta.el.VariableMapper;
+
+/* This ELContext provides only a FunctionMapper implementation and
+   an ELResolver that resolves only the functions mapped by the
+   FunctionMapper.
+ */
+
+public class FuncMapperELContext extends ELContext {
+
+  private final ELResolver elResolver;
+
+  private final FunctionMapper funcMapper;
+
+  /*
+   * Constructor.
+   */
+  public FuncMapperELContext() {
+    elResolver = new FunctionELResolver();
+    funcMapper = new TCKFunctionMapper();
+  }
+
+  public ELResolver getELResolver() {
+    return elResolver;
+  }
+
+  public VariableMapper getVariableMapper() {
+    return null;
+  }
+
+  public FunctionMapper getFunctionMapper() {
+    return funcMapper;
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/SimpleELContext.java b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/SimpleELContext.java
new file mode 100644
index 0000000..148fa5d
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/SimpleELContext.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+package com.sun.ts.tests.el.common.elcontext;
+
+
+import com.sun.ts.tests.el.common.elresolver.EmployeeELResolver;
+import com.sun.ts.tests.el.common.elresolver.VariableELResolver;
+import com.sun.ts.tests.el.common.elresolver.VectELResolver;
+import com.sun.ts.tests.el.common.util.ResolverType;
+
+import jakarta.el.CompositeELResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.FunctionMapper;
+import jakarta.el.VariableMapper;
+
+import java.lang.System.Logger;
+
+/**
+ * A basic ELContext that meets the needs of most EL tests. The no-args
+ * constructor builds the ELContext from a VariableELResolver that enables the
+ * setting and resolution of variables when base is null. The single- argument
+ * constructor allows the user to build the ELContext from any ELResolver. This
+ * ELContext is "simple" because no VariableMapper or FunctionMapper are used.
+ */
+public class SimpleELContext extends ELContext {
+
+  private static final Logger logger = System.getLogger(SimpleELContext.class.getName());
+
+  private static final String NLINE = System.getProperty("line.separator");
+
+  private final CompositeELResolver compResolver;
+
+  private ELResolver myResolver;
+
+  private VariableELResolver varResolver;
+
+  // Custom ELResolvers.
+  public enum Resolver {
+
+    EmployeeELResolver, VariableELResolver, VectELResolver
+  };
+
+  /*
+   * Default Constructor.
+   */
+  public SimpleELContext() {
+    this.compResolver = new CompositeELResolver();
+  }
+
+  /*
+   * Constructor with an ELResolver given through an enum.
+   */
+  public SimpleELContext(ResolverType resolverType) {
+    this.myResolver = this.getMyResolver(resolverType);
+    this.compResolver = new CompositeELResolver();
+  }
+
+  public ELResolver getELResolver() {
+    ELResolver elResolver;
+
+    if (myResolver == null) {
+      varResolver = new VariableELResolver();
+      compResolver.add(varResolver);
+    } else {
+      if (myResolver instanceof VariableELResolver) {
+        varResolver = (VariableELResolver) myResolver;
+      } else {
+        varResolver = null;
+      }
+      compResolver.add(myResolver);
+    }
+
+    elResolver = (ELResolver) compResolver;
+
+    return elResolver;
+  }
+
+  public ELContext getELContext() {
+    return (ELContext) (this);
+  }
+
+  public VariableMapper getVariableMapper() {
+    return null;
+  }
+
+  public FunctionMapper getFunctionMapper() {
+    return null;
+  }
+
+  // This method is not required by the ELContext API. It is for
+  // removing all entries from the the VariableELResolver's
+  // static hashtable between test invocations.
+  public void cleanup() {
+    if (varResolver != null) {
+      varResolver.cleanup();
+    }
+  }
+
+  // ------------------------------- Private Methods
+  // ------------------------------
+  private ELResolver getMyResolver(ResolverType enumResolver) {
+
+    switch (enumResolver) {
+    case EMPLOYEE_ELRESOLVER:
+      myResolver = new EmployeeELResolver();
+      logger.log(Logger.Level.TRACE, "Setting ELResolver == EmployeeELResolver");
+      break;
+
+    case VARIABLE_ELRESOLVER:
+      myResolver = new VariableELResolver();
+      logger.log(Logger.Level.TRACE, "Setting ELResolver == VariableELResolver");
+      break;
+
+    case VECT_ELRESOLVER:
+      myResolver = new VectELResolver();
+      logger.log(Logger.Level.TRACE, "Setting ELResolver == VectELResolver");
+      break;
+
+    default:
+      logger.log(Logger.Level.TRACE, 
+          "Unknown ELResolver! " + enumResolver + " trying to use default"
+              + NLINE + "Setting" + " ELResolver == VariableELResolver");
+      break;
+    }
+
+    return myResolver;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/VRContext.java b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/VRContext.java
new file mode 100644
index 0000000..b8666a3
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/VRContext.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+package com.sun.ts.tests.el.common.elcontext;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.api.jakarta_el.valueexpression.Worker;
+import com.sun.ts.tests.el.common.elresolver.VariableELResolver;
+import com.sun.ts.tests.el.common.functionmapper.TCKFunctionMapper;
+
+import jakarta.el.BeanELResolver;
+import jakarta.el.CompositeELResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.FunctionMapper;
+import jakarta.el.VariableMapper;
+
+import java.lang.System.Logger;
+
+public class VRContext extends ELContext {
+
+  private static final Logger logger = System.getLogger(VRContext.class.getName());
+
+  private final VariableMapper varMapper;
+
+  private final CompositeELResolver compResolver;
+
+  public VRContext(Properties testProps) {
+    this.compResolver = new CompositeELResolver();
+    varMapper = this.getVariableMapperImpl(testProps);
+  }
+
+  public ELResolver getELResolver() {
+    ELResolver elResolver;
+    ELResolver rel = new VariableELResolver();
+    rel.setValue(this, "worker", null, new Worker());
+    compResolver.add(rel);
+
+    BeanELResolver br = new BeanELResolver();
+    br.setValue(this, "worker", null, new Worker());
+    compResolver.add(br);
+    elResolver = compResolver;
+
+    return elResolver;
+  }
+
+  @Override
+  public FunctionMapper getFunctionMapper() {
+
+    return new TCKFunctionMapper();
+  }
+
+  @Override
+  public VariableMapper getVariableMapper() {
+    return varMapper;
+  }
+
+  private Object getImplSpecificInstance(String classname) {
+
+    Class clazz;
+    Object instance = null;
+
+    try {
+      clazz = Class.forName(classname);
+      instance = clazz.newInstance();
+    } catch (ClassNotFoundException cnfe) {
+      logger.log(Logger.Level.ERROR, "ClassNotFoundException: " + cnfe.getMessage());
+    } catch (InstantiationException ie) {
+      logger.log(Logger.Level.ERROR, "InstantiationException: " + ie.getMessage());
+    } catch (IllegalAccessException iae) {
+      logger.log(Logger.Level.ERROR, "IllegalAccessException: " + iae.getMessage());
+    }
+    return instance;
+  }
+
+  private VariableMapper getVariableMapperImpl(Properties testProps) {
+    String implSpecificClassName = testProps.getProperty("variable.mapper");
+
+    return (implSpecificClassName == null) ? null
+        : (VariableMapper) getImplSpecificInstance(implSpecificClassName);
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/VarMapperELContext.java b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/VarMapperELContext.java
new file mode 100644
index 0000000..ea9e35b
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elcontext/VarMapperELContext.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+package com.sun.ts.tests.el.common.elcontext;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.elresolver.VariableELResolver;
+
+import jakarta.el.CompositeELResolver;
+import jakarta.el.ELContext;
+import jakarta.el.ELResolver;
+import jakarta.el.FunctionMapper;
+import jakarta.el.VariableMapper;
+
+import java.lang.System.Logger;
+/**
+ * This ELContext provides a VariableELResolver to enable the setting and
+ * resolution of variables as well as a VariableMapper implementation. The path
+ * to the implementation is passed to the EL Context via a property in the
+ * ts.jte file.
+ */
+public class VarMapperELContext extends ELContext {
+
+  private static final Logger logger = System.getLogger(VarMapperELContext.class.getName());
+
+  private final VariableMapper varMapper;
+
+  private final CompositeELResolver compResolver;
+
+  /*
+   * Constructor.
+   */
+  public VarMapperELContext(Properties testProps) {
+    this.compResolver = new CompositeELResolver();
+    varMapper = this.getVariableMapperImpl(testProps);
+  }
+
+  public ELResolver getELResolver() {
+    ELResolver elResolver;
+    this.compResolver.add(new VariableELResolver());
+    this.compResolver.add(new jakarta.el.BeanELResolver());
+    elResolver = (ELResolver) compResolver;
+
+    return elResolver;
+  }
+
+  public ELContext getELContext() {
+    return (ELContext) (this);
+  }
+
+  public VariableMapper getVariableMapper() {
+    return varMapper;
+  }
+
+  public FunctionMapper getFunctionMapper() {
+    return null;
+  }
+
+  private Object getImplSpecificInstance(String classname) {
+
+    Class clazz;
+    Object instance = null;
+
+    try {
+      clazz = Class.forName(classname);
+      instance = clazz.newInstance();
+    } catch (ClassNotFoundException cnfe) {
+      logger.log(Logger.Level.ERROR, "ClassNotFoundException: " + cnfe.getMessage());
+    } catch (InstantiationException ie) {
+      logger.log(Logger.Level.ERROR, "InstantiationException: " + ie.getMessage());
+    } catch (IllegalAccessException iae) {
+      logger.log(Logger.Level.ERROR, "IllegalAccessException: " + iae.getMessage());
+    }
+    return instance;
+  }
+
+  private VariableMapper getVariableMapperImpl(Properties testProps) {
+    String implSpecificClassName = testProps.getProperty("variable.mapper");
+
+    return (implSpecificClassName == null) ? null
+        : (VariableMapper) getImplSpecificInstance(implSpecificClassName);
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/EmployeeELResolver.java b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/EmployeeELResolver.java
new file mode 100644
index 0000000..107e632
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/EmployeeELResolver.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.elresolver;
+
+import java.util.Iterator;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ELResolver;
+
+/* This simple EL Resolver resolves only method expressions of
+ * the form ${worker.methodName}, where 'worker' is resolved to
+ * com.sun.ts.tests.el.spec.language.EmployeeBean and 'methodName' is one of its
+ * methods.
+ */
+
+public class EmployeeELResolver extends ELResolver {
+
+  private static final String FIRST_NAME = "Ricky";
+
+  private static final String LAST_NAME = "Bobby";
+
+  public Object getValue(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    Object result = null;
+    String propertyName = property.toString();
+
+    if (base == null) {
+      // Resolving first variable (e.g. ${worker}).
+      if ("worker".equals(propertyName)) {
+        result = "worker has no name!";
+      }
+
+    } else if ((base instanceof String) && ("firstName".equals(property))) {
+
+      result = EmployeeELResolver.FIRST_NAME;
+
+    } else if ((base instanceof String) && ("lastName".equals(property))) {
+
+      result = EmployeeELResolver.LAST_NAME;
+    }
+
+    if (result != null)
+      context.setPropertyResolved(true);
+    return result;
+  }
+
+  public Class<?> getType(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    String propertyName = property.toString();
+    if ((base == null && propertyName.equals("worker"))
+        || (base instanceof String && base.equals("worker")))
+      context.setPropertyResolved(true);
+
+    // we never set a value
+    return null;
+  }
+
+  public void setValue(ELContext context, Object base, Object property,
+      Object value) {
+    if (context == null)
+      throw new NullPointerException();
+
+    if ((base == null && "worker".equals(property))
+        || (base instanceof String && base.equals("worker")))
+      context.setPropertyResolved(true);
+  }
+
+  public boolean isReadOnly(ELContext context, Object base, Object property) {
+    if (context == null)
+      throw new NullPointerException();
+
+    String propertyName = property.toString();
+    if ((base == null && propertyName.equals("worker"))
+        || (base instanceof String && base.equals("worker")))
+      context.setPropertyResolved(true);
+    return true;
+  }
+
+  public Iterator getFeatureDescriptors(ELContext context, Object base) {
+    return null;
+  }
+
+  public Class<?> getCommonPropertyType(ELContext context, Object base) {
+    if (base == null)
+      return Object.class;
+    return null;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/EnumELResolver.java b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/EnumELResolver.java
new file mode 100644
index 0000000..52b194f
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/EnumELResolver.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.elresolver;
+
+public enum EnumELResolver {
+  EMPLOYEE_ELRESOLVER, VARIABLE_ELRESOLVER, VECT_ELRESOLVER;
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/FunctionELResolver.java b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/FunctionELResolver.java
new file mode 100644
index 0000000..786ea73
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/FunctionELResolver.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.elresolver;
+
+import java.util.Iterator;
+
+import com.sun.ts.tests.el.common.functionmapper.TCKFunctionMapper;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ELResolver;
+
+/* This ELResolver resolves only functions mapped by the TCKFunctionMapper.
+ * It does not allow variables to be set.
+*/
+
+public class FunctionELResolver extends ELResolver {
+
+  public Object getValue(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    Object result = null;
+    if (base == null) {
+      context.setPropertyResolved(true);
+      String[] function = property.toString().split(":", 2);
+
+      // Strip off parentheses
+      String localname = function[1].substring(0, function[1].length() - 3);
+      result = new TCKFunctionMapper().resolveFunction(function[0], localname);
+    }
+
+    return result;
+  }
+
+  public Class getType(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null)
+      context.setPropertyResolved(true);
+
+    return null;
+  }
+
+  public void setValue(ELContext context, Object base, Object property,
+      Object value) {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null)
+      context.setPropertyResolved(true);
+  }
+
+  public boolean isReadOnly(ELContext context, Object base, Object property) {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null)
+      context.setPropertyResolved(true);
+    return false;
+  }
+
+  public Iterator getFeatureDescriptors(ELContext context, Object base) {
+    return null;
+  }
+
+  public Class getCommonPropertyType(ELContext context, Object base) {
+    if (base == null)
+      return Object.class;
+    return null;
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/VariableELResolver.java b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/VariableELResolver.java
new file mode 100644
index 0000000..7fb8e4e
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/VariableELResolver.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.elresolver;
+
+import java.beans.FeatureDescriptor;
+import java.util.Hashtable;
+import java.util.Iterator;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ELResolver;
+
+public class VariableELResolver extends ELResolver {
+
+  private Hashtable<Object, Object> varTable;
+
+  public Object getValue(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null) {
+      throw new NullPointerException();
+    }
+
+    Object result = null;
+    if (base == null) {
+      context.setPropertyResolved(true);
+      if (varTable != null) {
+        result = varTable.get(property.toString());
+      }
+    }
+
+    return result;
+  }
+
+  public Class<?> getType(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null) {
+      throw new NullPointerException();
+    }
+
+    if (base == null) {
+      context.setPropertyResolved(true);
+    }
+
+    return null;
+  }
+
+  public void setValue(ELContext context, Object base, Object property,
+      Object value) {
+    if (context == null) {
+      throw new NullPointerException();
+    }
+
+    if (varTable == null) {
+      varTable = new Hashtable<Object, Object>();
+    }
+
+    if (value == null) {
+      varTable = new Hashtable<Object, Object>();
+      varTable.clear();
+      return;
+    }
+
+    if (base == null) {
+      varTable.put(property.toString(), value);
+      context.setPropertyResolved(true);
+    } else {
+      varTable.put(base, value);
+      context.setPropertyResolved(true);
+    }
+  }
+
+  public boolean isReadOnly(ELContext context, Object base, Object property) {
+    if (context == null) {
+      throw new NullPointerException();
+    }
+
+    if (base == null) {
+      context.setPropertyResolved(true);
+    }
+    return false;
+  }
+
+  public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
+      Object base) {
+    return null;
+  }
+
+  public Class<Object> getCommonPropertyType(ELContext context, Object base) {
+    if (base == null) {
+      return Object.class;
+    }
+    return null;
+  }
+
+  // This method is not required by the ELResolver API. It is for
+  // removing all entries from the the VariableELResolver's
+  // static hashtable between test invocations.
+  public void cleanup() {
+
+    if (varTable != null) {
+      varTable.clear();
+    }
+
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/VectELResolver.java b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/VectELResolver.java
new file mode 100644
index 0000000..0897f86
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/elresolver/VectELResolver.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.elresolver;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ELResolver;
+
+/* This simple EL Resolver resolves only method expressions of
+   the form ${vect.methodName}, where 'vect' is resolved to java.util.Vector
+   and 'methodName' is one of its methods.
+*/
+
+public class VectELResolver extends ELResolver {
+
+  public Object getValue(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null && "vect".equals(property)) {
+      context.setPropertyResolved(true);
+      return new Vector();
+    }
+    return null;
+  }
+
+  public Class getType(ELContext context, Object base, Object property)
+      throws ELException {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null && "vect".equals(property))
+      context.setPropertyResolved(true);
+
+    // we never set a value
+    return null;
+  }
+
+  public void setValue(ELContext context, Object base, Object property,
+      Object value) {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null && "vect".equals(property))
+      context.setPropertyResolved(true);
+  }
+
+  public boolean isReadOnly(ELContext context, Object base, Object property) {
+    if (context == null)
+      throw new NullPointerException();
+
+    if (base == null && "vect".equals(property))
+      context.setPropertyResolved(true);
+    return true;
+  }
+
+  public Iterator getFeatureDescriptors(ELContext context, Object base) {
+    return null;
+  }
+
+  public Class getCommonPropertyType(ELContext context, Object base) {
+    return null;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/functionmapper/TCKFunctionMapper.java b/tck/src/main/java/com/sun/ts/tests/el/common/functionmapper/TCKFunctionMapper.java
new file mode 100644
index 0000000..cfb9efa
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/functionmapper/TCKFunctionMapper.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.functionmapper;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.FunctionMapper;
+
+import java.lang.System.Logger;
+
+/* A simple implementation of FunctionMapper that maps only
+   a single function to Integer.valueOf(String).
+*/
+
+public class TCKFunctionMapper extends FunctionMapper {
+
+  private static final Logger logger = System.getLogger(TCKFunctionMapper.class.getName());
+
+  private static final String KEY = "Int:val";
+
+  private final Class clazz = Integer.class;
+
+  private final HashMap<String, Method> fMap;
+
+  public TCKFunctionMapper() {
+
+    fMap = new HashMap<String, Method>();
+    try {
+      fMap.put(KEY, clazz.getMethod("valueOf", String.class));
+    } catch (NoSuchMethodException nsme) {
+      logger.log(Logger.Level.ERROR, "CONSTRUCTOR: Can't find method!");
+      ELTestUtil.printStackTrace(nsme);
+    }
+  }
+
+  public Method resolveFunction(String prefix, String localName) {
+
+    String key = prefix + ":" + localName;
+    return fMap.get(key);
+  }
+
+  public void update() {
+
+    fMap.remove(KEY);
+    try {
+      fMap.put(KEY, clazz.getMethod("toString", int.class));
+    } catch (NoSuchMethodException nsme) {
+      logger.log(Logger.Level.ERROR, "UPDATE: Can't find method!");
+      ELTestUtil.printStackTrace(nsme);
+    }
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/spec/Book.java b/tck/src/main/java/com/sun/ts/tests/el/common/spec/Book.java
new file mode 100644
index 0000000..e192c40
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/spec/Book.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+/* 
+ * Simple multi-member class to be used for type coercion tests. 
+ */
+
+package com.sun.ts.tests.el.common.spec;
+
+public class Book {
+
+  private String title;
+
+  private String authors;
+
+  private String publisher;
+
+  private int year;
+
+  public Book(String title, String authors, String publisher, int year) {
+    this.title = title;
+    this.authors = authors;
+    this.publisher = publisher;
+    this.year = year;
+  }
+
+  public String getTitle() {
+    return title;
+  }
+
+  public String getAuthors() {
+    return authors;
+  }
+
+  public String getPublisher() {
+    return publisher;
+  }
+
+  public int getYear() {
+    return year;
+  }
+
+  public String toString() {
+    return getTitle();
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/Customer.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/Customer.java
new file mode 100644
index 0000000..c375075
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/Customer.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Customer {
+  int customerID;
+
+  String name;
+
+  String address;
+
+  String city;
+
+  String country;
+
+  String phone;
+
+  List<Order> orders;
+
+  public Customer(int customerID, String name, String address, String city,
+      String country, String phone) {
+    this.customerID = customerID;
+    this.name = name;
+    this.address = address;
+    this.city = city;
+    this.country = country;
+    this.phone = phone;
+    this.orders = new ArrayList<Order>();
+  }
+
+  public String toString() {
+    return "Customer: " + customerID + ", " + name + ", " + city + ", "
+        + country;
+  }
+
+  public int getCustomerID() {
+    return customerID;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String getAddress() {
+    return address;
+  }
+
+  public String getCity() {
+    return city;
+  }
+
+  public String getCountry() {
+    return country;
+  }
+
+  public String getPhone() {
+    return phone;
+  }
+
+  public List<Order> getOrders() {
+    return orders;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/DataBase.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/DataBase.java
new file mode 100644
index 0000000..037702d
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/DataBase.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DataBase {
+
+  private int curCustomer = 100;
+
+  private int curProduct = 200;
+
+  private int curOrder = 10;
+
+  private boolean inited;
+
+  private List<Customer> customers;
+
+  private List<Product> products;
+
+  private List<Order> orders;
+
+  private List<Integer> ints;
+
+  public List<Integer> getInts() {
+    return this.ints;
+  }
+
+  public List<Customer> getCustomers() {
+    return this.customers;
+  }
+
+  public List<Product> getProducts() {
+    return this.products;
+  }
+
+  public List<Order> getOrders() {
+    return this.orders;
+  }
+
+  public void init() {
+    if (inited) {
+      return;
+    }
+
+    inited = true;
+    customers = new ArrayList<Customer>();
+    orders = new ArrayList<Order>();
+    products = new ArrayList<Product>();
+    ints = new ArrayList<Integer>();
+
+    initCustomer();
+    initProduct();
+    initOrder();
+    initNums();
+  }
+
+  void initNums() {
+    for (int i = 0; i < 10; i++) {
+      ints.add(Integer.valueOf(i));
+    }
+  }
+
+  void initCustomer() {
+    c("John Doe", "123 Willow Road", "Menlo Park", "USA", "650-734-2187");
+    c("Mary Lane", "75 State Street", "Atlanta", "USA", "302-145-8765");
+    c("Charlie Yeh", "5 Nathan Road", "Kowlon", "Hong Kong", "11-7565-2323");
+  }
+
+  void initProduct() {
+    p("Eagle", "book", 12.50, 100); // id: 200
+    p("Coming Home", "dvd", 8.00, 50); // id: 201
+    p("Greatest Hits", "cd", 6.5, 200); // id: 202
+    p("History of Golf", "book", 11.0, 30); // id: 203
+    p("Toy Story", "dvd", 10.00, 1000); // id: 204
+    p("iSee", "book", 12.50, 150); // 205
+  }
+
+  void initOrder() {
+    o(100, new Date(2010, 2, 18), 20.80);
+    o(100, new Date(2011, 5, 3), 34.50);
+    o(100, new Date(2011, 8, 2), 210.75);
+    o(101, new Date(2011, 1, 15), 50.23);
+    o(101, new Date(2012, 1, 3), 126.77);
+    o(102, new Date(2011, 4, 15), 101.20);
+  }
+
+  void c(String name, String address, String city, String country,
+      String phone) {
+    customers
+        .add(new Customer(curCustomer++, name, address, city, country, phone));
+  }
+
+  void o(int customerID, Date orderDate, double total) {
+    Order order = new Order(curOrder++, customerID, orderDate, total);
+    this.orders.add(order);
+    findCustomer(customerID).getOrders().add(order);
+  }
+
+  void p(String name, String category, double unitPrice, int unitsInStock) {
+    products.add(
+        new Product(curProduct++, name, category, unitPrice, unitsInStock));
+  }
+
+  private Customer findCustomer(int id) {
+    for (Customer customer : customers) {
+      if (customer.customerID == id) {
+        return customer;
+      }
+    }
+    return null;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/Date.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/Date.java
new file mode 100644
index 0000000..6f1a238
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/Date.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+public class Date {
+  int year, month, date;
+
+  public Date(int year, int month, int date) {
+    this.year = year;
+    this.month = month;
+    this.date = date;
+  }
+
+  public int getYear() {
+    return year;
+  }
+
+  public int getMonth() {
+    return month;
+  }
+
+  public int getDate() {
+    return date;
+  }
+
+  public String toString() {
+    return "" + month + "/" + date + "/" + year;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/ELTestUtil.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/ELTestUtil.java
new file mode 100644
index 0000000..a5ef130
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/ELTestUtil.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id:  $
+ */
+package com.sun.ts.tests.el.common.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import java.lang.System.Logger;
+
+public final class ELTestUtil {
+
+  private static final Logger logger = System.getLogger(ELTestUtil.class.getName());
+
+  public static final String NL = System.getProperty("line.separator", "\n");
+
+  public static final String PASS = "Test PASSED";
+
+  public static final String FAIL = "Test FAILED";
+
+  private ELTestUtil() {
+    throw new IllegalStateException();
+  }
+
+  /**
+   * Checks to see if a NullPointerException is thrown from a given
+   * method(methName) from a given Class(className). use this method for any
+   * none Abstract classes you wish to test.
+   * 
+   * @param className
+   *          - The Class that has the method under test.
+   * @param methName
+   *          - The method that you want to test.
+   * @param argTypes
+   *          - The type value of the arguments for the method under test.
+   * @param params
+   *          - The parameters you are feeding into the method under test.
+   * 
+   * @throws Exception
+   */
+  public static void checkForNPE(String className, String methName,
+      Class<?>[] argTypes, Object[] params) throws Exception {
+
+    try {
+      checkForNPE(Class.forName(className), methName, argTypes, params);
+
+    } catch (ClassNotFoundException cnfe) {
+      throw new Exception(FAIL + NL + cnfe.toString());
+    }
+
+  } // End checkForNPE
+
+  /**
+   * Checks to see if a NullPointerException is thrown from a given
+   * method(methName) from a given Class. use this method for any Abstract
+   * classes you wish to test. You can pass in the instantiated class that you
+   * want to test.
+   * 
+   * @param Class
+   *          - The class you want to test.
+   * @param methName
+   *          - The method that you want to test.
+   * @param argTypes
+   *          - The type value of the arguments for the method under test.
+   * @param params
+   *          - The parameters you are feeding into the method under test.
+   * 
+   * @throws Exception
+   */
+  public static void checkForNPE(Class<?> clazz, String methName,
+      Class<?>[] argTypes, Object[] params) throws Exception {
+
+    try {
+      checkForNPE(clazz.newInstance(), methName, argTypes, params);
+
+    } catch (Exception e) {
+      throw new Exception(FAIL + NL + e.toString());
+    }
+
+  } // End checkForNPE
+
+  /**
+   * Checks to see if a NullPointerException is thrown from a given
+   * method(methName) from a given Class. use this method for any Abstract
+   * classes you wish to test. You can pass in the instantiated class that you
+   * want to test.
+   * 
+   * @param object
+   *          - The Object you want to test.
+   * @param methName
+   *          - The method that you want to test.
+   * @param argTypes
+   *          - The type value of the arguments for the method under test.
+   * @param params
+   *          - The parameters you are feeding into the method under test.
+   * 
+   * @throws Exception
+   */
+  public static void checkForNPE(Object object, String methName,
+      Class<?>[] argTypes, Object[] params) throws Exception {
+
+    checkForException(object, methName, argTypes, params,
+        new NullPointerException());
+
+  } // End checkForNPE
+
+  /**
+   * Checks to see if a ClassNotFoundException is thrown
+   * 
+   * @param object
+   *          - The Object you want to test.
+   * @param methName
+   *          - The method that you want to test.
+   * @param argTypes
+   *          - The type value of the arguments for the method under test.
+   * @param params
+   *          - The parameters you are feeding into the method under test.
+   * 
+   * @throws Exception
+   */
+  public static void checkForCNFE(Object object, String methName,
+      Class<?>[] argTypes, Object[] params) throws Exception {
+
+    checkForException(object, methName, argTypes, params,
+        new ClassNotFoundException());
+
+  } // End checkForCNFE
+
+  /**
+   * Checks to see if a NoSuchMethodException is thrown
+   * 
+   * @param object
+   *          - The Object you want to test.
+   * @param methName
+   *          - The method that you want to test.
+   * @param argTypes
+   *          - The type value of the arguments for the method under test.
+   * @param params
+   *          - The parameters you are feeding into the method under test.
+   * 
+   * @throws Exception
+   */
+  public static void checkForNSME(Object object, String methName,
+      Class<?>[] argTypes, Object[] params) throws Exception {
+
+    checkForException(object, methName, argTypes, params,
+        new NoSuchMethodException());
+
+  } // End checkForCNFE
+
+  // ------------------------------------ private methods
+
+  /*
+   * Checks to see if a NoSuchMethodException is thrown
+   * 
+   * @param object - The Object you want to test.
+   * 
+   * @param methName - The method that you want to test.
+   * 
+   * @param argTypes - The type value of the arguments for the method under
+   * test.
+   * 
+   * @param params - The parameters you are feeding into the method under test.
+   * 
+   * @throws Exception
+   */
+  private static void checkForException(Object object, String methName,
+      Class<?>[] argTypes, Object[] params, Object exceptionType) throws Exception {
+
+    StringBuffer buff = new StringBuffer();
+    String className = object.getClass().getName();
+    String exceptionMess = buildMess(exceptionType.getClass().getSimpleName());
+
+    try {
+      Method execMeth = object.getClass().getMethod(methName, argTypes);
+      execMeth.invoke(object, params);
+
+      buff.append(FAIL + " No Exception thrown!" + NL + "Expected a "
+          + exceptionType.getClass().getSimpleName() + " to be thrown!" + NL
+          + "when testing: " + className + "." + methName);
+
+    } catch (InvocationTargetException ite) {
+      if (exceptionType.getClass().isInstance(ite.getCause())) {
+        logger.log(Logger.Level.INFO, PASS);
+        return;
+
+      } else {
+        buff.append(exceptionMess + ite.getCause().getClass().getSimpleName()
+            + NL + "When testing: " + className + "." + methName + NL
+            + ite.getCause().toString());
+      }
+
+    } catch (Throwable t) {
+      buff.append(exceptionMess + t.getClass().getSimpleName() + NL
+          + "When testing: " + className + "." + methName + NL + t.toString());
+    }
+
+    throw new Exception(FAIL + NL + buff.toString());
+
+  } // End checkForException
+
+  private static String buildMess(String exceptionName) {
+    return FAIL + " Unexpected Exception Thrown!" + NL + "Expected: "
+        + exceptionName + NL + "Received: ";
+  }
+
+  public static void printStackTrace(Throwable e) {
+    if (e == null) {
+      return;
+    }
+    try {
+      StringWriter sw = new StringWriter();
+      PrintWriter writer = new PrintWriter(sw);
+      e.printStackTrace(writer);
+      writer.close();
+    } catch (Exception E) {
+    }
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/ExprEval.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/ExprEval.java
new file mode 100644
index 0000000..f6a917b
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/ExprEval.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.math.RoundingMode;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+
+import com.sun.ts.tests.el.common.elcontext.SimpleELContext;
+
+import jakarta.el.ELContext;
+import jakarta.el.ELException;
+import jakarta.el.ELResolver;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.MethodExpression;
+import jakarta.el.PropertyNotFoundException;
+import jakarta.el.PropertyNotWritableException;
+import jakarta.el.ValueExpression;
+
+import java.lang.System.Logger;
+
+public final class ExprEval {
+
+  private static final Logger logger = System.getLogger(ExprEval.class.getName());
+
+  // Suppress default constructor for non-instantiability
+  private ExprEval() {
+  }
+
+  public static String buildElExpr(boolean deferred, String operation) {
+
+    String sandwich = null;
+    if (operation == null)
+      sandwich = "{A}";
+    else if ("unary_minus".equals(operation))
+      sandwich = "{-A}";
+    else if ("unary_not".equals(operation))
+      sandwich = "{not A}";
+    else if ("unary_bang".equals(operation))
+      sandwich = "{! A}";
+    else if ("empty".equals(operation))
+      sandwich = "{empty A}";
+    else if ("conditional".equals(operation))
+      sandwich = "{A " + "?" + "B" + ":" + " C}";
+    else // binary operation
+      sandwich = "{A " + operation + " B}";
+
+    return (deferred) ? "#" + sandwich : "$" + sandwich;
+  }
+
+  /**
+   * Evaluates the ValueExpression expression relative to the provided context
+   * and resolverType, then returns the resulting value.
+   *
+   * @param exprStr
+   *          - the String for the expression to be evaluated e.g. "${A + B}"
+   * @param nameVals
+   *          - an array of NameValuePair objects, each of which contains an
+   *          expression variable and the value to which it is to be set.
+   * @param expectedClass
+   *          - the type of the result produced by evaluating the expression.
+   * @param resolverType
+   *          - The type of ELResolver to use for expression resolution.
+   *
+   * @return - The result of the expression evaluation.
+   * 
+   * @throws jakarta.el.ELException
+   * @throws jakarta.el.PropertyNotFoundException
+   * @throws jakarta.el.PropertyNotWritableException
+   */
+  public static Object evaluateValueExpression(String exprStr,
+      NameValuePair[] nameVals, Class expectedClass, ResolverType resolverType)
+      throws ELException, PropertyNotFoundException,
+      PropertyNotWritableException {
+
+    // get what we need to create the expression
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    ELContext context = (new SimpleELContext(resolverType)).getELContext();
+    ELResolver resolver = context.getELResolver();
+    ExprEval.cleanup();
+
+    // set the values of variables to be used in the expression
+    if (nameVals == null) {
+      resolver.setValue(context, null, "A", null);
+      logger.log(Logger.Level.TRACE, "setting var 'A' to value null");
+      resolver.setValue(context, null, "B", null);
+      logger.log(Logger.Level.TRACE, "setting var 'B' to value null");
+
+    } else {
+      for (int i = 0; i < nameVals.length; ++i) {
+        String name = nameVals[i].getName();
+        Object val = nameVals[i].getValue();
+        logger.log(Logger.Level.TRACE, "setting var " + name + " to value " + val);
+        resolver.setValue(context, null, name, val);
+      }
+    }
+
+    // create the expression
+    logger.log(Logger.Level.TRACE, "Creating ValueExpression");
+    logger.log(Logger.Level.TRACE, "context is " + context.getClass().toString());
+    logger.log(Logger.Level.TRACE, "exprStr is " + exprStr);
+    logger.log(Logger.Level.TRACE, "expectedClass is " + expectedClass.toString());
+    logger.log(Logger.Level.TRACE, 
+        "resolver is " + context.getELResolver().getClass().toString());
+    ValueExpression vexp = expFactory.createValueExpression(context, exprStr,
+        expectedClass);
+
+    // now evaluate
+    return vexp.getValue(context);
+  }
+
+  /**
+   * Evaluates the ValueExpression expression relative to the provided context
+   * and the resolverType of
+   * com.sun.ts.tests.el.common.elresolver.VariableELResolver, then returns the
+   * resulting value.
+   *
+   * @param exprStr
+   *          - the String for the expression to be evaluated e.g. "${A + B}"
+   * @param nameVals
+   *          - an array of NameValuePair Objects, each of which contains an
+   *          expression variable and the value to which it is to be set
+   * @param expectedClass
+   *          - the type of the result produced by evaluating the expression.
+   *
+   * @return - The result of the expression evaluation.
+   *
+   * @throws jakarta.el.ELException
+   * @throws jakarta.el.PropertyNotFoundException
+   * @throws jakarta.el.PropertyNotWritableException
+   */
+  public static Object evaluateValueExpression(String exprStr,
+      NameValuePair[] nameVals, Class expectedClass) throws ELException,
+      PropertyNotFoundException, PropertyNotWritableException {
+
+    return ExprEval.evaluateValueExpression(exprStr, nameVals, expectedClass,
+        ResolverType.VARIABLE_ELRESOLVER);
+  }
+
+  /**
+   * Used to evaluate MethodExpression()
+   * 
+   * @param exprStr
+   *          - Expression to be parsed as a MethodExpression.
+   * @param params
+   *          - Parameters to pass to the method, or null if no parameters.
+   * @param expectedClass
+   *          - Expected return type.
+   * @param resolverType
+   *          - ELResolver to use for expression resolution.
+   *
+   * @return - the result of the method invocation.
+   * 
+   * @throws jakarta.el.ELException
+   * @throws jakarta.el.PropertyNotFoundException
+   * @throws jakarta.el.PropertyNotWritableException
+   */
+  public static Object evaluateMethodExpression(String exprStr, Class[] params,
+      Class expectedClass, ResolverType resolverType) throws ELException,
+      PropertyNotFoundException, PropertyNotWritableException {
+
+    // get what we need to create the expression
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    ELContext context = (new SimpleELContext(resolverType)).getELContext();
+
+    // create the expression
+    MethodExpression mexp = expFactory.createMethodExpression(context, exprStr,
+        expectedClass, params);
+
+    // now evaluate it
+    return mexp.invoke(context, params);
+  }
+
+  /**
+   * @param exprStr
+   *          - Expression to be parsed.
+   * @param exprVal
+   *          - The value passed to ValueExpression.setValue().
+   * @param expectedClass
+   *          - Expected return type.
+   *
+   * @return - the result of the method invocation.
+   *
+   * @throws jakarta.el.ELException
+   * @throws jakarta.el.PropertyNotFoundException
+   * @throws jakarta.el.PropertyNotWritableException
+   *
+   */
+  public static Object evaluateCoerceValueExpression(String exprStr,
+      Object exprVal, Class expectedClass) throws ELException,
+      PropertyNotFoundException, PropertyNotWritableException {
+
+    // get what we need to create the expression
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    ELContext context = (new SimpleELContext(ResolverType.VARIABLE_ELRESOLVER))
+        .getELContext();
+
+    // create the expression
+    ValueExpression vexp = expFactory.createValueExpression(context, exprStr,
+        expectedClass);
+
+    // set expression value
+    vexp.setValue(context, exprVal);
+
+    // grab the value for evaluation.
+    return vexp.getValue(context);
+  }
+
+  /**
+   * Parse a ValueExpression once, evaluate it many times, while adding Context
+   * Objects to the ELContext one at a time.
+   *
+   * @param exprStr
+   *          - Expression to be parsed.
+   * @param exprVal
+   *          - The value passed to ValueExpression.setValue().
+   * @param expectedClass
+   *          - Expected return type.
+   * @param contextobj
+   *          - a Hashtable of context objects in the form of key=Class,
+   *          value=value.
+   * @throws jakarta.el.ELException
+   * @throws jakarta.el.PropertyNotFoundException
+   * @throws jakarta.el.PropertyNotWritableException
+   * @throws java.lang.ClassNotFoundException
+   * @return - status of the evaluation.
+   */
+  public static boolean evaluateManyValueExpression(String exprStr,
+      Object exprVal, Class expectedClass, Hashtable contextobj)
+      throws ELException, PropertyNotFoundException,
+      PropertyNotWritableException, ClassNotFoundException {
+
+    boolean result = true;
+
+    // get what we need to create the expression
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    ELContext context = (new SimpleELContext(ResolverType.VARIABLE_ELRESOLVER))
+        .getELContext();
+
+    // create the expression
+    ValueExpression vexp = expFactory.createValueExpression(context, exprStr,
+        expectedClass);
+
+    // set expression value
+    vexp.setValue(context, exprVal);
+
+    // start adding objects to the Context.
+    Enumeration keys = contextobj.keys();
+    while (keys.hasMoreElements()) {
+      Class cl = (Class) keys.nextElement();
+      Object value = contextobj.get(cl);
+
+      // add the object
+      context.putContext(cl, value);
+      logger.log(Logger.Level.TRACE, "Adding value: " + "\"" + value + "\"" + " To Context!");
+
+      // test the expression
+      if (!(ExprEval.compareValue(exprVal, vexp.getValue(context)))) {
+        logger.log(Logger.Level.ERROR, "Expression Failed! After Adding: " + "\"" + value
+            + "\"" + " To Context");
+        result = false;
+      }
+    }
+
+    // return the status of the evaluation.
+    return result;
+
+  }
+
+  public static boolean compareClass(Object obj, Class expectedClass) {
+
+    boolean isInstance = expectedClass.isInstance(obj);
+    if (!isInstance) {
+      logger.log(Logger.Level.ERROR, "Unexpected type for expression evaluation");
+      logger.log(Logger.Level.ERROR, "Expected type: " + expectedClass.toString());
+      logger.log(Logger.Level.ERROR, "Computed type: " + obj.getClass().toString());
+    }
+    return isInstance;
+  }
+
+  public static boolean compareValue(Object val, Object expectedVal) {
+
+    if (!val.equals(expectedVal)) {
+      logger.log(Logger.Level.ERROR, "Unexpected value for expression evaluation");
+      logger.log(Logger.Level.ERROR, "Expected value: " + expectedVal.toString());
+      logger.log(Logger.Level.ERROR, "Computed value: " + val.toString());
+      return false;
+    }
+
+    return true;
+  }
+
+  public static boolean compareValue(Boolean val, Boolean expectedVal) {
+
+    if (!val.equals(expectedVal)) {
+      logger.log(Logger.Level.ERROR, "Unexpected value for expression evaluation");
+      logger.log(Logger.Level.ERROR, "Expected value: " + expectedVal.toString());
+      logger.log(Logger.Level.ERROR, "Computed value: " + val.toString());
+      return false;
+    }
+
+    return true;
+  }
+
+  public static boolean compareValue(Double val, Float expectedVal, int eps) {
+
+    BigDecimal a = new BigDecimal(val);
+    BigDecimal b = new BigDecimal(expectedVal);
+
+    return compareValue(a, b, eps);
+  }
+
+  public static boolean compareValue(Float val, Float expectedVal, int eps) {
+
+    BigDecimal a = new BigDecimal(val);
+    BigDecimal b = new BigDecimal(expectedVal);
+
+    return compareValue(a, b, eps);
+  }
+
+  public static boolean compareValue(Long val, Long expectedVal, int eps) {
+
+    BigDecimal a = new BigDecimal(val);
+    BigDecimal b = new BigDecimal(expectedVal);
+
+    return compareValue(a, b, eps);
+  }
+
+  public static boolean compareValue(BigInteger val, BigInteger expectedVal,
+      int eps) {
+
+    BigDecimal a = new BigDecimal(val);
+    BigDecimal b = new BigDecimal(expectedVal);
+
+    return compareValue(a, b, eps);
+  }
+
+  public static boolean compareValue(BigDecimal val, BigDecimal expectedVal,
+      int eps) {
+
+    MathContext mc = new MathContext(eps, RoundingMode.DOWN);
+    BigDecimal a = val.abs(mc);
+    BigDecimal b = expectedVal.abs(mc);
+
+    if (!(0 == a.compareTo(b))) {
+      logger.log(Logger.Level.ERROR, "Unexpected value for expression evaluation");
+      logger.log(Logger.Level.ERROR, "Expected value: " + expectedVal);
+      logger.log(Logger.Level.ERROR, "Computed value: " + val);
+      return false;
+    }
+
+    return true;
+  }
+
+  // This method is used to remove resolvable items from the static
+  // hashtable used by the SimpleELContext's VariableELResolver.
+  // It is meant to be called at the end of a test.
+  public static void cleanup() {
+    (new SimpleELContext()).cleanup();
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/Fault.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/Fault.java
new file mode 100644
index 0000000..dea2527
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/Fault.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+
+
+/**
+   * This exception must be thrown to signify a
+   * test failure. Overrides 3 printStackTrace methods to preserver the original
+   * stack trace. Using setStackTraceElement() would be more elegant but it is
+   * not available prior to j2se 1.4.
+   *
+   * @author Kyle Grucci
+   */
+  public class Fault extends Exception {
+    private static final long serialVersionUID = -1574745208867827913L;
+
+    public Throwable t;
+
+    /**
+     * creates a Fault with a message
+     */
+    public Fault(String msg) {
+      super(msg);
+      // TestUtil.logErr(msg);
+    }
+
+    /**
+     * creates a Fault with a message.
+     *
+     * @param msg
+     *          the message
+     * @param t
+     *          prints this exception's stacktrace
+     */
+    public Fault(String msg, Throwable t) {
+      super(msg);
+      this.t = t;
+      // TestUtil.logErr(msg, t);
+    }
+
+    /**
+     * creates a Fault with a Throwable.
+     *
+     * @param t
+     *          the Throwable
+     */
+    public Fault(Throwable t) {
+      super(t);
+      this.t = t;
+    }
+
+    /**
+     * Prints this Throwable and its backtrace to the standard error stream.
+     *
+     */
+    public void printStackTrace() {
+      if (this.t != null) {
+        this.t.printStackTrace();
+      } else {
+        super.printStackTrace();
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print stream.
+     *
+     * @param s
+     *          <code>PrintStream</code> to use for output
+     */
+    public void printStackTrace(PrintStream s) {
+      if (this.t != null) {
+        this.t.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print writer.
+     *
+     * @param s
+     *          <code>PrintWriter</code> to use for output
+     */
+    public void printStackTrace(PrintWriter s) {
+      if (this.t != null) {
+        this.t.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    @Override
+    public Throwable getCause() {
+      return t;
+    }
+
+    @Override
+    public synchronized Throwable initCause(Throwable cause) {
+      if (t != null)
+        throw new IllegalStateException("Can't overwrite cause");
+      if (!Exception.class.isInstance(cause))
+        throw new IllegalArgumentException("Cause not permitted");
+      this.t = (Exception) cause;
+      return this;
+    }
+  }
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/MethodsBean.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/MethodsBean.java
new file mode 100644
index 0000000..46bb82e
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/MethodsBean.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2021 Contributors to the Eclipse Foundation.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package com.sun.ts.tests.el.common.util;
+
+public class MethodsBean {
+
+  public String targetA(CharSequence arg0) {
+    return "CharSequence";
+  }
+
+  public String targetA(String arg0) {
+    return "String";
+  }
+
+  public String targetA(Long arg0) {
+    return "Long";
+  }
+
+  public String targetB(CharSequence arg0) {
+    return "CharSequence";
+  }
+
+  public String targetB(Long arg0) {
+    return "Long";
+  }
+  
+  public String targetC(CharSequence arg0, CharSequence arg1) {
+    return "CharSequence-CharSequence";
+  }
+
+  public String targetC(String arg0, String... varArgs) {
+    return "String-Strings";
+  }
+  
+  public String targetD(Long arg0, Long arg1) {
+    return "Long-Long";
+  }
+
+  public String targetD(String arg0, String... varArgs) {
+    return "String-Strings";
+  }
+  
+  public String targetE(Long arg0, Long arg1) {
+    return "Long-Long";
+  }
+
+  public String targetE(String arg0, String arg1) {
+    return "String-String";
+  }
+  
+  @Deprecated
+  public String targetF(String arg0, Long arg1) {
+    return "String-Long";
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/NameValuePair.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/NameValuePair.java
new file mode 100644
index 0000000..26a5de0
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/NameValuePair.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+// This class holds the name of a variable in an Expression
+// and the value to which the variable is to be set.
+public class NameValuePair {
+
+  private final String name;
+
+  private final Object value;
+
+  public NameValuePair(String name, Object value) {
+    this.name = name;
+    this.value = value;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public Object getValue() {
+    return value;
+  }
+
+  /*
+   * Builds a NameValuePair[] with values assigned to Tag Names A and B.
+   */
+  public static NameValuePair[] buildNameValuePair(Object a, Object b) {
+
+    NameValuePair value1 = new NameValuePair("A", a);
+    NameValuePair value2 = new NameValuePair("B", b);
+
+    NameValuePair values[] = { value1, value2 };
+
+    return values;
+  }
+
+  /*
+   * Builds a NameValuePair[] with a value assigned to Tag Name A.
+   */
+  public static NameValuePair[] buildUnaryNameValue(Object a) {
+
+    NameValuePair value1 = new NameValuePair("A", a);
+
+    NameValuePair value[] = { value1 };
+
+    return value;
+  }
+
+  /*
+   * Builds a NameValuePair[] with values assigned to Tag Names A, B, and C.
+   */
+  public static NameValuePair[] buildConditionalNameValue(Object a, Object b,
+      Object c) {
+
+    NameValuePair value1 = new NameValuePair("A", a);
+    NameValuePair value2 = new NameValuePair("B", b);
+    NameValuePair value3 = new NameValuePair("C", c);
+
+    NameValuePair values[] = { value1, value2, value3 };
+
+    return values;
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/Order.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/Order.java
new file mode 100644
index 0000000..49af247
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/Order.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+public class Order {
+
+  int orderID;
+
+  int customerID;
+
+  Date orderDate;
+
+  double total;
+
+  public Order(int orderID, int customerID, Date orderDate, double total) {
+    this.orderID = orderID;
+    this.customerID = customerID;
+    this.orderDate = orderDate;
+    this.total = total;
+  }
+
+  public String toString() {
+    return "Order: " + orderID + ", " + customerID + ", " + orderDate.toString()
+        + ", " + total;
+  }
+
+  public int getOrderID() {
+    return orderID;
+  }
+
+  public int getCustomerID() {
+    return customerID;
+  }
+
+  public Date getOrderDate() {
+    return orderDate;
+  }
+
+  public double getTotal() {
+    return total;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/Product.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/Product.java
new file mode 100644
index 0000000..7970bf4
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/Product.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+public class Product {
+
+  public int productID;
+
+  public String name;
+
+  public String category;
+
+  public double unitPrice;
+
+  public int unitsInStock;
+
+  Product(int productID, String name, String category, double unitPrice,
+      int unitsInStock) {
+
+    this.productID = productID;
+    this.name = name;
+    this.category = category;
+    this.unitPrice = unitPrice;
+    this.unitsInStock = unitsInStock;
+  }
+
+  public String toString() {
+    return "Product: " + productID + ", " + name + ", " + category + ", "
+        + unitPrice + ", " + unitsInStock;
+  }
+
+  public int getProductID() {
+    return productID;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String getCategory() {
+    return category;
+  }
+
+  public double getUnitPrice() {
+    return unitPrice;
+  }
+
+  public int getUnitsInStock() {
+    return unitsInStock;
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/ResolverType.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/ResolverType.java
new file mode 100644
index 0000000..f8beb2c
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/ResolverType.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+public enum ResolverType {
+  EMPLOYEE_ELRESOLVER, VARIABLE_ELRESOLVER, VECT_ELRESOLVER;
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/SimpleBean.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/SimpleBean.java
new file mode 100644
index 0000000..7f62e2d
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/SimpleBean.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+import java.io.Serializable;
+
+public class SimpleBean implements Serializable, SimpleInterface {
+
+  private String fullName = "Doug Donahue"; // Default Setting
+
+  private String intention;
+
+  public void setIntention(String s) {
+    intention = s;
+  }
+
+  public String getIntention() {
+    return intention;
+  }
+
+  /**
+   * Set full name using the pattern firstName + " " + lastName.
+   * 
+   * @param firstName
+   * @param lastName
+   */
+  public void setFullName(String firstName, String lastName) {
+    this.fullName = firstName + " " + lastName;
+  }
+
+  /**
+   *
+   * @param firstName
+   *          - first name @String
+   * @param lastName
+   *          - last Name
+   * @return true is full name matches the given firstName + " " + lastName
+   *         pattern.
+   */
+  public boolean isName(String firstName, String lastName) {
+    boolean result = Boolean.FALSE;
+    String testName = firstName + " " + lastName;
+
+    if (testName.equals(fullName)) {
+      result = true;
+    }
+
+    return result;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/SimpleInterface.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/SimpleInterface.java
new file mode 100644
index 0000000..ec20946
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/SimpleInterface.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021 Contributors to the Eclipse Foundation.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package com.sun.ts.tests.el.common.util;
+
+/**
+ * Defines an interface with default methods: one read-only, one read-write.
+ */
+public interface SimpleInterface {
+  default String getDefaultRO() {
+    return "RO";
+  }
+  default String getDefaultRW() {
+    return "RW";
+  }
+  default void setDefaultRW(String ignored) {
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/TestNum.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/TestNum.java
new file mode 100644
index 0000000..dfd191d
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/TestNum.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+package com.sun.ts.tests.el.common.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+
+/**
+ * Used to store lists that will be utilized accross the board for a common
+ * point of reference when testing.
+ */
+public final class TestNum {
+
+  private static final String COMPARATOR = "1";
+
+  private static ArrayList<Float> floatList;
+
+  private static ArrayList<Object> numberList;
+
+  /**
+   * Private as this class will only have static methods and members.
+   */
+  private TestNum() {
+  }
+
+  /**
+   * Used for a common list of Float values when testing.
+   * 
+   * @return - A set list of common Floats that we use as test values.
+   */
+  public static ArrayList getFloatList() {
+
+    floatList = new ArrayList<Float>();
+
+    floatList.add(Float.valueOf("1.00005f"));
+    floatList.add(Float.valueOf("1.5E-4d"));
+    floatList.add(Float.valueOf("1.5E+4"));
+    floatList.add(Float.valueOf("1.5e+4"));
+
+    return floatList;
+
+  }
+
+  /**
+   * Used a common reference point for Number types and a common value is
+   * assigned (1).
+   *
+   * @return - A common List of Number types with a constant value.
+   */
+  public static ArrayList getNumberList() {
+
+    numberList = new ArrayList<Object>();
+
+    numberList.add(BigDecimal.valueOf(Long.valueOf(COMPARATOR)));
+    numberList.add(Double.valueOf(COMPARATOR));
+    numberList.add(Float.valueOf(COMPARATOR));
+    numberList.add(COMPARATOR + ".0");
+    numberList.add(COMPARATOR + "e0");
+    numberList.add(COMPARATOR + "E0");
+    numberList.add(BigInteger.valueOf(Long.valueOf(COMPARATOR)));
+    numberList.add(Long.valueOf(COMPARATOR));
+    numberList.add(Integer.valueOf(COMPARATOR));
+    numberList.add(Short.valueOf(COMPARATOR));
+    numberList.add(Byte.valueOf(COMPARATOR));
+
+    return numberList;
+
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/TypesBean.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/TypesBean.java
new file mode 100644
index 0000000..2ef49fd
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/TypesBean.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashMap;
+
+/**
+ * This is a simple bean with different type values for testing Expressions.
+ * 
+ */
+public class TypesBean {
+  private final static String COMPARATOR = "1";
+
+  private static HashMap<Class<?>, String> numberMap;
+
+  private BigDecimal tckBigDecimal = BigDecimal
+      .valueOf(Long.valueOf(COMPARATOR));
+
+  private Double tckDouble = Double.valueOf(COMPARATOR);
+
+  private Float tckFloat = Float.valueOf(COMPARATOR);
+
+  private BigInteger tckBigInteger = BigInteger
+      .valueOf(Long.valueOf(COMPARATOR));
+
+  private Long tckLong = Long.valueOf(COMPARATOR);
+
+  private Integer tckInteger = Integer.valueOf(COMPARATOR);
+
+  private Short tckShort = Short.valueOf(COMPARATOR);
+
+  private Byte tckByte = Byte.valueOf(COMPARATOR);
+
+  private Boolean tckBoolean = true;
+
+  private Byte tckNull = null;
+
+  // Getter Setter for Type BigDeciaml
+  public BigDecimal getTckBigDecimal() {
+    return tckBigDecimal;
+  }
+
+  public void setTckBigDecimal(BigDecimal tckBigDecimal) {
+    this.tckBigDecimal = tckBigDecimal;
+  }
+
+  // Getter Setter for Type Double
+  public Double getTckDouble() {
+    return tckDouble;
+  }
+
+  public void setTckDouble(Double tckDouble) {
+    this.tckDouble = tckDouble;
+  }
+
+  // Getter Setter for Type Float
+  public Float getTckFloat() {
+    return tckFloat;
+  }
+
+  public void setTckFloat(Float tckFloat) {
+    this.tckFloat = tckFloat;
+  }
+
+  // Getter Setter for Type Integer
+  public BigInteger getTckBigInteger() {
+    return tckBigInteger;
+  }
+
+  public void setTckBigInteger(BigInteger tckBigInteger) {
+    this.tckBigInteger = tckBigInteger;
+  }
+
+  // Getter Setter for Type Long
+  public Long getTckLong() {
+    return tckLong;
+  }
+
+  public void setTckLong(Long tckLong) {
+    this.tckLong = tckLong;
+  }
+
+  // Getter Setter for Type Integer
+  public Integer getTckInteger() {
+    return tckInteger;
+  }
+
+  public void setTckInteger(Integer tckInt) {
+    this.tckInteger = tckInt;
+  }
+
+  // Getter Setter for Type Short
+  public Short getTckShort() {
+    return tckShort;
+  }
+
+  public void setTckShort(Short tchShort) {
+    this.tckShort = tchShort;
+  }
+
+  // Getter Setter for Type Byte
+  public Byte getTckByte() {
+    return tckByte;
+  }
+
+  public void setTckByte(Byte tckByte) {
+    this.tckByte = tckByte;
+  }
+
+  // Getter Setter for Type Boolean
+  public Boolean getTckBoolean() {
+    return tckBoolean;
+  }
+
+  public void setTckBoolean(Boolean tckBoolean) {
+    this.tckBoolean = tckBoolean;
+  }
+
+  public Byte getTckNull() {
+    return tckNull;
+  }
+
+  public void setTckNullString(Byte tckNull) {
+    this.tckNull = tckNull;
+  }
+
+  /**
+   * This method will return an HaashMap of Key = Class, Value = String for the
+   * purpose of using them in an ElProcessor expression.
+   * 
+   * 
+   * @return - A common List of Number types with a constant value.
+   */
+  public static HashMap<Class<?>, String> getNumberMap() {
+
+    numberMap = new HashMap<Class<?>, String>();
+
+    numberMap.put(BigDecimal.class, "b = types.tckBigDecimal");
+    numberMap.put(Double.class, "b = types.tckDouble");
+    numberMap.put(Float.class, "b = types.tckFloat");
+    numberMap.put(BigInteger.class, "b = types.tckBigInteger");
+    numberMap.put(Long.class, "b = types.tckLong");
+    numberMap.put(Integer.class, "b = types.tckInteger");
+    numberMap.put(Short.class, "b = types.tckShort");
+    numberMap.put(Byte.class, "b = types.tckByte");
+
+    return numberMap;
+
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/common/util/Validator.java b/tck/src/main/java/com/sun/ts/tests/el/common/util/Validator.java
new file mode 100644
index 0000000..3c74a29
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/common/util/Validator.java
@@ -0,0 +1,998 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.common.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+
+import jakarta.el.ELProcessor;
+
+import java.lang.System.Logger;
+
+public class Validator {
+
+  private static final Logger logger = System.getLogger(Validator.class.getName());
+
+  private static Validator instance = null;
+
+  protected Validator() {
+    // Exists only to defeat instantiation.
+  }
+
+  private Validator getInstance() {
+    if (instance == null) {
+      instance = new Validator();
+    }
+    return instance;
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one
+   * BigDecimal in it. We pass in one of the operands(testVal), the other
+   * operand is automatically picked up from the NumberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testBigDecimal(BigDecimal testVal, Object expectedVal,
+      String operator) throws Exception {
+    boolean pass = false;
+    Class<?> returnType;
+
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO, 
+          "*** Start " + "\"" + "BigDecimal" + "\"" + " Test Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are BigDecimal and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        /*
+         * If operator is "+=" (concatenation) then coerce both operands to
+         * String and concatenate them. (NEW to EL 3.0)
+         */
+        if ("+=".equals(operator)) {
+
+          pass = Validator.runConcatenationTest(testVal, result, testNum);
+
+          // If the Operator is "%" then the return type is Double.
+        } else if ("%".equals(operator)) {
+
+          returnType = Double.class;
+          logger.log(Logger.Level.INFO, "Setting Expected Type: " + returnType.getName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Double) result,
+                  Double.valueOf(((BigDecimal) expectedVal).doubleValue())));
+        } else {
+          returnType = BigDecimal.class;
+          logger.log(Logger.Level.INFO, "Setting Expected Type: " + returnType.getName());
+
+          pass = (ExprEval.compareClass(result, returnType) && ExprEval
+              .compareValue((BigDecimal) result, (BigDecimal) expectedVal, 5));
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO, 
+            "*** End " + "\"" + "BigDecimal" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one Float
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the NumberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testFloat(Float testVal, Object expectedVal,
+      String operator) throws Exception {
+
+    boolean pass = false;
+    Class<?> returnType;
+
+    // For each NumberType in this list.
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO, "*** Start " + "\"" + "Float" + "\"" + " Test Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      // If Test value from numberList is BigDecimal skip it.
+      if (testNum instanceof BigDecimal) {
+        logger.log(Logger.Level.INFO, "Skip " + testNum.getClass().getSimpleName()
+            + " for Float tests we already tested for this in the"
+            + " BigDecimal tests.");
+        continue;
+      }
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are Float and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        /*
+         * If operator is "+="concatenation then coerce both operands to String
+         * and concatenate them. (NEW to EL 3.0)
+         */
+        if ("+=".equals(operator)) {
+          pass = Validator.runConcatenationTest(testVal, result, testNum);
+
+          // If the Operator is "%" then the return type is Double.
+        } else if ("%".equals(operator)) {
+          returnType = Double.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Double) result,
+                  Double.valueOf(((Float) expectedVal).doubleValue())));
+        } else {
+          if (testNum instanceof BigInteger) {
+            returnType = BigDecimal.class;
+            logger.log(Logger.Level.INFO, 
+                "Setting Expected Type: " + returnType.getCanonicalName());
+
+            pass = (ExprEval.compareClass(result, returnType)
+                && ExprEval.compareValue(((BigDecimal) result).floatValue(),
+                    (Float) expectedVal, 3));
+          } else {
+            returnType = Double.class;
+            logger.log(Logger.Level.INFO, 
+                "Setting Expected Type: " + returnType.getCanonicalName());
+
+            pass = (ExprEval.compareClass(result, returnType) && ExprEval
+                .compareValue((Double) result, (Float) expectedVal, 3));
+          }
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO, "*** End " + "\"" + "Float" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one Double
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the NumberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testDouble(Double testVal, Object expectedVal,
+      String operator) throws Exception {
+
+    boolean pass = false;
+    Class<?> returnType;
+
+    // For each NumberType in this list.
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO, 
+          "*** Start " + "\"" + "Double" + "\"" + "Test " + "Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      // If Test value from numberList is BigDecimal, Float skip it.
+      if ((testNum instanceof BigDecimal) || (testNum instanceof Float)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.INFO, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are Double and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        /*
+         * If operator is "+=" (concatenation) then coerce both operands to
+         * String and concatenate them. (NEW to EL 3.0)
+         */
+        if ("+=".equals(operator)) {
+          pass = Validator.runConcatenationTest(testVal, result, testNum);
+
+          // If the Operator is "%" then the return type is Double.
+        } else if ("%".equals(operator)) {
+          returnType = Double.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Double) result, expectedVal));
+        } else {
+          if (testNum instanceof BigInteger) {
+            returnType = BigDecimal.class;
+            logger.log(Logger.Level.INFO, 
+                "Setting Expected Type: " + returnType.getCanonicalName());
+
+            pass = (ExprEval.compareClass(result, returnType)
+                && ExprEval.compareValue(((BigDecimal) result).doubleValue(),
+                    expectedVal));
+          } else {
+            returnType = Double.class;
+            logger.log(Logger.Level.INFO, 
+                "Setting Expected Type: " + returnType.getCanonicalName());
+
+            pass = (ExprEval.compareClass(result, returnType)
+                && ExprEval.compareValue((Double) result, expectedVal));
+          }
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO, "*** End " + "\"" + "Double" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one
+   * NumericString in it (numeric String containing ".", "e", or "E". We pass in
+   * one of the operands(testVal), the other operand is automatically picked up
+   * from the NumberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testNumericString(String testVal, Double expectedVal,
+      String operator) throws Exception {
+
+    boolean pass = false;
+    Class<?> returnType;
+
+    // For each NumberType in this list.
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO, "*** Start " + "\"" + "NumericString" + "\"" + "Test "
+          + "Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      // If Test value from numberList is BigDecimal, Float, Double skip
+      // it.
+      if ((testNum instanceof BigDecimal) || (testNum instanceof Float)
+          || (testNum instanceof Double)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.INFO, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are String and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        if ("%".equals(operator)) {
+          returnType = Double.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Double) result, expectedVal));
+        } else {
+          if (testNum instanceof BigInteger) {
+            returnType = BigDecimal.class;
+            logger.log(Logger.Level.INFO, 
+                "Setting Expected Type: " + returnType.getCanonicalName());
+
+            pass = (ExprEval.compareClass(result, returnType)
+                && ExprEval.compareValue(((BigDecimal) result).doubleValue(),
+                    expectedVal));
+          } else {
+            returnType = Double.class;
+            logger.log(Logger.Level.INFO, 
+                "Setting Expected Type: " + returnType.getCanonicalName());
+
+            pass = (ExprEval.compareClass(result, returnType)
+                && ExprEval.compareValue((Double) result, expectedVal));
+          }
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO, 
+            "*** End " + "\"" + "NumericString" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one
+   * BigInteger in it. We pass in one of the operands(testVal), the other
+   * operand is automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testBigInteger(BigInteger testVal, Object expectedVal,
+      String operator) throws Exception {
+
+    boolean pass = false;
+    Class<?> returnType;
+
+    // For each NumberType in this list.
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO, 
+          "*** Start " + "\"" + "BigInteger" + "\"" + " Test Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      // If Test value from numberList BigDecimal, Float, Double, or
+      // String skip it.
+      if ((testNum instanceof BigDecimal) || (testNum instanceof Float)
+          || (testNum instanceof Double) || (testNum instanceof String)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.INFO, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are BigInteger and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        /*
+         * If operator is "+=" then coerce both operands to String and
+         * concatenate them. (NEW to EL 3.0)
+         */
+        if ("+=".equals(operator)) {
+          pass = Validator.runConcatenationTest(testVal, result, testNum);
+
+          // If the Operator is "/" then the return type is
+          // BigDecimal.
+        } else if ("/".equals(operator)) {
+          returnType = BigDecimal.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((BigDecimal) result,
+                  BigDecimal.valueOf(((BigInteger) expectedVal).doubleValue()),
+                  0));
+        } else {
+          returnType = BigInteger.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType) && ExprEval
+              .compareValue((BigInteger) result, (BigInteger) expectedVal, 0));
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO, 
+            "*** End " + "\"" + "BigInteger" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one Long
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testLong(Long testVal, Object expectedVal, String operator)
+      throws Exception {
+
+    boolean pass = false;
+    Class<?> returnType;
+
+    // For each NumberType in this list.
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO, "*** Start " + "\"" + "Long" + "\"" + " Test Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      // If Test value from numberList BigDecimal, Float, Double,
+      // String or BigInteger skip it.
+      if ((testNum instanceof BigDecimal) || (testNum instanceof Float)
+          || (testNum instanceof Double) || (testNum instanceof String)
+          || (testNum instanceof BigInteger)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.INFO, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are  Long and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        /*
+         * If operator is "+=" then coerce both operands to String and
+         * concatenate them. (NEW to EL 3.0)
+         */
+        if ("+=".equals(operator)) {
+          pass = Validator.runConcatenationTest(testVal, result, testNum);
+
+          // If the Operator is "/" then the return type is Double.
+        } else if ("/".equals(operator)) {
+          returnType = Double.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Double) result,
+                  ((Long) expectedVal).doubleValue()));
+        } else {
+          returnType = Long.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Long) result, (Long) expectedVal, 0));
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO, "*** End " + "\"" + "Long" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one
+   * Integer in it. We pass in one of the operands(testVal), the other operand
+   * is automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testInteger(Integer testVal, Object expectedVal,
+      String operator) throws Exception {
+
+    boolean pass = false;
+    Class<?> returnType;
+
+    // For each NumberType in this list.
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO, 
+          "*** Start " + "\"" + "Integer" + "\"" + " Test Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      // If Test value from numberList BigDecimal, Float, Double, String,
+      // Long, or BigInteger skip it.
+      if ((testNum instanceof BigDecimal) || (testNum instanceof Float)
+          || (testNum instanceof Double) || (testNum instanceof String)
+          || (testNum instanceof Long) || (testNum instanceof BigInteger)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.INFO, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are  Integer and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        /*
+         * If operator is "+=" then coerce both operands to String and
+         * concatenate them. (NEW to EL 3.0)
+         */
+        if ("+=".equals(operator)) {
+          pass = Validator.runConcatenationTest(testVal, result, testNum);
+
+          // If the Operator is "/" then the return type is Double.
+        } else if ("/".equals(operator)) {
+          returnType = Double.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Double) result,
+                  ((Integer) expectedVal).doubleValue()));
+        } else {
+          returnType = Long.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Long) result,
+                  ((Integer) expectedVal).longValue()));
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO, 
+            "*** End " + "\"" + "Integer" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one Short
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testShort(Short testVal, Object expectedVal,
+      String operator) throws Exception {
+
+    boolean pass = false;
+    Class<?> returnType;
+
+    // For each NumberType in this list.
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO,"*** Start " + "\"" + "Short" + "\"" + " Test Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      // If Test value from numberList BigDecimal, Float, Double, String,
+      // Long, BigInteger, Integer skip it.
+      if (!(testNum instanceof Short || testNum instanceof Byte)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.INFO, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are  Short and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        /*
+         * If operator is "+=" then coerce both operands to String and
+         * concatenate them. (NEW to EL 3.0)
+         */
+        if ("+=".equals(operator)) {
+          pass = Validator.runConcatenationTest(testVal, result, testNum);
+
+          // If the Operator is "/" then the return type is Double.
+        } else if ("/".equals(operator)) {
+          returnType = Double.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Double) result,
+                  ((Short) expectedVal).doubleValue()));
+        } else {
+          returnType = Long.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType) && ExprEval
+              .compareValue((Long) result, ((Short) expectedVal).longValue()));
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO, "*** End " + "\"" + "Short" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that have at least one Byte
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testByte(Byte testVal, Object expectedVal, String operator)
+      throws Exception {
+
+    boolean pass = false;
+    Class<?> returnType;
+
+    // For each NumberType in this list.
+    for (int i = 0; TestNum.getNumberList().size() > i; i++) {
+      logger.log(Logger.Level.INFO, "*** Start " + "\"" + "Byte" + "\"" + " Test Sequence ***");
+
+      Object testNum = TestNum.getNumberList().get(i);
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      // If Test value from numberList BigDecimal, Float, Double, String,
+      // Long, BigInteger, Integer, Short skip it.
+      if (!(testNum instanceof Byte)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.INFO, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      try {
+        String expr = ExprEval.buildElExpr(true, operator);
+        logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.INFO, "types are  Byte and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+
+        /*
+         * If operator is "+=" then coerce both operands to String and
+         * concatenate them. (NEW to EL 3.0)
+         */
+        if ("+=".equals(operator)) {
+          pass = Validator.runConcatenationTest(testVal, result, testNum);
+
+          // If the Operator is "/" then the return type is Double.
+        } else if ("/".equals(operator)) {
+          returnType = Double.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType)
+              && ExprEval.compareValue((Double) result,
+                  ((Byte) expectedVal).doubleValue()));
+        } else {
+          returnType = Long.class;
+          logger.log(Logger.Level.INFO, 
+              "Setting Expected Type: " + returnType.getCanonicalName());
+
+          pass = (ExprEval.compareClass(result, returnType) && ExprEval
+              .compareValue((Long) result, ((Byte) expectedVal).longValue()));
+        }
+
+      } catch (RuntimeException re) {
+        ELTestUtil.printStackTrace(re);
+        throw new Exception(re);
+
+      } catch (Exception e) {
+        ELTestUtil.printStackTrace(e);
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.INFO,"*** End " + "\"" + "Byte" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one boolean
+   * in it.
+   * 
+   * @param testValOne
+   *          - The boolean operand.
+   * @param testValTwo
+   *          - The second operand that will be coerced to a boolean.
+   * @param expectedVal
+   *          - The expected value returned from the Expression evaluation.
+   * @param operator
+   *          - The operator in which the operands are compared. (i.e. "+", "-",
+   *          etc...)
+   */
+  public static void testBoolean(boolean testValOne, Object testValTwo,
+      Object expectedVal, String operator) throws Exception {
+
+    boolean pass = false;
+
+    NameValuePair values[] = NameValuePair.buildNameValuePair(testValOne,
+        testValTwo);
+
+    try {
+      logger.log(Logger.Level.INFO, 
+          "*** Start " + "\"" + "Boolean" + "\"" + " Test Sequence ***");
+      String expr = ExprEval.buildElExpr(true, operator);
+      logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+      logger.log(Logger.Level.INFO, "types are  Boolean and " + testValTwo.getClass().getName());
+
+      Object result = ExprEval.evaluateValueExpression(expr, values,
+          Object.class);
+
+      /*
+       * If operator is "+=" then coerce both operands to String and concatenate
+       * them. (NEW to EL 3.0)
+       */
+      if ("+=".equals(operator)) {
+        pass = Validator.runConcatenationTest(testValOne, result, testValTwo);
+
+      } else {
+        logger.log(Logger.Level.INFO, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && ExprEval.compareValue((Boolean) result, expectedVal));
+      }
+
+    } catch (RuntimeException re) {
+      ELTestUtil.printStackTrace(re);
+      throw new Exception(re);
+
+    } catch (Exception e) {
+      ELTestUtil.printStackTrace(e);
+      throw new Exception(e);
+
+    } finally {
+      ExprEval.cleanup();
+      logger.log(Logger.Level.INFO, "*** End " + "\"" + "Boolean" + "\"" + " Test Sequence ***");
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+
+  }
+
+  public static void testExpression(ELProcessor elp, String expr,
+      Object expected, String testName) throws Exception {
+    boolean pass = false;
+
+    try {
+      logger.log(Logger.Level.INFO, "*** Start " + testName + " Test Sequence ***");
+      logger.log(Logger.Level.INFO, "expression to be evaluated is " + expr);
+      Object result = elp.eval(expr);
+
+      pass = ExprEval.compareClass(result, expected.getClass())
+          && ExprEval.compareValue(result, expected);
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (RuntimeException re) {
+      ELTestUtil.printStackTrace(re);
+      throw new Exception(re);
+
+    } catch (Exception e) {
+      ELTestUtil.printStackTrace(e);
+      throw new Exception(e);
+
+    } finally {
+      ExprEval.cleanup();
+      logger.log(Logger.Level.INFO, "*** End " + testName + " Test Sequence ***");
+    }
+  }
+
+  // ------------------------- private methods
+
+  private static Boolean runConcatenationTest(Object testVal, Object result,
+      Object testNum) {
+
+    Class<String> returnType = String.class;
+    String expectedResult = testVal.toString() + testNum.toString();
+
+    logger.log(Logger.Level.INFO, "Setting Expected Type: " + returnType.getName());
+
+    return (ExprEval.compareClass(result, returnType)
+        && ExprEval.compareValue(result, expectedResult));
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/signaturetest/ELSigTestIT.java b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/ELSigTestIT.java
new file mode 100644
index 0000000..53a6f56
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/ELSigTestIT.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2007, 2024 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.signaturetest;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.File;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Properties;
+import java.lang.System.Logger;
+
+/*
+ * This class is a simple example of a signature test that extends the
+ * SigTest framework class.  This signature test is run outside of the
+ * EE containers.
+ */
+public class ELSigTestIT extends SigTest {
+
+  private static final Logger logger = System.getLogger(ELSigTestIT.class.getName());
+
+  public ELSigTestIT(){
+    setup();
+  }
+
+  /***** Abstract Method Implementation *****/
+
+  /**
+   * Returns a list of strings where each string represents a package name. Each
+   * package name will have it's signature tested by the signature test
+   * framework.
+   *
+   * @return String[] The names of the packages whose signatures should be
+   *         verified.
+   */
+  protected String[] getPackages() {
+    return new String[] { "jakarta.el" };
+  }
+
+
+  /*
+   * The following comments are specified in the base class that defines the
+   * signature tests. This is done so the test finders will find the right class
+   * to run. The implementation of these methods is inherited from the super
+   * class which is part of the signature test framework.
+   */
+
+  // NOTE: If the API under test is not part of your testing runtime
+  // environment, you may use the property sigTestClasspath to specify
+  // where the API under test lives. This should almost never be used.
+  // Normally the API under test should be specified in the classpath
+  // of the VM running the signature tests. Use either the first
+  // comment or the one below it depending on which properties your
+  // signature tests need. Please do not use both comments.
+
+  /*
+   * @testName: signatureTest
+   *
+   * @assertion: An EL container must implement the required classes and APIs
+   * specified in the EL Specification.
+   *
+   * @test_Strategy: Using reflection, gather the implementation specific
+   * classes and APIs. Compare these results with the expected (required)
+   * classes and APIs.
+   *
+   */
+  @Test
+  public void signatureTest() throws Exception {
+
+    logger.log(Logger.Level.INFO, "$$$ SigTestIT.signatureTest() called");
+    String mapFile = null;
+    String packageFile = null;
+    Properties mapFileAsProps = null;
+    String[] packages = getPackages();
+    String apiPackage = "jakarta.el";
+
+    try {
+
+    InputStream inStreamMapfile = ELSigTestIT.class.getClassLoader().getResourceAsStream("com/sun/ts/tests/signaturetest/el/sig-test.map");
+    File mFile = writeStreamToTempFile(inStreamMapfile, "sig-test", ".map");
+    mapFile = mFile.getCanonicalPath();
+    logger.log(Logger.Level.INFO, "mapFile location is :"+mapFile);
+
+    InputStream inStreamPackageFile = ELSigTestIT.class.getClassLoader().getResourceAsStream("com/sun/ts/tests/signaturetest/el/sig-test-pkg-list.txt");
+    File pFile = writeStreamToTempFile(inStreamPackageFile, "sig-test-pkg-list", ".txt");
+    packageFile = pFile.getCanonicalPath();
+    logger.log(Logger.Level.INFO, "packageFile location is :"+packageFile);
+
+    mapFileAsProps = getSigTestDriver().loadMapFile(mapFile);
+    String packageVersion = mapFileAsProps.getProperty(apiPackage);
+    logger.log(Logger.Level.INFO, "Package version from mapfile :"+packageVersion);
+
+    InputStream inStreamSigFile = ELSigTestIT.class.getClassLoader().getResourceAsStream("com/sun/ts/tests/signaturetest/el/jakarta.el.sig_"+packageVersion);
+    File sigFile = writeStreamToSigFile(inStreamSigFile, apiPackage, packageVersion);
+    logger.log(Logger.Level.INFO, "signature File location is :"+sigFile.getCanonicalPath());
+
+    } catch(IOException ex) {
+        logger.log(Logger.Level.ERROR, "Exception while creating temp files :"+ex);
+    }
+
+    super.signatureTest(mapFile, packageFile, mapFileAsProps, packages);
+  }
+
+
+  /*
+   * Call the parent class's cleanup method.
+   */
+
+  /*
+   * define which sig driver we will use
+   */
+  @Override
+  protected SignatureTestDriver getSigTestDriver() {
+    driver = SignatureTestDriverFactory
+        .getInstance(SignatureTestDriverFactory.SIG_TEST);
+
+    return driver;
+
+  } // END getSigTestDriver
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/signaturetest/PackageList.java b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/PackageList.java
new file mode 100644
index 0000000..6136911
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/PackageList.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2007, 2024 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.signaturetest;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * This class represents a package list file. A package list file is used in
+ * conjunction with a set of signature files to execute API signature tests.
+ * Users specify which set of package APIs are verified. Each package's
+ * signature is verified independently. As such all valid sub-packages must be
+ * excluded while a package's signature is being verified. This allows API check
+ * to determine incompatible additional packages included in a distribution.
+ * <p/>
+ * This class builds a package list file when signatures are recorded and
+ * provides an API to provide valid sub-package lists when signatures are played
+ * back (verified).
+ * <p/>
+ * In record mode, this class reads the existing package list file, if one
+ * exists, and removes the package (as well as sub-packages) that are currently
+ * being recorded. All package names read from the existing package list file
+ * are held in a tree set which sorts the package names and keeps duplicate
+ * package names from ocurring. The user can then instruct this class to write
+ * out the package list file. At this point this class reads the currently
+ * recorded signature file and extracts each package names and adds it to the
+ * tree set. After this step the previous package list file is saved as a backup
+ * and the new package list file is written to disk.
+ * <p/>
+ * In playback mode, this class reads the contents of the package list file and
+ * stores each package name in a tree set. Users can then invoke the
+ * getSubPackages method to retrieve the valid sub-packages for any given
+ * package. This is done by simply examining the package names in the tree set
+ * and returning any package name that starts with the parent package name and a
+ * trailing period character.
+ */
+class PackageList {
+
+  // Any line in the packageFile starting with this character is a comment
+  private static final char COMMENT_CHAR = '#';
+
+  private static final String BACKUP_EXT = ".bak";
+
+  // File containing the list of packages and sub-packages
+  private File packageFile;
+
+  // Signature file where the package signatures were recorded
+  private File sigFile;
+
+  // Name of the package being recorded
+  private String additionalPackageName;
+
+  // Name of packages and sub-packages in the
+  private Set packageNames = new TreeSet();
+
+  /**
+   * Creates an instance of the PackageList class. The PackageList instance
+   * reads the specified package file and populates it's internal state with the
+   * package names found in this file. Users should use this c'tor when playing
+   * back signature files. Users can init the PackageList instance then use the
+   * "String[] getSubPackages(String packageName)" method to get the list of
+   * valid sub-packages for every package who's signature is being verified.
+   *
+   * @param packageFileName
+   *          The name of the file that contains the package list. This file
+   *          contains the names of all the packages that exist across all the
+   *          signature files that makeup this deliverable. This file is used to
+   *          generate a list of valid sub-packages that must be exclued when
+   *          testing theor parent package's signature.
+   *
+   * @throws Exception
+   *           when the packageFileName does not exist.
+   */
+  public PackageList(String packageFileName) throws Exception {
+    packageFile = new File(packageFileName);
+    if (packageFile.exists() && packageFile.isFile()) {
+      extractExistingPackageNames();
+    } else {
+      throw new FileNotFoundException(packageFileName);
+    }
+  }
+
+  /**
+   * Creates an instance of the PackageList class. The PackageList instance
+   * reads the contents of the packageFileName and stores it in it's internal
+   * state. Next, any packages whos name starts with the specified packageName
+   * are removed from the internal package list. This is done because this is
+   * the package being recorded and we need to remove any previously recorded
+   * package names in case any sub-packages have been removed since the last
+   * time the signatures were recorded. Users should use this c'tor when they
+   * are recording signature files never during playback.
+   *
+   * @param packageName
+   *          The name of the package whos signatures are being recorded (along
+   *          with sub-packages).
+   * @param sigFileName
+   *          The name of the file that contains the recored signatures.
+   * @param packageFileName
+   *          The name of the file that contains the package list. This file
+   *          contains the names of all the packages that exist across all the
+   *          signature files that makeup this deliverable. This file is used to
+   *          generate a list of valid sub-packages that must be exclued when
+   *          testing their parent package's signature.
+   *
+   * @throws Exception
+   *           when an error occurs reading the packageFileName or the
+   *           sigFileName does not exist.
+   */
+  public PackageList(String packageName, String sigFileName,
+      String packageFileName) throws Exception {
+    this.additionalPackageName = packageName;
+    sigFile = new File(sigFileName);
+    if (!sigFile.exists() || !sigFile.isFile()) {
+      throw new FileNotFoundException(sigFileName);
+    }
+    packageFile = new File(packageFileName);
+    if (packageFile.exists() && packageFile.isFile()) {
+      extractExistingPackageNames();
+      removeExistingPackage();
+    }
+  }
+
+  /**
+   * Read the package names stored in the package list file. Each package name
+   * found in the package list file is added to the internal tree set.
+   *
+   * @throws Exception
+   *           if there is an error opening or reading the package list file.
+   */
+  private void extractExistingPackageNames() throws Exception {
+    BufferedReader in = new BufferedReader(new FileReader(packageFile));
+    String line;
+    String trimLine;
+    try {
+      while ((line = in.readLine()) != null) {
+        trimLine = line.trim();
+        if (isComment(trimLine) || "".equals(trimLine)) {
+          continue;
+        }
+        packageNames.add(trimLine);
+      }
+    } finally {
+      try {
+        in.close();
+      } catch (Exception e) {
+      }
+    }
+  }
+
+  /**
+   * Returns true if the specified string starts with a comment character as
+   * denoted by the COMMENT_CHAR constant.
+   *
+   * @param line
+   *          Determins of this line is a comment line
+   *
+   * @return boolean True if the specified line is a comment line else false.
+   */
+  private boolean isComment(String line) {
+    if (line == null) {
+      return false;
+    }
+    String theLine = line.trim();
+    if (theLine.length() > 0) {
+      return (theLine.charAt(0) == COMMENT_CHAR);
+    }
+
+    return false;
+  }
+
+  /**
+   * Removes package names from the package list file. The packages that are
+   * removed are the ones currently being recorded. The packages being recorded
+   * is denoted by this.additionalPackageName. This includes any sub-packages of
+   * the additionalPackageName. This step is necessary in the cases where a
+   * sub-package has been removed from a parent package in between signature
+   * recordings.
+   */
+  private void removeExistingPackage() {
+    String delPackage = this.additionalPackageName;
+    String packageName;
+    List delPkgs = new ArrayList();
+    // iterate over package set and find package names to remove
+    for (Iterator i = packageNames.iterator(); i.hasNext();) {
+      packageName = (String) i.next();
+      if (packageName.startsWith(delPackage)) {
+        delPkgs.add(packageName);
+      }
+    }
+    // actually remove the package names from the set
+    for (int i = 0; i < delPkgs.size(); i++) {
+      packageName = (String) (delPkgs.get(i));
+      packageNames.remove(packageName);
+      System.out.println(
+          "PackageList.removeExistingPackage() \"" + packageName + "\"");
+    }
+  }
+
+  /**
+   * Extract the package name from the specified string. The specified string
+   * should have the form: "package jakarta.ejb;"
+   *
+   * @param packageLine
+   *          The string containing the package name.
+   *
+   * @return String The extracted package name.
+   *
+   * @throws Exception
+   *           if the specified string does not conform to the expected format.
+   */
+  private String parsePackageName(String packageLine) throws Exception {
+
+    // sig test framework doesn't have the concept of package entries
+    // as the ApiCheck signature format does.
+    // Instead, we need to parse an entry similar to this:
+    // CLSS public jakarta.some.package.SomeClass
+
+    return packageLine.substring(packageLine.lastIndexOf(' ') + 1,
+        packageLine.lastIndexOf('.'));
+  }
+
+  /**
+   * Reads the package names from the signature file. Each package name that is
+   * read is added to this classes internal tree set.
+   *
+   * @throws Exception
+   *           if there is an error opening or reading the signature file.
+   */
+  private void readPkgsFromSigFile() throws Exception {
+    BufferedReader in = new BufferedReader(new FileReader(sigFile));
+    String line;
+    String trimLine;
+    try {
+      while ((line = in.readLine()) != null) {
+        trimLine = line.trim();
+        if (trimLine.startsWith("CLSS")) {
+          packageNames.add(parsePackageName(trimLine));
+        }
+      }
+    } finally {
+      try {
+        in.close();
+      } catch (Exception e) {
+      }
+    }
+  }
+
+  /**
+   * Removes the existing package list file. The package list file is actually
+   * moved to a backup file if it exists. The old backup is lost.
+   *
+   * @throws Exception
+   *           if there is an error moving the current package list file to a
+   *           backup file.
+   */
+  private void removePkgFile() throws Exception {
+    File backupPkgFile = new File(packageFile.getPath() + BACKUP_EXT);
+    if (backupPkgFile.exists() && backupPkgFile.isFile()) {
+      backupPkgFile.delete();
+    }
+    if (packageFile.isFile() && packageFile.exists()) {
+      File copyPackageFile = new File(packageFile.getPath());
+      copyPackageFile.renameTo(backupPkgFile);
+    }
+  }
+
+  /**
+   * Write a simple header to the package list file to explain what the file is.
+   *
+   * @param out
+   *          The BufferedWriter to dump the header to.
+   *
+   * @throws Exception
+   *           if there is any errors writing the header to the specified
+   *           BufferedWriter.
+   */
+  private void writeHeader(BufferedWriter out) throws Exception {
+    out.write(COMMENT_CHAR);
+    out.write(COMMENT_CHAR);
+    out.newLine();
+    out.write(COMMENT_CHAR + " This file contains a list of all the packages");
+    out.newLine();
+    out.write(COMMENT_CHAR + " contained in the signature files for this");
+    out.newLine();
+    out.write(
+        COMMENT_CHAR + " deliverable.  This file is used to exclude valid");
+    out.newLine();
+    out.write(COMMENT_CHAR + " sub-packages from being verified when their");
+    out.newLine();
+    out.write(COMMENT_CHAR + " parent package's signature is checked.");
+    out.newLine();
+    out.write(COMMENT_CHAR);
+    out.write(COMMENT_CHAR);
+    out.newLine();
+    out.newLine();
+  }
+
+  /**
+   * Write the list of package names out to a package list file.
+   *
+   * @throws Exception
+   *           if there is an error creating and writting the package list file.
+   */
+  private void writePkgFile() throws Exception {
+    BufferedWriter out = null;
+    try {
+      out = new BufferedWriter(new FileWriter(packageFile));
+      writeHeader(out);
+      for (Iterator i = packageNames.iterator(); i.hasNext();) {
+        String packageName = (String) i.next();
+        out.write(packageName);
+        out.newLine();
+        System.out
+            .println("PackageList.writePkgFile() \"" + packageName + "\"");
+      }
+    } finally {
+      if (out != null) {
+        out.close();
+      }
+    }
+  }
+
+  /**
+   * Returns the list of sub-packages that exist in the specified package name.
+   *
+   * @param pkgName
+   *          The name of the package we want the sub-package list for.
+   *
+   * @return String[] The sub-packages that live under the specified parent
+   *         package.
+   */
+  public String[] getSubPackages(String pkgName) {
+    List result = new ArrayList();
+    String subPackageName = pkgName + ".";
+    for (Iterator i = packageNames.iterator(); i.hasNext();) {
+      String packageName = (String) i.next();
+      if (packageName.startsWith(subPackageName)) {
+        result.add(packageName);
+      }
+    }
+    return (String[]) (result.toArray(new String[result.size()]));
+  }
+
+  /**
+   * Returns the list of sub-packages that exist in the specified package name.
+   * The returned string matches the API check format of specifying multiple
+   * packages with a single string. Each package name is separated with the "+"
+   * character.
+   *
+   * @param pkgName
+   *          The name of the package we want the sub-package list for.
+   *
+   * @return String The sub-packages that live under the specified parent
+   *         package.
+   */
+  public String getSubPackagesFormatted(String pkgName) {
+    StringBuffer formattedResult = new StringBuffer();
+    String[] result = getSubPackages(pkgName);
+    for (int i = 0; i < result.length; i++) {
+      formattedResult.append(result[i]);
+      if (i < (result.length - 1)) {
+        formattedResult.append("+");
+      }
+    }
+    return formattedResult.toString();
+  }
+
+} // end class PackageList
diff --git a/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTest.java b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTest.java
new file mode 100644
index 0000000..cc16e41
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTest.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2007, 2024 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.signaturetest;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+import java.lang.System.Logger;
+
+/**
+ * This class should be extended by TCK developers that wish to create a set of
+ * signature tests that run outside of any Java EE container. Developers must
+ * implement the getPackages method to specify which packages are to be tested
+ * by the signature test framework.
+ */
+public abstract class SigTest {
+
+  private static final Logger logger = System.getLogger(SigTest.class.getName());
+
+  protected SignatureTestDriver driver;
+
+  /**
+   * <p>
+   * Returns a {@link SignatureTestDriver} appropriate for the particular TCK
+   * (using API check or the Signature Test Framework).
+   * </p>
+   *
+   * <p>
+   * The default implementation of this method will return a
+   * {@link SignatureTestDriver} that will use API Check. TCK developers can
+   * override this to return the desired {@link SignatureTestDriver} for their
+   * TCK.
+   */
+  protected SignatureTestDriver getSigTestDriver() {
+
+    if (driver == null) {
+      driver = SignatureTestDriverFactory.getInstance(SignatureTestDriverFactory.SIG_TEST);
+    }
+
+    return driver;
+
+  } // END getSigTestDriver
+
+
+  /**
+   * Returns the list of packages that must be tested by the siganture test
+   * framework. TCK developers must implement this method in their signature
+   * test sub-class.
+   *
+   * @return String A list of packages that the developer wishes to test using
+   *         the signature test framework.
+   */
+  protected abstract String[] getPackages();
+
+  /**
+   * Returns an array of individual classes that must be tested by the signature
+   * test framwork. TCK developers may override this method when this
+   * functionality is needed. Most will only need package level granularity.
+   *
+   * @return an Array of Strings containing the individual classes the framework
+   *         should test. The default implementation of this method returns a
+   *         zero-length array.
+   */
+  protected String[] getClasses() {
+
+    return new String[] {};
+
+  } // END getClasses
+
+  protected SigTestData testInfo;
+
+  /**
+   * Called by the test framework to initialize this test. The method simply
+   * retrieves some state information that is necessary to run the test when
+   * when the test framework invokes the run method (actually the test1 method).
+   *
+   * @param args
+   *          List of arguments passed to this test.
+   * @param p
+   *          Properties specified by the test user and passed to this test via
+   *          the test framework.
+   */
+  public void setup() {
+    try {
+      logger.log(Logger.Level.TRACE, "$$$ SigTest.setup() called");
+      this.testInfo = new SigTestData();
+      logger.log(Logger.Level.TRACE, "$$$ SigTest.setup() complete");
+    } catch (Exception e) {
+      logger.log(Logger.Level.ERROR, "Unexpected exception " + e.getMessage());
+    }
+  }
+
+  /**
+   * Called by the test framework to run this test. This method utilizes the
+   * state information set in the setup method to run the signature tests. All
+   * signature test code resides in the utility class so it can be reused by the
+   * signature test framework base classes.
+   *
+   * @throws Exception
+   *           When an error occurs executing the signature tests.
+   */
+  public void signatureTest(String mapFile, String packageFile, Properties mapFileAsProps, String[] packages)
+   throws Exception {
+
+    SigTestResult results = null;
+    String repositoryDir = System.getProperty("java.io.tmpdir");
+    String[] classes = getClasses();
+    String testClasspath = testInfo.getTestClasspath(); 
+
+    // If testing with Java 9+, extract the JDK's modules so they can be used
+    // on the testcase's classpath.
+
+    String jimageDir = testInfo.getJImageDir();
+    File f = new File(jimageDir);
+    f.mkdirs();
+
+    String javaHome = System.getProperty("java.home");
+    logger.log(Logger.Level.INFO, "Executing JImage");
+
+    try {
+      ProcessBuilder pb = new ProcessBuilder(javaHome + "/bin/jimage", "extract", "--dir=" + jimageDir, javaHome + "/lib/modules");
+      logger.log(Logger.Level.INFO, javaHome + "/bin/jimage extract --dir=" + jimageDir + " " + javaHome + "/lib/modules");
+      pb.redirectErrorStream(true);
+      Process proc = pb.start();
+      BufferedReader out = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+      String line = null;
+      while ((line = out.readLine()) != null) {
+        logger.log(Logger.Level.INFO, line);
+      }
+
+      int rc = proc.waitFor();
+      logger.log(Logger.Level.INFO,"JImage RC = " + rc);
+      out.close();
+    } catch (Exception e) {
+      logger.log(Logger.Level.INFO, "Exception while executing JImage!  Some tests may fail.");
+      e.printStackTrace();
+    }
+    
+
+    try {
+      results = getSigTestDriver().executeSigTest(packageFile, mapFile,
+          repositoryDir, packages, classes, testClasspath);
+      logger.log(Logger.Level.INFO,results.toString());
+      if (!results.passed()) {
+        logger.log(Logger.Level.TRACE, "results.passed() returned false");
+        throw new Exception();
+      }
+      logger.log(Logger.Level.TRACE, "$$$ SigTest.test1() returning");
+    } catch (Exception e) {
+      if (results != null && !results.passed()) {
+        throw new Exception("SigTest.test1() failed!, diffs found");
+      } else {
+        logger.log(Logger.Level.ERROR, "Unexpected exception " + e.getMessage());
+        throw new Exception("test failed with an unexpected exception", e);
+      }
+    }
+  }
+
+  public File writeStreamToTempFile(InputStream inputStream, String tempFilePrefix, String tempFileSuffix) throws IOException {
+    FileOutputStream outputStream = null;
+    try {
+        File file = File.createTempFile(tempFilePrefix, tempFileSuffix);
+        file.deleteOnExit();
+        outputStream = new FileOutputStream(file);
+        byte[] buffer = new byte[1024];
+        while (true) {
+            int bytesRead = inputStream.read(buffer);
+            if (bytesRead == -1) {
+                break;
+            }
+            outputStream.write(buffer, 0, bytesRead);
+        }
+        return file;
+    }
+    finally {
+        if (outputStream != null) {
+            outputStream.close();
+        }
+    }
+  }
+
+  public File writeStreamToSigFile(InputStream inputStream, String apiPackage, String packageVersion) throws IOException {
+    FileOutputStream outputStream = null;
+    String tmpdir = System.getProperty("java.io.tmpdir");
+    try {
+        File sigfile = new File(tmpdir+ File.separator + apiPackage + ".sig_"+packageVersion);
+        if(sigfile.exists()){
+          sigfile.delete();
+          logger.log(Logger.Level.INFO, "Existing signature file deleted to create new one");
+        }
+        if(!sigfile.createNewFile()){
+          logger.log(Logger.Level.ERROR, "signature file is not created");
+        }
+        outputStream = new FileOutputStream(sigfile);
+        byte[] buffer = new byte[1024];
+        while (true) {
+            int bytesRead = inputStream.read(buffer);
+            if (bytesRead == -1) {
+                break;
+            }
+            outputStream.write(buffer, 0, bytesRead);
+        }
+        return sigfile;
+    }
+
+    finally {
+        if (outputStream != null) {
+            outputStream.close();
+        }
+    }
+  }
+
+  /**
+   * Called by the test framework to cleanup any outstanding state.
+   *
+   */
+  public void cleanup() {
+    logger.log(Logger.Level.TRACE, "$$$ SigTest.cleanup()");
+  }
+
+} // end class SigTest
diff --git a/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestData.java b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestData.java
new file mode 100644
index 0000000..374f915
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestData.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2024 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.signaturetest;
+
+import java.util.Properties;
+
+/**
+ * This class holds the data passed to a signature test invocation during the
+ * setup phase. This allows us to keep the passed data separate and reuse the
+ * data between the signature test framework base classes.
+ */
+public class SigTestData {
+
+  private Properties props;
+
+  public SigTestData() {
+    this.props = System.getProperties();
+  }
+
+  public String getTestClasspath() {
+    return props.getProperty("sigTestClasspath", "");
+  }
+
+  public String getProperty(String prop) {
+    return props.getProperty(prop);
+  }
+
+  public String getJImageDir() {
+    return props.getProperty("jimage.dir", "");
+  }
+} // end class SigTestData
diff --git a/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestDriver.java b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestDriver.java
new file mode 100644
index 0000000..a4aeedf
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestDriver.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2007, 2024 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.signaturetest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintWriter;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.lang.System.Logger;
+
+
+/**
+ * <p>
+ * Wrapper for the <code>Sig Test</code> framework.
+ * </p>
+ */
+public class SigTestDriver extends SignatureTestDriver {
+
+  private static final Logger logger = System.getLogger(SigTestDriver.class.getName());
+
+  private static final String CLASSPATH_FLAG = "-Classpath";
+
+  private static final String FILENAME_FLAG = "-FileName";
+
+  private static final String PACKAGE_FLAG = "-Package";
+
+  private static final String PACKAGE_NO_SUBS_FLAG = "-PackageWithoutSubpackages";
+
+  private static final String API_VERSION_FLAG = "-ApiVersion";
+
+  private static final String EXCLUDE_FLAG = "-Exclude";
+  
+  private static final String STATIC_FLAG = "-Static";
+
+  private static final String CHECKVALUE_FLAG = "-CheckValue"; // only valid w/
+                                                               // -static
+
+  private static final String NO_CHECKVALUE_FLAG = "-NoCheckValue";
+
+  private static final String SMODE_FLAG = "-mode"; // requires arg of bin or
+                                                    // src
+
+  private static final String DEBUG_FLAG = "-Debug";
+
+  private static final String FORMATPLAIN_FLAG = "-FormatPlain";
+  
+  private static final String EXCLUDE_JDK_CLASS_FLAG = "-IgnoreJDKClass";
+
+  @Override
+  protected String[] createTestArguments(String packageListFile, String mapFile,
+      String signatureRepositoryDir, String packageOrClassUnderTest,
+      String classpath, boolean bStaticMode) throws Exception {
+
+    SignatureFileInfo info = getSigFileInfo(packageOrClassUnderTest, mapFile,
+        signatureRepositoryDir);
+
+    PackageList packageList = new PackageList(packageListFile);
+    String[] subPackages = packageList.getSubPackages(packageOrClassUnderTest);
+
+    List command = new ArrayList();
+
+    if (bStaticMode) {
+      // static mode allows finer level of constants checking
+      // -CheckValue says to check the actual const values
+      logger.log(Logger.Level.TRACE, "Setting static mode flag to allow constant checking.");
+      command.add(STATIC_FLAG);
+      command.add(CHECKVALUE_FLAG);
+
+      // specifying "-mode src" allows stricter 2 way verification of constant
+      // vals
+      // (note that using "-mode bin" mode is less strict)
+      command.add(SMODE_FLAG);
+      // command.add("bin");
+      command.add("src");
+    } else {
+      logger.log(Logger.Level.TRACE, "Not Setting static mode flag to allow constant checking.");
+    }
+
+    // if (TestUtil.harnessDebug) {
+    //   command.add(DEBUG_FLAG);
+    // }
+    command.add("-Verbose");
+
+    command.add(FILENAME_FLAG);
+    command.add(info.getFile());
+
+    command.add(CLASSPATH_FLAG);
+    command.add(classpath);
+
+    command.add(PACKAGE_FLAG);
+    command.add(packageOrClassUnderTest);
+
+    for (int i = 0; i < subPackages.length; i++) {
+      command.add(EXCLUDE_FLAG);
+      command.add(subPackages[i]);
+    }
+
+    command.add(EXCLUDE_JDK_CLASS_FLAG);
+            
+    command.add(API_VERSION_FLAG);
+    command.add(info.getVersion());
+
+    return ((String[]) command.toArray(new String[command.size()]));
+
+  } // END createTestArguments
+
+  @Override
+  protected boolean runSignatureTest(String packageOrClassName,
+      String[] testArguments) throws Exception {
+
+    Class sigTestClass = Class
+        .forName("com.sun.tdk.signaturetest.SignatureTest");
+    Object sigTestInstance = sigTestClass.newInstance();
+
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+    // do some logging to help with troubleshooting
+    logger.log(Logger.Level.TRACE, 
+        "\nCalling:  com.sun.tdk.signaturetest.SignatureTest() with following args:");
+    for (int ii = 0; ii < testArguments.length; ii++) {
+      logger.log(Logger.Level.TRACE, "   testArguments[" + ii + "] = " + testArguments[ii]);
+    }
+
+    @SuppressWarnings("unchecked")
+    Method runMethod = sigTestClass.getDeclaredMethod("run",
+        new Class[] { String[].class, PrintWriter.class, PrintWriter.class });
+    runMethod.invoke(sigTestInstance,
+        new Object[] { testArguments, new PrintWriter(output, true), null });
+
+    String rawMessages = output.toString();
+
+    // currently, there is no way to determine if there are error msgs in
+    // the rawmessages, so we will always dump this and call it a status.
+    logger.log(Logger.Level.INFO, "********** Status Report '" + packageOrClassName + "' **********\n");
+    logger.log(Logger.Level.INFO, rawMessages);    
+
+    return sigTestInstance.toString().substring(7).startsWith("Passed.");
+  } // END runSignatureTest
+
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestResult.java b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestResult.java
new file mode 100644
index 0000000..05a482d
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SigTestResult.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2007, 2024 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.signaturetest;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SigTestResult implements Serializable {
+
+  private static final String NL = System.getProperty("line.separator", "\n");
+
+  private List failedPkgs = new ArrayList();
+
+  private List passedPkgs = new ArrayList();
+
+  private List failedClasses = new ArrayList();
+
+  private List passedClasses = new ArrayList();
+
+  // ---------------------------------------------------------- Public Methods
+
+  public synchronized boolean passed() {
+
+    return (failedPkgs.size() == 0 && failedClasses.size() == 0);
+
+  } // end passed
+
+  public synchronized void addFailedPkg(String pkg) {
+
+    failedPkgs.add(pkg);
+
+  } // END addFailedPkg
+
+  public synchronized void addPassedPkg(String pkg) {
+
+    passedPkgs.add(pkg);
+
+  } // END addPassedPkg
+
+  public synchronized void addFailedClass(String className) {
+
+    failedClasses.add(className);
+
+  } // END addFailedClass
+
+  public synchronized void addPassedClass(String className) {
+
+    passedClasses.add(className);
+
+  } // END addPassedClass
+
+  public String toString() {
+
+    String delim = "******************************************************"
+        + NL;
+    if (!pkgsTested() && !classesTested()) {
+      return (delim + "******** No packages or classes were tested **********"
+          + NL + delim);
+    }
+    StringBuffer buf = new StringBuffer();
+    buf.append(delim);
+    buf.append(delim);
+    if (passed()) {
+      buf.append("All package signatures passed.").append(NL);
+    } else {
+      buf.append("Some signatures failed.").append(NL);
+      if (failedPkgs.size() > 0) {
+        buf.append("\tFailed packages listed below: ").append(NL);
+        formatList(failedPkgs, buf);
+      }
+      if (failedClasses.size() > 0) {
+        buf.append("\tFailed classes listed below: ").append(NL);
+        formatList(failedClasses, buf);
+      }
+    }
+    if (passedPkgs.size() > 0) {
+      buf.append("\tPassed packages listed below: ").append(NL);
+      formatList(passedPkgs, buf);
+    }
+    if (passedClasses.size() > 0) {
+      buf.append("\tPassed classes listed below: ").append(NL);
+      formatList(passedClasses, buf);
+    }
+    buf.append("\t");
+    buf.append(delim);
+    buf.append(delim);
+    return buf.toString();
+
+  } // END toString
+
+  // --------------------------------------------------------- Private Methods
+
+  private synchronized void formatList(List list, StringBuffer buf) {
+
+    synchronized (this) {
+      for (int i = 0; i < list.size(); i++) {
+        String pkg = (String) (list.get(i));
+        buf.append("\t\t").append(pkg).append(NL);
+      }
+    }
+
+  } // END formatList
+
+  private synchronized boolean pkgsTested() {
+
+    return (failedPkgs.size() != 0 || passedPkgs.size() != 0);
+
+  } // END pkgsTested
+
+  private synchronized boolean classesTested() {
+
+    return (failedClasses.size() != 0 || passedClasses.size() != 0);
+
+  } // END classesTested
+
+} // end class SigTestResult
diff --git a/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SignatureTestDriver.java b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SignatureTestDriver.java
new file mode 100644
index 0000000..55603cc
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SignatureTestDriver.java
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 2007, 2024 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.signaturetest;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import java.lang.System.Logger;
+
+/**
+ * Allows the sigtest framework to be extended using different signature test
+ * implementations (e.g. ApiCheck, or SigTest)
+ */
+public abstract class SignatureTestDriver {
+
+  private static final Logger logger = System.getLogger(SignatureTestDriver.class.getName());
+
+  private static final String SIG_FILE_EXT = ".sig";
+
+  private static final String SIG_FILE_VER_SEP = "_";
+
+  // ---------------------------------------------------------- Public Methods
+
+  /**
+   * <p>
+   * Execute the signature test. By default, this method passes the result of
+   * {@link #createTestArguments(String, String, String, String, String)} and
+   * passes the result to {@link #runSignatureTest(String, String[])}.
+   *
+   * @param packageListFile
+   *          - file containing the packages/classes that are to be verified
+   * @param mapFile
+   *          sig-test.map file
+   * @param signatureRepositoryDir
+   *          directory containing the recorded signatures
+   * @param packagesUnderTest
+   *          packages, defined by the test client, that should be tested
+   * @param classesUnderTest
+   *          classes, defined by the test client, that should be tested
+   * @param classpath
+   *          The location of the API being verified. Normally the checked API
+   *          will be available in the test environment and testClasspath will
+   *          be null. In some rare cases the tested API may not be part of the
+   *          test environment and will have to specified using this parameter.
+   *
+   * @return a {@link SigTestResult} containing the result of the test execution
+   */
+  public SigTestResult executeSigTest(String packageListFile, String mapFile,
+      String signatureRepositoryDir, String[] packagesUnderTest,
+      String[] classesUnderTest, String classpath)
+      throws Exception {
+
+    SigTestResult result = new SigTestResult();
+
+    if (packagesUnderTest != null && packagesUnderTest.length > 0) {
+      logger.log(Logger.Level.INFO, "********** BEGIN PACKAGE LEVEL SIGNATURE "
+          + "VALIDATION **********\n\n");
+      for (int i = 0; i < packagesUnderTest.length; i++) {
+
+        String packageName = packagesUnderTest[i];
+
+        logger.log(Logger.Level.INFO, "********** BEGIN VALIDATE PACKAGE '"
+            + packagesUnderTest[i] + "' **********\n");
+
+        logger.log(Logger.Level.INFO, 
+            "********** VALIDATE IN STATIC MODE - TO CHECK CONSANT VALUES ****");
+        logger.log(Logger.Level.INFO, "Static mode supports checks of static constants values ");
+
+        String[] args = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, packageName, classpath, true);
+        dumpTestArguments(args);
+
+        if (runSignatureTest(packageName, args)) {
+          logger.log(Logger.Level.INFO, "********** Package '" + packageName
+              + "' - PASSED (STATIC MODE) **********");
+          result.addPassedPkg(packageName + "(static mode)");
+        } else {
+          result.addFailedPkg(packageName + "(static mode)");
+          logger.log(Logger.Level.INFO, "********** Package '" + packageName
+              + "' - FAILED (STATIC MODE) **********");
+        }
+
+        logger.log(Logger.Level.INFO, "\n\n");
+        logger.log(Logger.Level.INFO, "********** VALIDATE IN REFLECTIVE MODE  ****");
+        logger.log(Logger.Level.INFO, 
+            "Reflective mode supports verification within containers (ie ejb, servlet, etc)");
+
+        String[] args2 = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, packageName, classpath, false);
+        dumpTestArguments(args2);
+
+        if (runSignatureTest(packageName, args2)) {
+          logger.log(Logger.Level.INFO, "********** Package '" + packageName
+              + "' - PASSED (REFLECTION MODE) **********");
+          result.addPassedPkg(packageName + "(reflection mode)");
+        } else {
+          result.addFailedPkg(packageName + "(reflection mode)");
+          logger.log(Logger.Level.INFO, "********** Package '" + packageName
+              + "' - FAILED (REFLECTION MODE) **********");
+        }
+
+        logger.log(Logger.Level.INFO, "********** END VALIDATE PACKAGE '"
+            + packagesUnderTest[i] + "' **********\n");
+
+        logger.log(Logger.Level.INFO, "\n");
+        logger.log(Logger.Level.INFO, "\n");
+
+      }
+    }
+
+    if (classesUnderTest != null && classesUnderTest.length > 0) {
+      logger.log(Logger.Level.INFO, "********** BEGIN CLASS LEVEL SIGNATURE "
+          + "VALIDATION **********\n\n");
+
+      for (int i = 0; i < classesUnderTest.length; i++) {
+
+        String className = classesUnderTest[i];
+
+        logger.log(Logger.Level.INFO, "********** BEGIN VALIDATE CLASS '"
+            + classesUnderTest[i] + "' **********\n");
+
+        logger.log(Logger.Level.INFO, 
+            "********** VALIDATE IN STATIC MODE - TO CHECK CONSANT VALUES ****");
+        logger.log(Logger.Level.INFO, "Static mode supports checks of static constants values ");
+
+        String[] args = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, className, classpath, true);
+        dumpTestArguments(args);
+
+        if (runSignatureTest(className, args)) {
+          logger.log(Logger.Level.INFO, "********** Class '" + className
+              + "' - PASSED (STATIC MODE) **********");
+          result.addPassedClass(className + "(static mode)");
+        } else {
+          logger.log(Logger.Level.INFO, "********** Class '" + className
+              + "' - FAILED (STATIC MODE) **********");
+          result.addFailedClass(className + "(static mode)");
+        }
+
+        logger.log(Logger.Level.INFO, "\n\n");
+        logger.log(Logger.Level.INFO, "********** VALIDATE IN REFLECTIVE MODE  ****");
+        logger.log(Logger.Level.INFO, 
+            "Reflective mode supports verification within containers (ie ejb, servlet, etc)");
+
+        String[] args2 = createTestArguments(packageListFile, mapFile,
+            signatureRepositoryDir, className, classpath, false);
+        dumpTestArguments(args2);
+
+        if (runSignatureTest(className, args2)) {
+          logger.log(Logger.Level.INFO, "********** Class '" + className
+              + "' - PASSED (REFLECTION MODE) **********");
+          result.addPassedClass(className + "(reflection mode)");
+        } else {
+          logger.log(Logger.Level.INFO, "********** Class '" + className
+              + "' - FAILED (REFLECTION MODE) **********");
+          result.addFailedClass(className + "(reflection mode)");
+        }
+
+        logger.log(Logger.Level.INFO, "********** END VALIDATE CLASS '" + classesUnderTest[i]
+            + "' **********\n");
+
+        logger.log(Logger.Level.INFO, "\n");
+        logger.log(Logger.Level.INFO, "\n");
+
+      }
+    }
+
+    return result;
+
+  } // END executeSigTest
+
+  // ------------------------------------------------------- Protected Methods
+
+  /**
+   * Using a common set of information, create arguments that are appropriate to
+   * be used with the underlying signature test framework.
+   *
+   * @param packageListFile
+   *          - file containing the packages/classes that are to be verified
+   * @param mapFile
+   *          sig-test.map file
+   * @param signatureRepositoryDir
+   *          directory containing the recorded signatures
+   * @param packageOrClassUnderTest
+   *          the class or package
+   * @param classpath
+   *          The location of the API being verified. Normally the checked API
+   *          will be available in the test environment and testClasspath will
+   *          be null. In some rare cases the tested API may not be part of the
+   *          test environment and will have to specified using this parameter.
+   */
+  protected abstract String[] createTestArguments(String packageListFile,
+      String mapFile, String signatureRepositoryDir,
+      String packageOrClassUnderTest, String classpath, boolean bStaticMode)
+      throws Exception;
+
+  /**
+   * Invoke the underlying signature test framework for the specified package or
+   * class.
+   *
+   * @param packageOrClassName
+   *          the package or class to be validated
+   * @param testArguments
+   *          the arguments necessary to invoke the signature test framework
+   *
+   * @return <code>true</code> if the test passed, otherwise <code>false</code>
+   */
+  protected abstract boolean runSignatureTest(String packageOrClassName,
+      String[] testArguments) throws Exception;
+
+
+  /**
+   * Loads the specified file into a Properties object provided the specified
+   * file exists and is a regular file. The call to new FileInputStream verifies
+   * that the specfied file is a regular file and exists.
+   *
+   * @param mapFile
+   *          the path and name of the map file to be loaded
+   *
+   * @return Properties The Properties object initialized with the contents of
+   *         the specified file
+   *
+   * @throws java.io.IOException
+   *           If the specified map file does not exist or is not a regular
+   *           file, can also be thrown if there is an error creating an input
+   *           stream from the specified file.
+   */
+  public Properties loadMapFile(String mapFile)
+      throws IOException, FileNotFoundException {
+
+    FileInputStream in = null;
+    try {
+      File map = new File(mapFile);
+      Properties props = new Properties();
+      in = new FileInputStream(map);
+      props.load(in);
+      return props;
+    } finally {
+      try {
+        if (in != null) {
+          in.close();
+        }
+      } catch (Throwable t) {
+        // do nothing
+      }
+    }
+
+  } // END loadMapFile
+
+  /**
+   * This method will attempt to build a fully-qualified filename in the format
+   * of <code>respositoryDir</code> + </code>baseName</code> +
+   * <code>.sig_</code> + </code>version</code>.
+   *
+   * @param baseName
+   *          the base portion of the signature filename
+   * @param repositoryDir
+   *          the directory in which the signatures are stored
+   * @param version
+   *          the version of the signature file
+   * @throws FileNotFoundException
+   *           if the file cannot be validated as existing and is in fact a file
+   * @return a valid, fully qualified filename, appropriate for the system the
+   *         test is being run on
+   */
+  protected String getSigFileName(String baseName, String repositoryDir,
+      String version) throws FileNotFoundException {
+
+    String sigFile;
+    if (repositoryDir.endsWith(File.separator)) {
+      sigFile = repositoryDir + baseName + SIG_FILE_EXT + SIG_FILE_VER_SEP
+          + version;
+    } else {
+      sigFile = repositoryDir + File.separator + baseName + SIG_FILE_EXT
+          + SIG_FILE_VER_SEP + version;
+    }
+
+    File testFile = new File(sigFile);
+
+    if (!testFile.exists() && !testFile.isFile()) {
+      throw new FileNotFoundException(
+          "Signature file \"" + sigFile + "\" does not exist.");
+    }
+
+    // we are actually requiring this normalizeFileName call to get
+    // things working on Windows. Without this, if we just return the
+    // testFile; we will fail on windows. (Solaris works either way)
+    // IMPORTANT UPDATE!! (4/5/2011)
+    // in sigtest 2.2: they stopped supporting the normalized version which
+    // created a string filename =
+    // "file://com/sun/ts/tests/signaturetest/foo.sig"
+    // so now use file path and name only.
+    // return normalizeFileName(testFile);
+    return testFile.toString();
+
+  } // END getSigFileName
+
+
+  /**
+   * Returns the name and path to the signature file that contains the specified
+   * package's signatures.
+   *
+   * @param packageName
+   *          The package under test
+   * @param mapFile
+   *          The name of the file that maps package names to versions
+   * @param repositoryDir
+   *          The directory that conatisn all signature files
+   *
+   * @return String The path and name of the siganture file that contains the
+   *         specified package's signatures
+   *
+   * @throws Exception
+   *           if the determined signature file is not a regular file or does
+   *           not exist
+   */
+  protected SignatureFileInfo getSigFileInfo(String packageName, String mapFile,
+      String repositoryDir) throws Exception {
+
+    String originalPackage = packageName;
+    String name = null;
+    String version = null;
+    Properties props = loadMapFile(mapFile);
+
+    while (true) {
+      boolean packageFound = false;
+      for (Enumeration<?> e = props.propertyNames(); e.hasMoreElements();) {
+        name = (String) (e.nextElement());
+        if (name.equals(packageName)) {
+          version = props.getProperty(name);
+          packageFound = true;
+          break;
+        } // end if
+      } // end for
+
+      if (packageFound) {
+        break;
+      }
+
+      /*
+       * If we get here we did not find a package name in the properties file
+       * that matches the package name under test. So we look for a package name
+       * in the properties file that could be the parent package for the package
+       * under test. We do this by removing the specified packages last package
+       * name section. So jakarta.ejb.spi would become jakarta.ejb
+       */
+      int index = packageName.lastIndexOf(".");
+      if (index <= 0) {
+        throw new Exception("Package \"" + originalPackage
+            + "\" not specified in mapping file \"" + mapFile + "\".");
+      }
+      packageName = packageName.substring(0, index);
+    } // end while
+
+    /* Return the expected name of the signature file */
+
+    return new SignatureFileInfo(getSigFileName(name, repositoryDir, version),
+        version);
+
+  } // END getSigFileInfo
+
+  // --------------------------------------------------------- Private Methods
+
+  /**
+   * Prints the specified list of parameters to the message log. Used for
+   * debugging purposes only.
+   *
+   * @param params
+   *          The list of parameters to dump.
+   */
+  private static void dumpTestArguments(String[] params) {
+
+    if (params != null && params.length > 0) {
+      logger.log(Logger.Level.TRACE, "----------------- BEGIN SIG PARAM DUMP -----------------");
+      for (int i = 0; i < params.length; i++) {
+        logger.log(Logger.Level.TRACE, "   Param[" + i + "]: " + params[i]);
+      }
+      logger.log(Logger.Level.TRACE, "------------------ END SIG PARAM DUMP ------------------");
+    }
+
+  } // END dumpTestArguments
+
+  // ----------------------------------------------------------- Inner Classes
+
+  /**
+   * A simple data structure containing the fully qualified path to the
+   * signature file as well as the version being tested.
+   */
+  protected static class SignatureFileInfo {
+
+    private String file;
+
+    private String version;
+
+    // -------------------------------------------------------- Constructors
+
+    public SignatureFileInfo(String file, String version) {
+
+      if (file == null) {
+        throw new IllegalArgumentException("'file' argument cannot be null");
+      }
+
+      if (version == null) {
+        throw new IllegalArgumentException("'version' argument cannot be null");
+      }
+
+      this.file = file;
+      this.version = version;
+
+    } // END SignatureFileInfo
+
+    // ------------------------------------------------------ Public Methods
+
+    public String getFile() {
+
+      return file;
+
+    } // END getFileIncludingPath
+
+    public String getVersion() {
+
+      return version;
+
+    } // END getVersion
+
+  }
+
+} // END SigTestDriver
diff --git a/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SignatureTestDriverFactory.java b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SignatureTestDriverFactory.java
new file mode 100644
index 0000000..0a781e2
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/signaturetest/SignatureTestDriverFactory.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 2024 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package com.sun.ts.tests.el.signaturetest;
+
+/**
+ * <p>
+ * Factory to obtain SignatureTestDriver implementations.
+ * </p>
+ */
+public class SignatureTestDriverFactory {
+
+  /**
+   * <p>
+   * Identifier for the driver that uses the Signature Test framwork for
+   * signature validation.
+   * </p>
+   */
+  public static final String SIG_TEST = "sigtest";
+
+  // ------------------------------------------------------------ Constructors
+
+  // Access via factory method
+  private SignatureTestDriverFactory() {
+  } // END SignatureTestDriverFactory
+
+  // ---------------------------------------------------------- Public Methods
+
+  /**
+   * <p>
+   * Obtain a {@link SignatureTestDriver} instance based on the
+   * <code>type</code> argument.
+   *
+   * @param type
+   *          the driver type to create
+   * @return a {@link SignatureTestDriver} implementation
+   */
+  public static SignatureTestDriver getInstance(String type) {
+
+    if (type == null || type.length() == 0) {
+      throw new IllegalArgumentException("Type was null or empty");
+    }
+
+    if (SIG_TEST.equals(type)) {
+      return new SigTestDriver();
+    } else {
+      throw new IllegalArgumentException("Unknown Type: '" + type + '\'');
+    }
+
+  } // END getInstance
+
+} // END SignatureTestDriverFactory
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/assignmentoperator/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/assignmentoperator/ELClientIT.java
new file mode 100644
index 0000000..1b0287c
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/assignmentoperator/ELClientIT.java
@@ -0,0 +1,947 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.assignmentoperator;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.TypesBean;
+import com.sun.ts.tests.el.common.util.Validator;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+import jakarta.el.ELProcessor;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /**
+   * @testName: elAssignmentOperatorBigDecimalTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - BigDecimal
+   * 
+   *                 Variable B - Rotating through the following types:
+   *                 BigDecimal, BigInteger, Integer, Float, Long, Short,
+   *                 Double, Byte
+   * 
+   *                 Excluded: none
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorBigDecimalTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "BigDecimal";
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String aValue = "a = types.tckBigDecimal";
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      elp.eval(aValue);
+      elp.eval(bValue);
+
+      // (+ operator)
+      Validator.testExpression(elp, "a + b", BigDecimal.valueOf(2),
+          comparitorA + " + " + bName);
+
+      // (* operator)
+      Validator.testExpression(elp, "a * b", BigDecimal.valueOf(1),
+          comparitorA + " * " + bName);
+
+      // (- operator)
+      Validator.testExpression(elp, "a - b", BigDecimal.valueOf(0),
+          comparitorA + " - " + bName);
+
+      // (/ operator)
+      Validator.testExpression(elp, "a / b", BigDecimal.valueOf(1),
+          comparitorA + " / " + bName);
+
+      // (div operator)
+      Validator.testExpression(elp, "a div b", BigDecimal.valueOf(1),
+          comparitorA + " div " + bName);
+
+      // (% operator)
+      Validator.testExpression(elp, "a % b", Double.valueOf(0),
+          comparitorA + " % " + bName);
+
+      // (mod operator)
+      Validator.testExpression(elp, "a mod b", Double.valueOf(0),
+          comparitorA + " mod " + bName);
+
+      // Clean variables...
+      elp.eval("a = null");
+      elp.eval("b = null");
+    }
+
+  } // End elAssignmentOperatorBigDecimalTest
+
+  /**
+   * @testName: elAssignmentOperatorFloatTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - Float
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorFloatTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Float";
+    String aValue = "a = types.tckFloat";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if (excludeList.contains(bName)) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+
+        elp.eval(aValue);
+        elp.eval(bValue);
+
+        if ("BigInteger".equals(bName)) {
+          // (+ operator)
+          Validator.testExpression(elp, "a + b", BigDecimal.valueOf(2),
+              comparitorA + " + " + bName);
+
+          // (* operator)
+          Validator.testExpression(elp, "a * b", BigDecimal.valueOf(1),
+              comparitorA + " * " + bName);
+
+          // (- operator)
+          Validator.testExpression(elp, "a - b", BigDecimal.valueOf(0),
+              comparitorA + " - " + bName);
+
+          // (/ operator)
+          Validator.testExpression(elp, "a / b", BigDecimal.valueOf(1),
+              comparitorA + " / " + bName);
+
+          // (div operator)
+          Validator.testExpression(elp, "a div b", BigDecimal.valueOf(1),
+              comparitorA + " div " + bName);
+
+        } else {
+          // (+ operator)
+          Validator.testExpression(elp, "a + b", Double.valueOf(2),
+              comparitorA + " + " + bName);
+
+          // (* operator)
+          Validator.testExpression(elp, "a * b", Double.valueOf(1),
+              comparitorA + " * " + bName);
+
+          // (- operator)
+          Validator.testExpression(elp, "a - b", Double.valueOf(0),
+              comparitorA + " - " + bName);
+
+          // (/ operator)
+          Validator.testExpression(elp, "a / b", Double.valueOf(1),
+              comparitorA + " / " + bName);
+
+          // (div operator)
+          Validator.testExpression(elp, "a div b", Double.valueOf(1),
+              comparitorA + " div " + bName);
+
+        }
+
+        // The same for all other tested data types.
+
+        // (% operator)
+        Validator.testExpression(elp, "a % b", Double.valueOf(0),
+            comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a mod b", Double.valueOf(0),
+            comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elAssignmentOperatorFloatTest
+
+  /**
+   * @testName: elAssignmentOperatorDoubleTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - Double
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, Float
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorDoubleTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Double";
+    String aValue = "a = types.tckDouble";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if (excludeList.contains(bName)) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+
+        elp.eval(aValue);
+        elp.eval(bValue);
+
+        if ("BigInteger".equals(bName)) {
+          // (+ operator)
+          Validator.testExpression(elp, "a + b", BigDecimal.valueOf(2),
+              comparitorA + " + " + bName);
+
+          // (* operator)
+          Validator.testExpression(elp, "a * b", BigDecimal.valueOf(1),
+              comparitorA + " * " + bName);
+
+          // (- operator)
+          Validator.testExpression(elp, "a - b", BigDecimal.valueOf(0),
+              comparitorA + " - " + bName);
+
+          // (/ operator)
+          Validator.testExpression(elp, "a / b", BigDecimal.valueOf(1),
+              comparitorA + " / " + bName);
+
+          // (div operator)
+          Validator.testExpression(elp, "a div b", BigDecimal.valueOf(1),
+              comparitorA + " div " + bName);
+
+        } else {
+          // (+ operator)
+          Validator.testExpression(elp, "a + b", Double.valueOf(2),
+              comparitorA + " + " + bName);
+
+          // (* operator)
+          Validator.testExpression(elp, "a * b", Double.valueOf(1),
+              comparitorA + " * " + bName);
+
+          // (- operator)
+          Validator.testExpression(elp, "a - b", Double.valueOf(0),
+              comparitorA + " - " + bName);
+
+          // (/ operator)
+          Validator.testExpression(elp, "a / b", Double.valueOf(1),
+              comparitorA + " / " + bName);
+
+          // (div operator)
+          Validator.testExpression(elp, "a div b", Double.valueOf(1),
+              comparitorA + " div " + bName);
+
+        }
+
+        // The same for all other tested data types.
+
+        // (% operator)
+        Validator.testExpression(elp, "a % b", Double.valueOf(0),
+            comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a mod b", Double.valueOf(0),
+            comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elAssignmentOperatorDoubleTest
+
+  /**
+   * @testName: elAssignmentOperatorBigIntegerTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - BigInteger
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, Float, Double
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorBigIntegerTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "BigInteger";
+    String aValue = "a = types.tckBigInteger";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+
+        elp.eval(aValue);
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a + b", BigInteger.valueOf(2),
+            comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a * b", BigInteger.valueOf(1),
+            comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a - b", BigInteger.valueOf(0),
+            comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a / b", BigDecimal.valueOf(1),
+            comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a div b", BigDecimal.valueOf(1),
+            comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a % b", BigInteger.valueOf(0),
+            comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a mod b", BigInteger.valueOf(0),
+            comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elAssignmentOperatorBigIntegerTest
+
+  /**
+   * @testName: elAssignmentOperatorIntegerTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - Integer
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorIntegerTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Integer";
+    String aValue = "a = types.tckInteger";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+
+        elp.eval(aValue);
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a + b", Long.valueOf(2),
+            comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a * b", Long.valueOf(1),
+            comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a - b", Long.valueOf(0),
+            comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a / b", Double.valueOf(1),
+            comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a div b", Double.valueOf(1),
+            comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a % b", Long.valueOf(0),
+            comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a mod b", Long.valueOf(0),
+            comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elAssignmentOperatorIntegerTest
+
+  /**
+   * @testName: elAssignmentOperatorLongTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - Long
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorLongTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Long";
+    String aValue = "a = types.tckLong";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+
+        elp.eval(aValue);
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a + b", Long.valueOf(2),
+            comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a * b", Long.valueOf(1),
+            comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a - b", Long.valueOf(0),
+            comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a / b", Double.valueOf(1),
+            comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a div b", Double.valueOf(1),
+            comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a % b", Long.valueOf(0),
+            comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a mod b", Long.valueOf(0),
+            comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elAssignmentOperatorLongTest
+
+  /**
+   * @testName: elAssignmentOperatorShortTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - Short
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer,
+   *                 Long
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorShortTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Short";
+    String aValue = "a = types.tckShort";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+    excludeList.add("Long");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+
+        elp.eval(aValue);
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a + b", Long.valueOf(2),
+            comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a * b", Long.valueOf(1),
+            comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a - b", Long.valueOf(0),
+            comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a / b", Double.valueOf(1),
+            comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a div b", Double.valueOf(1),
+            comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a % b", Long.valueOf(0),
+            comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a mod b", Long.valueOf(0),
+            comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elAssignmentOperatorShortTest
+
+  /**
+   * @testName: elAssignmentOperatorByteTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - Byte
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer,
+   *                 Long, Short
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorByteTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Byte";
+    String aValue = "a = types.tckByte";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+    excludeList.add("Long");
+    excludeList.add("Short");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+
+        elp.eval(aValue);
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a + b", Long.valueOf(2),
+            comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a * b", Long.valueOf(1),
+            comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a - b", Long.valueOf(0),
+            comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a / b", Double.valueOf(1),
+            comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a div b", Double.valueOf(1),
+            comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a % b", Long.valueOf(0),
+            comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a mod b", Long.valueOf(0),
+            comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elAssignmentOperatorByteTest
+
+  /**
+   * @testName: elAssignmentOperatorNullTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - null
+   * 
+   *                 Variable B - null
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorNullTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    elp.defineBean("types", new TypesBean());
+
+    Long expected = Long.valueOf(0);
+    String aValue = "a = types.tckNull";
+    String bValue = "b = types.tckNull";
+
+    elp.eval(aValue);
+    elp.eval(bValue);
+
+    // (+ operator)
+    Validator.testExpression(elp, "a + b", expected, "null + null");
+
+    // (- operator)
+    Validator.testExpression(elp, "a - b", expected, "null - null");
+
+    // (* operator)
+    Validator.testExpression(elp, "a * b", expected, "null * null");
+
+    // (/ operator)
+    Validator.testExpression(elp, "a / b", expected, "null / null");
+
+    // (div operator)
+    Validator.testExpression(elp, "a div b", expected, "null div null");
+
+    // (% operator)
+    Validator.testExpression(elp, "a % b", expected, "null % null");
+
+    // (mod operator)
+    Validator.testExpression(elp, "a mod b", expected, "null mod null");
+
+  } // End elAssignmentOperatorNullTest
+
+  /**
+   * @testName: elAssignmentOperatorMultiTest
+   * @assertion_ids: EL:SPEC:48.1.1; EL:SPEC:48.1.2; EL:SPEC:48.1.3;
+   *                 EL:SPEC:48.1.4
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Variable A - BigDecimal
+   * 
+   *                 Variable B - Rotating through the following types:
+   *                 BigDecimal, BigInteger, Integer, Float, Long, Short,
+   *                 Double, Byte
+   * 
+   *                 Excluded: none
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elAssignmentOperatorMultiTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "BigDecimal";
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bName = bType.getSimpleName();
+
+      String aValue = "a = types.tckBigDecimal";
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String cValue = "c = types.tckBigDecimal";
+
+      elp.eval(aValue);
+      elp.eval(bValue);
+      elp.eval(cValue);
+
+      // (+ operator)
+      Validator.testExpression(elp, "a + b + c", BigDecimal.valueOf(3),
+          comparitorA + " + " + bName);
+
+      // (* operator)
+      Validator.testExpression(elp, "a * b + c", BigDecimal.valueOf(2),
+          comparitorA + " * " + bName);
+
+      // (- operator)
+      Validator.testExpression(elp, "a - b + c", BigDecimal.valueOf(1),
+          comparitorA + " - " + bName);
+
+      // (/ operator)
+      Validator.testExpression(elp, "a / b + c", BigDecimal.valueOf(2),
+          comparitorA + " / " + bName);
+
+      // (div operator)
+      Validator.testExpression(elp, "a div b + c", BigDecimal.valueOf(2),
+          comparitorA + " div " + bName);
+
+      // (% operator)
+      Validator.testExpression(elp, "a % b + c", BigDecimal.valueOf(1),
+          comparitorA + " % " + bName);
+
+      // (mod operator)
+      Validator.testExpression(elp, "a mod b + c", BigDecimal.valueOf(1),
+          comparitorA + " mod " + bName);
+
+      // Clean variables...
+      elp.eval("a = null");
+      elp.eval("b = null");
+    }
+
+  } // End elAssignmentOperatorMultiTest
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/binaryoperator/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/binaryoperator/ELClientIT.java
new file mode 100644
index 0000000..ad7660d
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/binaryoperator/ELClientIT.java
@@ -0,0 +1,1177 @@
+/*
+ * Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.binaryoperator;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ExprEval;
+import com.sun.ts.tests.el.common.util.TestNum;
+import com.sun.ts.tests.el.common.util.Validator;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /**
+   * @testName: elNullOperandAddTest
+   * @assertion_ids: EL:SPEC:17.1
+   * @test_Strategy: Validate that if both of the operands in an EL "+"
+   *                 (addition) operation are null, the result is (Long) 0.
+   */
+  @Test
+  public void elNullOperandAddTest() throws Exception {
+
+    boolean pass = false;
+
+    Long expectedResult = Long.valueOf("0");
+    try {
+      String expr = ExprEval.buildElExpr(true, "+");
+      logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+
+      Object result = ExprEval.evaluateValueExpression(expr, null,
+          Object.class);
+      logger.log(Logger.Level.TRACE, "result is " + result.toString());
+      pass = (ExprEval.compareClass(result, Long.class)
+          && ExprEval.compareValue((Long) result, expectedResult, 0));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elNullOperandSubtractTest
+   * @assertion_ids: EL:SPEC:17.1
+   * @test_Strategy: Validate that if both of the operands in an EL "-"
+   *                 (subtraction) operation are null, the result is (Long) 0.
+   */
+  @Test
+  public void elNullOperandSubtractTest() throws Exception {
+
+    boolean pass = false;
+
+    Long expectedResult = Long.valueOf("0");
+    try {
+      String expr = ExprEval.buildElExpr(false, "-");
+      logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+
+      Object result = ExprEval.evaluateValueExpression(expr, null,
+          Object.class);
+      logger.log(Logger.Level.TRACE, "result is " + result.toString());
+      pass = (ExprEval.compareClass(result, Long.class)
+          && ExprEval.compareValue((Long) result, expectedResult, 0));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elNullOperandMultiplyTest
+   * @assertion_ids: EL:SPEC:17.1
+   * @test_Strategy: Validate that if both of the operands in an EL "*"
+   *                 (multiplication) operation are null, the result is (Long)
+   *                 0.
+   */
+  @Test
+  public void elNullOperandMultiplyTest() throws Exception {
+
+    boolean pass = false;
+
+    Long expectedResult = Long.valueOf("0");
+    try {
+      String expr = ExprEval.buildElExpr(true, "*");
+      logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+
+      Object result = ExprEval.evaluateValueExpression(expr, null,
+          Object.class);
+      logger.log(Logger.Level.TRACE, "result is " + result.toString());
+      pass = (ExprEval.compareClass(result, Long.class)
+          && ExprEval.compareValue((Long) result, expectedResult, 0));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elNullOperandDivisionTest
+   * @assertion_ids: EL:SPEC:18.1
+   * @test_Strategy: Validate that if both of the operands in an EL "/"
+   *                 (division) operation are null, the result is (Long) 0.
+   * 
+   */
+  @Test
+  public void elNullOperandDivisionTest() throws Exception {
+
+    boolean pass = false;
+    Long expectedResult = Long.valueOf("0");
+
+    try {
+      String expr = ExprEval.buildElExpr(true, "/");
+      logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+
+      Object result = ExprEval.evaluateValueExpression(expr, null,
+          Object.class);
+      logger.log(Logger.Level.TRACE, "result is " + result.toString());
+      pass = (ExprEval.compareClass(result, Long.class)
+          && ExprEval.compareValue((Long) result, expectedResult, 0));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elNullOperandModulusTest
+   * @assertion_ids: EL:SPEC:19.1
+   * @test_Strategy: Validate that if both of the operands in an EL "%" (mod)
+   *                 operation are null, the result is (Long) 0.
+   * 
+   */
+  @Test
+  public void elNullOperandModulusTest() throws Exception {
+
+    boolean pass = false;
+
+    Long expectedResult = Long.valueOf("0");
+    try {
+      String expr = ExprEval.buildElExpr(true, "%");
+      logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+
+      Object result = ExprEval.evaluateValueExpression(expr, null,
+          Object.class);
+      logger.log(Logger.Level.TRACE, "result is " + result.toString());
+      pass = (ExprEval.compareClass(result, Long.class)
+          && ExprEval.compareValue((Long) result, expectedResult, 0));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elBigDecimalAddTest
+   * @assertion_ids: EL:SPEC:17.2.1
+   * @test_Strategy: Validate that if one of the operands in an EL "+"
+   *                 (addition) operation is a BigDecimal, the result is coerced
+   *                 to BigDecimal and is the sum of the operands.
+   * 
+   *                 Equations tested: BigDecimal + BigDecimal BigDecimal +
+   *                 Double BigDecimal + Float BigDecimal + String containing
+   *                 ".", "e", or "E" BigDecimal + BigInteger BigDecimal +
+   *                 Integer BigDecimal + Long BigDecimal + Short BigDecimal +
+   *                 Byte
+   */
+  @Test
+  public void elBigDecimalAddTest() throws Exception {
+
+    BigDecimal testValue = BigDecimal.valueOf(10.531);
+    BigDecimal expectedResult = BigDecimal.valueOf(11.531);
+
+    Validator.testBigDecimal(testValue, expectedResult, "+");
+
+  }
+
+  /**
+   * @testName: elBigDecimalSubtractTest
+   * @assertion_ids: EL:SPEC:17.2.2
+   * @test_Strategy: Validate that if one of the operands in an EL "-"
+   *                 (subtraction) operation is a BigDecimal, the result is
+   *                 coerced to BigDecimal and is the difference of the
+   *                 operands.
+   * 
+   *                 Equations tested: BigDecimal - BigDecimal BigDecimal -
+   *                 Double BigDecimal - Float BigDecimal - String containing
+   *                 ".", "e", or "E" BigDecimal - BigInteger BigDecimal -
+   *                 Integer BigDecimal - Long BigDecimal - Short BigDecimal -
+   *                 Byte
+   */
+  @Test
+  public void elBigDecimalSubtractTest() throws Exception {
+
+    BigDecimal testValue = BigDecimal.valueOf(10.531);
+    BigDecimal expectedResult = BigDecimal.valueOf(9.531);
+
+    Validator.testBigDecimal(testValue, expectedResult, "-");
+
+  }
+
+  /**
+   * @testName: elBigDecimalMultiplyTest
+   * @assertion_ids: EL:SPEC:17.2.3
+   * @test_Strategy: Validate that if one of the operands in an EL "*"
+   *                 (multiplication) operation is a BigDecimal, the result is
+   *                 coerced to BigDecimal and is the product of the operands.
+   * 
+   *                 Equations tested: BigDecimal * BigDecimal BigDecimal *
+   *                 Double BigDecimal * Float BigDecimal * String containing
+   *                 ".", "e", or "E" BigDecimal * BigInteger BigDecimal *
+   *                 Integer BigDecimal * Long BigDecimal * Short BigDecimal *
+   *                 Byte
+   */
+  @Test
+  public void elBigDecimalMultiplyTest() throws Exception {
+
+    BigDecimal testValue = BigDecimal.valueOf(1.5);
+    BigDecimal expectedResult = BigDecimal.valueOf(1.5);
+
+    Validator.testBigDecimal(testValue, expectedResult, "*");
+
+  }
+
+  /**
+   * @testName: elBigDecimalDivisionTest
+   * @assertion_ids: EL:SPEC:18.2
+   * @test_Strategy: Validate that if one of the operands in an EL "/" (div)
+   *                 operation is a BigDecimal, the result is coerced to
+   *                 BigDecimal and is the quotient of the operands.
+   * 
+   *                 Equations tested: BigDecimal / BigDecimal BigDecimal /
+   *                 Double BigDecimal / Float BigDecimal / String containing
+   *                 ".", "e", or "E" BigDecimal / BigInteger BigDecimal /
+   *                 Integer BigDecimal / Long BigDecimal / Short BigDecimal /
+   *                 Byte
+   */
+  @Test
+  public void elBigDecimalDivisionTest() throws Exception {
+
+    BigDecimal testValue = BigDecimal.valueOf(3.0);
+    BigDecimal expectedResult = BigDecimal.valueOf(3.0);
+
+    Validator.testBigDecimal(testValue, expectedResult, "/");
+
+  }
+
+  /**
+   * @testName: elBigDecimalModulusTest
+   * @assertion_ids: EL:SPEC:19.2
+   * @test_Strategy: Validate that if one of the operands in an EL "%" (mod)
+   *                 operation is a BigDecimal, the result is coerced to Double
+   *                 and is the remainder of the quotient of the operands.
+   * 
+   *                 Equations tested: BigDecimal % BigDecimal BigDecimal %
+   *                 Double BigDecimal % Float BigDecimal % String containing
+   *                 ".", "e", or "E" BigDecimal % BigInteger BigDecimal %
+   *                 Integer BigDecimal % Long BigDecimal % Short BigDecimal %
+   *                 Byte
+   */
+  @Test
+  public void elBigDecimalModulusTest() throws Exception {
+
+    BigDecimal testValue = BigDecimal.valueOf(2.5);
+    BigDecimal expectedResult = BigDecimal.valueOf(0.5);
+
+    Validator.testBigDecimal(testValue, expectedResult, "%");
+
+  }
+
+  /**
+   * @testName: elBigIntegerAddTest
+   * @assertion_ids: EL:SPEC:17.4.1
+   * @test_Strategy: Validate that if one of the operands in an EL "+"
+   *                 (addition) operation is a BigInteger, the result is coerced
+   *                 to BigInteger and is the sum of the operands.
+   * 
+   *                 Equations tested: BigInteger + BigInteger BigInteger +
+   *                 Integer BigInteger + Long BigInteger + Short BigInteger +
+   *                 Byte
+   */
+  @Test
+  public void elBigIntegerAddTest() throws Exception {
+
+    BigInteger testValue = BigInteger.valueOf(10531);
+    BigInteger expectedResult = BigInteger.valueOf(10532);
+
+    Validator.testBigInteger(testValue, expectedResult, "+");
+
+  }
+
+  /**
+   * @testName: elBigIntegerSubtractTest
+   * @assertion_ids: EL:SPEC:17.4.2
+   * @test_Strategy: Validate that if one of the operands in an EL "-"
+   *                 (subtraction) operation is a BigInteger, the result is
+   *                 coerced to BigInteger and is the difference of the
+   *                 operands.
+   * 
+   *                 Equations tested: BigInteger - BigInteger BigInteger -
+   *                 Integer BigInteger - Long BigInteger - Short BigInteger -
+   *                 Byte
+   */
+  @Test
+  public void elBigIntegerSubtractTest() throws Exception {
+
+    BigInteger testValue = BigInteger.valueOf(10531);
+    BigInteger expectedResult = BigInteger.valueOf(10530);
+
+    Validator.testBigInteger(testValue, expectedResult, "-");
+
+  }
+
+  /**
+   * @testName: elBigIntegerMultiplyTest
+   * @assertion_ids: EL:SPEC:17.4.3
+   * @test_Strategy: Validate that if one of the operands in an EL "*" operation
+   *                 is a BigInteger, the result is coerced to BigInteger and is
+   *                 the product of the operands.
+   * 
+   *                 BigInteger * BigInteger BigInteger * Integer BigInteger *
+   *                 Long BigInteger * Short BigInteger * Byte
+   */
+  @Test
+  public void elBigIntegerMultiplyTest() throws Exception {
+
+    BigInteger testValue = BigInteger.valueOf(10531);
+    BigInteger expectedResult = BigInteger.valueOf(10531);
+
+    Validator.testBigInteger(testValue, expectedResult, "*");
+
+  }
+
+  /**
+   * @testName: elBigIntegerDivisionTest
+   * @assertion_ids: EL:SPEC:18.2
+   * @test_Strategy: Validate that if one of the operands in an EL "/" (div)
+   *                 operation is a BigInteger, the result is coerced to
+   *                 BigDecimal and is the quotient of the operands.
+   * 
+   *                 BigInteger / BigInteger BigInteger / Integer BigInteger /
+   *                 Long BigInteger / Short BigInteger / Byte
+   */
+  @Test
+  public void elBigIntegerDivisionTest() throws Exception {
+
+    BigInteger testValue = BigInteger.valueOf(10531);
+    BigInteger expectedResult = BigInteger.valueOf(10531);
+
+    Validator.testBigInteger(testValue, expectedResult, "/");
+
+  }
+
+  /**
+   * @testName: elBigIntegerModulusTest
+   * @assertion_ids: EL:SPEC:19.3
+   * @test_Strategy: Validate that if one of the operands in an EL "%" (mod)
+   *                 operation is a BigInteger, the result is coerced to
+   *                 BigInteger and is the remainder of the quotient of the
+   *                 operands.
+   * 
+   *                 BigInteger % BigInteger BigInteger % Integer BigInteger %
+   *                 Long BigInteger % Short BigInteger % Byte
+   */
+  @Test
+  public void elBigIntegerModulusTest() throws Exception {
+
+    BigInteger testValue = BigInteger.valueOf(10531);
+    BigInteger expectedResult = BigInteger.valueOf(0);
+
+    Validator.testBigInteger(testValue, expectedResult, "%");
+
+  }
+
+  /**
+   * @testName: elFloatAddTest
+   * @assertion_ids: EL:SPEC:17.3.1; EL:SPEC:17.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "+"
+   *                 (addition) operation is a Float, the result is coerced to
+   *                 Double and is the sum of the operands.
+   * 
+   *                 Equations tested: Float + Double Float + Float Float +
+   *                 String containing ".", "e", or "E" Float + BigInteger Float
+   *                 + Integer Float + Long Float + Short Float + Byte
+   */
+  @Test
+  public void elFloatAddTest() throws Exception {
+
+    Float expectedResult;
+    // For each float in validate List.
+    for (Iterator<?> it = TestNum.getFloatList().iterator(); it.hasNext();) {
+      Float testValue = (Float) it.next();
+      expectedResult = testValue + Float.valueOf("1.0");
+      Validator.testFloat(testValue, expectedResult, "+");
+    }
+
+  }
+
+  /**
+   * @testName: elFloatSubtractTest
+   * @assertion_ids: EL:SPEC:17.3.1; EL:SPEC:17.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "-"
+   *                 (subtraction) operation is a Float, the result is coerced
+   *                 to Double and is the difference of the operands.
+   * 
+   *                 Equations tested: Float - Double Float - Float Float -
+   *                 String containing ".", "e", or "E" Float - BigInteger Float
+   *                 - Integer Float - Long Float - Short Float - Byte
+   */
+  @Test
+  public void elFloatSubtractTest() throws Exception {
+
+    Float expectedResult;
+    // For each float in validate List.
+    for (Iterator<?> it = TestNum.getFloatList().iterator(); it.hasNext();) {
+      Float testValue = (Float) it.next();
+      expectedResult = testValue - Float.valueOf("1.0");
+      Validator.testFloat(testValue, expectedResult, "-");
+    }
+
+  }
+
+  /**
+   * @testName: elFloatMultiplyTest
+   * @assertion_ids: EL:SPEC:17.3.1; EL:SPEC:17.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "*"
+   *                 (multiplication) operation is a Float, the result is
+   *                 coerced to Double and is the product of the operands.
+   * 
+   *                 Equations tested: Float * Double Float * Float Float *
+   *                 String containing ".", "e", or "E" Float * BigInteger Float
+   *                 * Integer Float * Long Float * Short Float * Byte
+   */
+  @Test
+  public void elFloatMultiplyTest() throws Exception {
+
+    Float expectedResult;
+    // For each float in validate List.
+    for (Iterator<?> it = TestNum.getFloatList().iterator(); it.hasNext();) {
+      Float testValue = (Float) it.next();
+      expectedResult = testValue * Float.valueOf("1.0");
+      Validator.testFloat(testValue, expectedResult, "*");
+    }
+
+  }
+
+  /**
+   * @testName: elFloatDivisionTest
+   * @assertion_ids: EL:SPEC:18.2; EL:SPEC:18.3
+   * @test_Strategy: Validate that if one of the operands in an EL "/" (div)
+   *                 operation is a Float, the result is coerced to Double and
+   *                 is the quotient of the operands.
+   * 
+   *                 Equations tested: Float / Double Float / Float Float /
+   *                 String containing ".", "e", or "E" Float / BigInteger Float
+   *                 / Integer Float / Long Float / Short Float / Byte
+   */
+  @Test
+  public void elFloatDivisionTest() throws Exception {
+
+    Float expectedResult;
+    // For each float in validate List.
+    for (Iterator<?> it = TestNum.getFloatList().iterator(); it.hasNext();) {
+      Float testValue = (Float) it.next();
+      expectedResult = testValue / Float.valueOf("1.0");
+      Validator.testFloat(testValue, expectedResult, "/");
+    }
+
+  }
+
+  /**
+   * @testName: elFloatModulusTest
+   * @assertion_ids: EL:SPEC:19.2
+   * @test_Strategy: Validate that if one of the operands in an EL "%" (mod)
+   *                 operation is a Float, the result is coerced to Double and
+   *                 is the remainder of the quotient of the operands.
+   * 
+   *                 Equations tested: Float % Double Float % Float Float %
+   *                 String containing ".", "e", or "E" Float % BigInteger Float
+   *                 % Integer Float % Long Float % Short Float % Byte
+   */
+  @Test
+  public void elFloatModulusTest() throws Exception {
+
+    Float expectedResult;
+    // For each float in validate List.
+    for (Iterator<?> it = TestNum.getFloatList().iterator(); it.hasNext();) {
+      Float testValue = (Float) it.next();
+      expectedResult = testValue % Float.valueOf("1.0");
+      Validator.testFloat(testValue, expectedResult, "%");
+    }
+
+  }
+
+  /**
+   * @testName: elDoubleAddTest
+   * @assertion_ids: EL:SPEC:17.3.1; EL:SPEC:17.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "+"
+   *                 (addition) operation is a Double, the result is coerced to
+   *                 Double and is the sum of the operands.
+   * 
+   *                 Equations tested: Double + Double Double + String
+   *                 containing ".", "e", or "E" Double + BigInteger Double +
+   *                 Integer Double + Long Double + Short Double + Byte
+   */
+  @Test
+  public void elDoubleAddTest() throws Exception {
+
+    Double testValue = Double.valueOf(2.5);
+    Double expectedResult = Double.valueOf(3.5);
+
+    Validator.testDouble(testValue, expectedResult, "+");
+
+  }
+
+  /**
+   * @testName: elDoubleSubtractTest
+   * @assertion_ids: EL:SPEC:17.3.1; EL:SPEC:17.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "-"
+   *                 (subtraction) operation is a Double, the result is coerced
+   *                 to Double and is the difference of the operands.
+   * 
+   *                 Equations tested: Double - Double Double - String
+   *                 containing ".", "e", or "E" Double - BigInteger Double -
+   *                 Integer Double - Long Double - Short Double - Byte
+   */
+  @Test
+  public void elDoubleSubtractTest() throws Exception {
+
+    Double testValue = Double.valueOf(2.5);
+    Double expectedResult = Double.valueOf(1.5);
+
+    Validator.testDouble(testValue, expectedResult, "-");
+
+  }
+
+  /**
+   * @testName: elDoubleMultiplyTest
+   * @assertion_ids: EL:SPEC:17.3.1; EL:SPEC:17.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "*"
+   *                 (multiplication) operation is a Double, the result is
+   *                 coerced to Double and is the product of the operands.
+   * 
+   *                 Equations tested: Double * Double Double * String
+   *                 containing ".", "e", or "E" Double * BigInteger Double *
+   *                 Integer Double * Long Double * Short Double * Byte
+   */
+  @Test
+  public void elDoubleMultiplyTest() throws Exception {
+
+    Double testValue = Double.valueOf(2.5);
+    Double expectedResult = Double.valueOf(2.5);
+
+    Validator.testDouble(testValue, expectedResult, "*");
+
+  }
+
+  /**
+   * @testName: elDoubleDivisionTest
+   * @assertion_ids: EL:SPEC:18.2; EL:SPEC:18.3
+   * @test_Strategy: Validate that if one of the operands in an EL "/" (div)
+   *                 operation is a Double, the result is coerced to Double and
+   *                 is the quotient of the operands.
+   * 
+   *                 Equations tested: Double / Double Double / String
+   *                 containing ".", "e", or "E" Double / BigInteger Double /
+   *                 Integer Double / Long Double / Short Double / Byte
+   */
+  @Test
+  public void elDoubleDivisionTest() throws Exception {
+
+    Double testValue = Double.valueOf(2.5);
+    Double expectedResult = Double.valueOf(2.5);
+
+    Validator.testDouble(testValue, expectedResult, "/");
+
+  }
+
+  /**
+   * @testName: elDoubleModulusTest
+   * @assertion_ids: EL:SPEC:19.2
+   * @test_Strategy: Validate that if one of the operands in an EL "%" (mod)
+   *                 operation is a Double, the result is coerced to Double and
+   *                 is the remainder of the quotient of the operands.
+   * 
+   *                 Equations tested: Double % Double Double % String
+   *                 containing ".", "e", or "E" Double % BigInteger Double %
+   *                 Integer Double % Long Double % Short Double % Byte
+   */
+  @Test
+  public void elDoubleModulusTest() throws Exception {
+
+    Double testValue = Double.valueOf(2.5);
+    Double expectedResult = Double.valueOf(0.5);
+
+    Validator.testDouble(testValue, expectedResult, "%");
+  }
+
+  /**
+   * @testName: elNumericStringSubtractTest
+   * @assertion_ids: EL:SPEC:17.3.1; EL:SPEC:17.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "-"
+   *                 (subtraction) operation is a numeric string, the result is
+   *                 coerced to Double and is the difference of the operands.
+   * 
+   *                 Equations tested: Numeric String - String containing ".",
+   *                 "e", or "E" Numeric String - BigInteger Numeric String -
+   *                 Integer Numeric String - Long Numeric String - Short
+   *                 Numeric String - Byte
+   */
+  @Test
+  public void elNumericStringSubtractTest() throws Exception {
+
+    String testValue = "25e-1";
+    Double expectedResult = Double.valueOf(1.5);
+
+    Validator.testNumericString(testValue, expectedResult, "-");
+
+  }
+
+  /**
+   * @testName: elNumericStringMultiplyTest
+   * @assertion_ids: EL:SPEC:17.3.1; EL:SPEC:17.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "*"
+   *                 (multiplication) operation is a numeric string, the result
+   *                 is coerced to Double and is the product of the operands.
+   * 
+   *                 Equations tested: Numeric String * String containing ".",
+   *                 "e", or "E" Numeric String * BigInteger Numeric String *
+   *                 Integer Numeric String * Long Numeric String * Short
+   *                 Numeric String * Byte
+   */
+  @Test
+  public void elNumericStringMultiplyTest() throws Exception {
+
+    String testValue = "25E-1";
+    Double expectedResult = Double.valueOf(2.5);
+
+    Validator.testNumericString(testValue, expectedResult, "*");
+
+  }
+
+  /**
+   * @testName: elNumericStringDivisionTest
+   * @assertion_ids: EL:SPEC:18.2; EL:SPEC:18.3
+   * @test_Strategy: Validate that if one of the operands in an EL "/" (div)
+   *                 operation is a numeric string, the result is coerced to
+   *                 Double and is the quotient of the operands.
+   * 
+   *                 Equations tested: Numeric String / String containing ".",
+   *                 "e", or "E" Numeric String / BigInteger Numeric String /
+   *                 Integer Numeric String / Long Numeric String / Short
+   *                 Numeric String / Byte
+   */
+  @Test
+  public void elNumericStringDivisionTest() throws Exception {
+
+    String testValue = "2.5";
+    Double expectedResult = Double.valueOf(2.5);
+
+    Validator.testNumericString(testValue, expectedResult, "/");
+
+  }
+
+  /**
+   * @testName: elNumericStringModulusTest
+   * @assertion_ids: EL:SPEC:19.2
+   * @test_Strategy: Validate that if one of the operands in an EL "%" (mod)
+   *                 operation is a numeric string, the result is coerced to
+   *                 Double and is the remainder of the quotient of the
+   *                 operands.
+   * 
+   *                 Equations tested: Numeric String % String containing ".",
+   *                 "e", or "E" Numeric String % BigInteger Numeric String %
+   *                 Integer Numeric String % Long Numeric String % Short
+   *                 Numeric String % Byte
+   */
+  @Test
+  public void elNumericStringModulusTest() throws Exception {
+
+    String testValue = "2.5e0";
+    Double expectedResult = Double.valueOf(0.5);
+
+    Validator.testNumericString(testValue, expectedResult, "%");
+
+  }
+
+  /**
+   * @testName: elLongAddTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "+"
+   *                 (addition) operation is a Long, the result is coerced to
+   *                 Long and is the sum of the operands.
+   * 
+   *                 Equations tested: Long + Integer Long + Long Long + Short
+   *                 Long + Byte
+   */
+  @Test
+  public void elLongAddTest() throws Exception {
+
+    Long testValue = Long.valueOf(25000);
+    Long expectedResult = Long.valueOf(25001);
+
+    Validator.testLong(testValue, expectedResult, "+");
+
+  }
+
+  /**
+   * @testName: elLongSubtractTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "-"
+   *                 (subtraction) operation is a Long, the result is coerced to
+   *                 Long and is the difference of the operands.
+   * 
+   *                 Equations tested: Long - Integer Long - Long Long - Short
+   *                 Long - Byte
+   */
+  @Test
+  public void elLongSubtractTest() throws Exception {
+
+    Long testValue = Long.valueOf(25000);
+    Long expectedResult = Long.valueOf(24999);
+
+    Validator.testLong(testValue, expectedResult, "-");
+
+  }
+
+  /**
+   * @testName: elLongMultiplyTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "*"
+   *                 (multiplication) operation is a Long, the result is coerced
+   *                 to Long and is the product of the operands.
+   * 
+   *                 Equations tested: Long * Integer Long * Long Long * Short
+   *                 Long * Byte
+   */
+  @Test
+  public void elLongMultiplyTest() throws Exception {
+
+    Long testValue = Long.valueOf(25000);
+    Long expectedResult = Long.valueOf(25000);
+
+    Validator.testLong(testValue, expectedResult, "*");
+
+  }
+
+  /**
+   * @testName: elLongDivisionTest
+   * @assertion_ids: EL:SPEC:18.3
+   * @test_Strategy: Validate that if one of the operands in an EL "/" (div)
+   *                 operation is a Long, the result is coerced to Double and is
+   *                 the quotient of the operands.
+   * 
+   *                 Equations tested: Long / Integer Long / Long Long / Short
+   *                 Long / Byte
+   */
+  @Test
+  public void elLongDivisionTest() throws Exception {
+
+    Long testValue = Long.valueOf(25000);
+    Long expectedResult = Long.valueOf(25000);
+
+    Validator.testLong(testValue, expectedResult, "/");
+
+  }
+
+  /**
+   * @testName: elLongModulusTest
+   * @assertion_ids: EL:SPEC:19.4
+   * @test_Strategy: Validate that if one of the operands in an EL "%" (mod)
+   *                 operation is a Long, the result is coerced to Long and is
+   *                 the remainder of the quotient of the operands.
+   * 
+   *                 Equations tested: Long % Integer Long % Long Long % Short
+   *                 Long % Byte
+   */
+  @Test
+  public void elLongModulusTest() throws Exception {
+
+    Long testValue = Long.valueOf(25000);
+    Long expectedResult = Long.valueOf(0);
+
+    Validator.testLong(testValue, expectedResult, "%");
+
+  }
+
+  /**
+   * @testName: elIntegerAddTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "+"
+   *                 (addition) operation is a Integer, the result is coerced to
+   *                 Long and is the sum of the operands.
+   * 
+   *                 Equations tested: Integer + Integer Integer + Short Integer
+   *                 + Byte
+   */
+  @Test
+  public void elIntegerAddTest() throws Exception {
+
+    Integer testValue = Integer.valueOf(25);
+    Integer expectedResult = Integer.valueOf(26);
+
+    Validator.testInteger(testValue, expectedResult, "+");
+
+  }
+
+  /**
+   * @testName: elIntegerSubtractTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "-"
+   *                 (subtraction) operation is a Integer, the result is coerced
+   *                 to Long and is the difference of the operands.
+   * 
+   *                 Equations tested: Long - Integer Long - Short Long - Byte
+   */
+  @Test
+  public void elIntegerSubtractTest() throws Exception {
+
+    Integer testValue = Integer.valueOf(25);
+    Integer expectedResult = Integer.valueOf(24);
+
+    Validator.testInteger(testValue, expectedResult, "-");
+
+  }
+
+  /**
+   * @testName: elIntegerMultiplyTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "*"
+   *                 (multiplication) operation is a Integer, the result is
+   *                 coerced to Long and is the product of the operands.
+   * 
+   *                 Equations tested: Integer * Integer Integer * Short Integer
+   *                 * Byte
+   */
+  @Test
+  public void elIntegerMultiplyTest() throws Exception {
+
+    Integer testValue = Integer.valueOf(25);
+    Integer expectedResult = Integer.valueOf(25);
+
+    Validator.testInteger(testValue, expectedResult, "*");
+
+  }
+
+  /**
+   * @testName: elIntegerDivisionTest
+   * @assertion_ids: EL:SPEC:18.3
+   * @test_Strategy: Validate that if one of the operands in an EL "/" (div)
+   *                 operation is a Integer, the result is coerced to Double and
+   *                 is the quotient of the operands.
+   * 
+   *                 Equations tested: Integer / Integer Integer / Short Integer
+   *                 / Byte
+   */
+  @Test
+  public void elIntegerDivisionTest() throws Exception {
+
+    Integer testValue = Integer.valueOf(25);
+    Integer expectedResult = Integer.valueOf(25);
+
+    Validator.testInteger(testValue, expectedResult, "/");
+
+  }
+
+  /**
+   * @testName: elIntegerModulusTest
+   * @assertion_ids: EL:SPEC:19.4
+   * @test_Strategy: Validate that if one of the operands in an EL "%" (mod)
+   *                 operation is a Integer, the result is coerced to Long and
+   *                 is the remainder of the quotient of the operands.
+   * 
+   *                 Equations tested: Integer % Integer Integer % Short Integer
+   *                 % Byte
+   */
+  @Test
+  public void elIntegerModulusTest() throws Exception {
+
+    Integer testValue = Integer.valueOf(25);
+    Integer expectedResult = Integer.valueOf(0);
+
+    Validator.testInteger(testValue, expectedResult, "%");
+
+  }
+
+  /**
+   * @testName: elShortAddTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "+"
+   *                 (addition) operation is a Short, the result is coerced to
+   *                 Long and is the sum of the operands.
+   * 
+   *                 Equations tested: Short + Short Short + Byte
+   */
+  @Test
+  public void elShortAddTest() throws Exception {
+
+    Short testValue = Short.valueOf("2");
+    Short expectedResult = Short.valueOf("3");
+
+    Validator.testShort(testValue, expectedResult, "+");
+
+  }
+
+  /**
+   * @testName: elShortSubtractTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "-"
+   *                 (subtraction) operation is a Short, the result is coerced
+   *                 to Long and is the difference of the operands.
+   * 
+   *                 Equations tested: Short - Short Short - Byte
+   */
+  @Test
+  public void elShortSubtractTest() throws Exception {
+
+    Short testValue = Short.valueOf("2");
+    Short expectedResult = Short.valueOf("1");
+
+    Validator.testShort(testValue, expectedResult, "-");
+
+  }
+
+  /**
+   * @testName: elShortMultiplyTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if one of the operands in an EL "*"
+   *                 (multiplication) operation is a Short, the result is
+   *                 coerced to Long and is the product of the operands.
+   * 
+   *                 Equations tested: Short * Short Short * Byte
+   */
+  @Test
+  public void elShortMultiplyTest() throws Exception {
+
+    Short testValue = Short.valueOf("2");
+    Short expectedResult = Short.valueOf("2");
+
+    Validator.testShort(testValue, expectedResult, "*");
+
+  }
+
+  /**
+   * @testName: elShortDivisionTest
+   * @assertion_ids: EL:SPEC:18.3
+   * @test_Strategy: Validate that if one of the operands in an EL "/" (div)
+   *                 operation is a Short, the result is coerced to Double and
+   *                 is the quotient of the operands.
+   * 
+   *                 Equations tested: Short / Short Short / Byte
+   */
+  @Test
+  public void elShortDivisionTest() throws Exception {
+
+    Short testValue = Short.valueOf("2");
+    Short expectedResult = Short.valueOf("2");
+
+    Validator.testShort(testValue, expectedResult, "/");
+
+  }
+
+  /**
+   * @testName: elShortModulusTest
+   * @assertion_ids: EL:SPEC:19.4
+   * @test_Strategy: Validate that if one of the operands in an EL "%" (mod)
+   *                 operation is a Short, the result is coerced to Long and is
+   *                 the remainder of the quotient of the operands.
+   * 
+   *                 Equations tested: Short % Short Short % Byte
+   */
+  @Test
+  public void elShortModulusTest() throws Exception {
+
+    Short testValue = Short.valueOf("2");
+    Short expectedResult = Short.valueOf("0");
+
+    Validator.testShort(testValue, expectedResult, "%");
+
+  }
+
+  /**
+   * @testName: elByteAddTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if both operands in an EL "+" (addition)
+   *                 operation are Bytes, the result is coerced to Long and is
+   *                 the sum of the operands.
+   * 
+   *                 Equations tested: Byte + Byte
+   */
+  @Test
+  public void elByteAddTest() throws Exception {
+
+    Byte testValue = Byte.valueOf("2");
+    Byte expectedResult = Byte.valueOf("3");
+
+    Validator.testByte(testValue, expectedResult, "+");
+
+  }
+
+  /**
+   * @testName: elByteSubtractTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if both operands in an EL "-" (subtraction)
+   *                 operation are Bytes, the result is coerced to Long and is
+   *                 the difference of the operands.
+   * 
+   *                 Equations tested: Byte - Byte
+   */
+  @Test
+  public void elByteSubtractTest() throws Exception {
+
+    Byte testValue = Byte.valueOf("2");
+    Byte expectedResult = Byte.valueOf("1");
+
+    Validator.testByte(testValue, expectedResult, "-");
+
+  }
+
+  /**
+   * @testName: elByteMultiplyTest
+   * @assertion_ids: EL:SPEC:17.5
+   * @test_Strategy: Validate that if both operands in an EL "*"
+   *                 (multiplication) operation are Bytes, the result is coerced
+   *                 to Long and is the product of the operands.
+   * 
+   *                 Equations tested: Byte * Byte
+   */
+  @Test
+  public void elByteMultiplyTest() throws Exception {
+
+    Byte testValue = Byte.valueOf("2");
+    Byte expectedResult = Byte.valueOf("2");
+
+    Validator.testByte(testValue, expectedResult, "*");
+
+  }
+
+  /**
+   * @testName: elByteDivisionTest
+   * @assertion_ids: EL:SPEC:18.3
+   * @test_Strategy: Validate that if both operands in an EL "/" (div) operation
+   *                 are Bytes, the result is coerced to Double and is the
+   *                 quotient of the operands.
+   * 
+   *                 Equations tested: Byte / Byte
+   */
+  @Test
+  public void elByteDivisionTest() throws Exception {
+
+    Byte testValue = Byte.valueOf("2");
+    Byte expectedResult = Byte.valueOf("2");
+
+    Validator.testByte(testValue, expectedResult, "/");
+
+  }
+
+  /**
+   * @testName: elByteModulusTest
+   * @assertion_ids: EL:SPEC:19.4
+   * @test_Strategy: Validate that if both operands in an EL "%" (mod) operation
+   *                 are Bytes, the result is coerced to Long and is the
+   *                 remainder of the quotient of the operands.
+   * 
+   *                 Equations tested: Byte % Byte
+   */
+  @Test
+  public void elByteModulusTest() throws Exception {
+
+    Byte testValue = Byte.valueOf("2");
+    Byte expectedResult = Byte.valueOf("0");
+
+    Validator.testByte(testValue, expectedResult, "%");
+
+  }
+
+  /**
+   * @testName: elBooleanAndTest
+   * @assertion_ids: EL:SPEC:23.1; EL:SPEC:24.2.1
+   * @test_Strategy: Validate that if one of the operands in an EL "&&", "and"
+   *                 operation is a Boolean, the result is coerced to Boolean.
+   * 
+   *                 Equations tested: Boolean && String Boolean && Boolean
+   *                 Boolean and String Boolean and Boolean
+   * 
+   */
+  @Test
+  public void elBooleanAndTest() throws Exception {
+
+    Validator.testBoolean(true, "true", true, "&&");
+    Validator.testBoolean(true, true, true, "&&");
+
+    Validator.testBoolean(true, "false", false, "and");
+    Validator.testBoolean(true, false, false, "and");
+
+  }
+
+  /**
+   * @testName: elBooleanOrTest
+   * @assertion_ids: EL:SPEC:23.1; EL:SPEC:24.2.1
+   * @test_Strategy: Validate that if one of the operands in an EL "||", "or"
+   *                 operation is a Boolean, the result is coerced to Boolean.
+   * 
+   *                 Equations tested: Boolean || String Boolean || Boolean
+   *                 Boolean or String Boolean or Boolean
+   * 
+   */
+  @Test
+  public void elBooleanOrTest() throws Exception {
+
+    Validator.testBoolean(false, "false", false, "||");
+    Validator.testBoolean(true, "false", true, "or");
+
+    Validator.testBoolean(true, false, true, "||");
+    Validator.testBoolean(true, true, true, "or");
+
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/coercion/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/coercion/ELClientIT.java
new file mode 100644
index 0000000..f5f5ee3
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/coercion/ELClientIT.java
@@ -0,0 +1,1945 @@
+/*
+ * Copyright (c) 2009, 2024 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/**
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.coercion;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Time;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.function.Predicate;
+
+
+import com.sun.ts.tests.el.common.util.ExprEval;
+import com.sun.ts.tests.el.common.util.NameValuePair;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELException;
+import jakarta.el.ELProcessor;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private static final String NLINE = System.getProperty("line.separator",
+      "\n");
+
+  private static final String BYTE = "30";
+
+  private static final String SHORT = "32";
+
+  private static final String INTEGER = "33";
+
+  private static final String LONG = "34";
+
+  // NOTE: The elStringToNumberCoercionTest assumes a non-numeric
+  // ending character for Float and Double types
+  private static final String FLOAT = "35.5f";
+
+  private static final String DOUBLE = "36.5d";
+
+  private static final String BIGINT = "125";
+
+  private static final String BIGDEC = "100.5";
+
+  private static enum greeting {
+    hello, goodbye
+  };
+
+  private Hashtable numberTable;
+
+  private enum planets {
+    MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE
+    /** ,PLUTO */
+  };
+
+  public ELClientIT(){
+    initializeNumberTable();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: positivePrimitiveToBoxedTest
+   * @assertion_ids: EL:SPEC:37.3; EL:SPEC:37.5
+   * @test_Strategy: Validate that the primitive types - boolean - char - byte -
+   *                 short - int - long - float - double when found in an
+   *                 expression are converted to the appropriate 'boxed' types.
+   */
+  @Test
+  public void positivePrimitiveToBoxedTest() throws Exception {
+
+    boolean fail = false;
+    boolean[] pass = { false, false, false, false, false, false, false, false };
+    Object result = null;
+
+    try {
+      result = ExprEval.evaluateValueExpression("${true}", null, Boolean.class);
+      pass[0] = ExprEval.compareClass(result, Boolean.class)
+          && ExprEval.compareValue(result, Boolean.TRUE);
+
+      result = ExprEval.evaluateValueExpression("#{'x'}", null,
+          Character.class);
+      pass[1] = ExprEval.compareClass(result, Character.class)
+          && ExprEval.compareValue(result, Character.valueOf('x'));
+
+      result = ExprEval.evaluateValueExpression("${2}", null, Byte.class);
+      pass[2] = ExprEval.compareClass(result, Byte.class)
+          && ExprEval.compareValue(result, Byte.valueOf("2"));
+
+      result = ExprEval.evaluateValueExpression("#{20}", null, Short.class);
+      pass[3] = ExprEval.compareClass(result, Short.class)
+          && ExprEval.compareValue(result, Short.valueOf("20"));
+
+      result = ExprEval.evaluateValueExpression("${2000}", null, Integer.class);
+      pass[4] = ExprEval.compareClass(result, Integer.class)
+          && ExprEval.compareValue(result, Integer.valueOf(2000));
+
+      result = ExprEval.evaluateValueExpression("#{2000}", null, Long.class);
+      pass[5] = ExprEval.compareClass(result, Long.class)
+          && ExprEval.compareValue(result, Long.valueOf(2000L));
+
+      result = ExprEval.evaluateValueExpression("${2e+3}", null, Float.class);
+      pass[6] = ExprEval.compareClass(result, Float.class)
+          && ExprEval.compareValue(result, Float.valueOf(2000f));
+
+      result = ExprEval.evaluateValueExpression("#{2000.00}", null,
+          Double.class);
+      pass[7] = ExprEval.compareClass(result, Double.class)
+          && ExprEval.compareValue(result, Double.valueOf(2000));
+
+    } catch (RuntimeException re) {
+      throw new Exception(re);
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    for (int i = 0; i < pass.length; ++i) {
+      if (!pass[i]) {
+        fail = true;
+        logger.log(Logger.Level.ERROR, "Unexpected result for test case " + i);
+      }
+    }
+
+    if (fail)
+      throw new Exception("TEST FAILED");
+  }
+
+  /**
+   * @testName: positiveBoxedToPrimitiveTest
+   * @assertion_ids: EL:SPEC:37.3; EL:SPEC:37.4
+   * @test_Strategy: Validate that the 'boxed' types - Boolean - Character -
+   *                 Byte - Short - Integer - Long - Float - Double when found
+   *                 in an expression are converted to the appropriate primitive
+   *                 types. Note that the conversion takes place in
+   *                 ExprEval.evaluateValueExpression() when
+   *                 ExpressionFactory.createValueExpression() is called. When
+   *                 ValueExpression.getValue() is subsequently called, the
+   *                 primitive type is converted back to its 'boxed' type.
+   */
+  @Test
+  public void positiveBoxedToPrimitiveTest() throws Exception {
+
+    boolean fail = false;
+    boolean[] pass = { false, false, false, false, false, false, false, false };
+    Object result = null;
+
+    String immExpr = "${A}";
+    String defExpr = "#{A}";
+
+    Boolean boolVal = Boolean.FALSE;
+    NameValuePair[] boolNV = NameValuePair.buildUnaryNameValue(boolVal);
+
+    Character charVal = Character.valueOf('x');
+    NameValuePair[] charNV = NameValuePair.buildUnaryNameValue(charVal);
+
+    Byte byteVal = Byte.valueOf("2");
+    NameValuePair[] byteNV = NameValuePair.buildUnaryNameValue(byteVal);
+
+    Short shortVal = Short.valueOf("20");
+    NameValuePair[] shortNV = NameValuePair.buildUnaryNameValue(shortVal);
+
+    Integer intVal = Integer.valueOf(2000);
+    NameValuePair[] intNV = NameValuePair.buildUnaryNameValue(intVal);
+
+    Long longVal = Long.valueOf(2000);
+    NameValuePair[] longNV = NameValuePair.buildUnaryNameValue(longVal);
+
+    Float floatVal = Float.valueOf("2e+3");
+    NameValuePair[] floatNV = NameValuePair.buildUnaryNameValue(floatVal);
+
+    Double doubleVal = Double.valueOf(2000.0);
+    NameValuePair[] doubleNV = NameValuePair.buildUnaryNameValue(doubleVal);
+
+    try {
+      result = ExprEval.evaluateValueExpression(defExpr, boolNV, boolean.class);
+      pass[0] = ExprEval.compareClass(result, Boolean.class)
+          && ExprEval.compareValue(result, boolVal);
+
+      result = ExprEval.evaluateValueExpression(immExpr, charNV, char.class);
+      pass[1] = ExprEval.compareClass(result, Character.class)
+          && ExprEval.compareValue(result, charVal);
+
+      result = ExprEval.evaluateValueExpression(defExpr, byteNV, byte.class);
+      pass[2] = ExprEval.compareClass(result, Byte.class)
+          && ExprEval.compareValue(result, byteVal);
+
+      result = ExprEval.evaluateValueExpression(immExpr, shortNV, short.class);
+      pass[3] = ExprEval.compareClass(result, Short.class)
+          && ExprEval.compareValue(result, shortVal);
+
+      result = ExprEval.evaluateValueExpression(defExpr, intNV, int.class);
+      pass[4] = ExprEval.compareClass(result, Integer.class)
+          && ExprEval.compareValue(result, intVal);
+
+      result = ExprEval.evaluateValueExpression(immExpr, longNV, long.class);
+      pass[5] = ExprEval.compareClass(result, Long.class)
+          && ExprEval.compareValue(result, longVal);
+
+      result = ExprEval.evaluateValueExpression(defExpr, floatNV, float.class);
+      pass[6] = ExprEval.compareClass(result, Float.class)
+          && ExprEval.compareValue(result, floatVal);
+
+      result = ExprEval.evaluateValueExpression(immExpr, doubleNV,
+          double.class);
+      pass[7] = ExprEval.compareClass(result, Double.class)
+          && ExprEval.compareValue(result, doubleVal);
+
+    } catch (RuntimeException re) {
+      throw new Exception(re);
+    } catch (Exception e) {
+      throw new Exception(e);
+    } finally {
+      ExprEval.cleanup();
+    }
+
+    for (int i = 0; i < pass.length; ++i) {
+      if (!pass[i]) {
+        fail = true;
+        logger.log(Logger.Level.ERROR, "Unexpected result for test case " + i);
+      }
+    }
+
+    if (fail)
+      throw new Exception("TEST FAILED");
+  }
+
+  /**
+   * @testName: positiveElBooleanCoercionTest
+   * @assertion_ids: EL:SPEC:41.1; EL:SPEC:41.2; EL:SPEC:41.3
+   * @test_Strategy: Validate that null, the empty String, a Boolean, and a
+   *                 proper String argument to Boolean.valueOf() are coerced to
+   *                 the expected Boolean values.
+   */
+  @Test
+  public void positiveElBooleanCoercionTest() throws Exception {
+
+    Class expectedClass = Boolean.class;
+    boolean pass = false;
+
+    try {
+      Object result2 = ExprEval.evaluateValueExpression("#{''}", null,
+          expectedClass);
+      Object result3 = ExprEval.evaluateValueExpression(
+          "${" + Boolean.TRUE + "}", null, expectedClass);
+      Object result4 = ExprEval.evaluateValueExpression("#{'true'}", null,
+          expectedClass);
+
+      logger.log(Logger.Level.TRACE, "result2 is " + result2.toString());
+      logger.log(Logger.Level.TRACE, "result3 is " + result3.toString());
+      logger.log(Logger.Level.TRACE, "result4 is " + result4.toString());
+
+      pass = (ExprEval.compareClass(result2, expectedClass)
+          && ExprEval.compareValue(result2, Boolean.FALSE)
+          && ExprEval.compareClass(result3, expectedClass)
+          && ExprEval.compareValue(result3, Boolean.TRUE)
+          && ExprEval.compareClass(result4, expectedClass)
+          && ExprEval.compareValue(result4, Boolean.TRUE));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: negativeElBooleanCoercionTest
+   * @assertion_ids: EL:SPEC:41.4; EL:JAVADOC:112
+   * @test_Strategy: Validate that an error occurs when an attempt is made to
+   *                 coerce an invalid class to a Boolean. The coercion is
+   *                 performed with a call to ValueExpression.getValue(), which
+   *                 must throw an ELException.
+   */
+  @Test
+  public void negativeElBooleanCoercionTest() throws Exception {
+
+    boolean pass = false;
+
+    try {
+      ExprEval.evaluateValueExpression("${1}", null, Boolean.class);
+      logger.log(Logger.Level.ERROR, 
+          "No exception thrown when coercing invalid class " + "to Boolean");
+
+    } catch (ELException ee) {
+      pass = true;
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elPrimitiveToStringCoercionTest
+   * @assertion_ids: EL:SPEC:38.1; EL:SPEC:38.2; EL:SPEC:38.3; EL:SPEC:38.5
+   * @test_Strategy: Validate that the following types coerce to type of String
+   *                 and the expected String value is returned.
+   * 
+   *                 Types: String(), boolean, null, byte, char, short, int,
+   *                 long, float, double, enum.
+   * 
+   */
+  @Test
+  public void elPrimitiveToStringCoercionTest() throws Exception {
+
+    boolean pass1, pass2, pass4, pass5, pass6, pass7, pass8, pass9, pass10,
+        pass11 = false;
+
+    Object result1, result2, result4, result5, result6, result7, result8,
+        result9, result10, result11;
+
+    Class expectedClass = String.class;
+
+    String primString = "\"STRING\""; // result1
+    boolean primBoolean = false; // result2
+    // String nothing = null; // result3
+    byte primByte = 0; // result4
+    char primChar = '1'; // result5
+    short primShort = 2; // result6
+    int primInt = 3; // result7
+    long primLong = 4L; // result8
+    float primFloat = 5.5f; // result9
+    double primDouble = 6.5d; // result10
+    greeting morning; // result11
+    morning = greeting.hello;
+
+    try {
+      // String to String
+      result1 = ExprEval.evaluateValueExpression("${" + primString + "}", null,
+          expectedClass);
+      pass1 = (ExprEval.compareClass(result1, expectedClass)
+          && ExprEval.compareValue(result1, "STRING"));
+
+      // boolean to String
+      result2 = ExprEval.evaluateValueExpression("#{" + primBoolean + "}", null,
+          expectedClass);
+      pass2 = (ExprEval.compareClass(result2, expectedClass)
+          && ExprEval.compareValue(result2, "false"));
+
+      // byte to String
+      result4 = ExprEval.evaluateValueExpression("#{" + primByte + "}", null,
+          expectedClass);
+      pass4 = (ExprEval.compareClass(result4, expectedClass)
+          && ExprEval.compareValue(result4, "0"));
+
+      // char to String
+      result5 = ExprEval.evaluateValueExpression("#{" + primChar + "}", null,
+          expectedClass);
+      pass5 = (ExprEval.compareClass(result5, expectedClass)
+          && ExprEval.compareValue(result5, "1"));
+
+      // short to String
+      result6 = ExprEval.evaluateValueExpression("#{" + primShort + "}", null,
+          expectedClass);
+      pass6 = (ExprEval.compareClass(result6, expectedClass)
+          && ExprEval.compareValue(result6, "2"));
+
+      // int to String
+      result7 = ExprEval.evaluateValueExpression("#{" + primInt + "}", null,
+          expectedClass);
+      pass7 = (ExprEval.compareClass(result7, expectedClass)
+          && ExprEval.compareValue(result7, "3"));
+
+      // long to String
+      result8 = ExprEval.evaluateValueExpression("#{" + primLong + "}", null,
+          expectedClass);
+      pass8 = (ExprEval.compareClass(result8, expectedClass)
+          && ExprEval.compareValue(result8, "4"));
+
+      // float to String
+      result9 = ExprEval.evaluateValueExpression("#{" + primFloat + "}", null,
+          expectedClass);
+      pass9 = (ExprEval.compareClass(result9, expectedClass)
+          && ExprEval.compareValue(result9, "5.5"));
+
+      // double to String
+      result10 = ExprEval.evaluateValueExpression("#{" + primDouble + "}", null,
+          expectedClass);
+      pass10 = (ExprEval.compareClass(result10, expectedClass)
+          && ExprEval.compareValue(result10, "6.5"));
+
+      // enum to String
+      result11 = ExprEval.evaluateValueExpression("#{'" + morning + "'}", null,
+          expectedClass);
+
+      pass11 = (ExprEval.compareClass(result11, expectedClass)
+          && ExprEval.compareValue(result11, morning.name()));
+
+    } catch (RuntimeException re) {
+      throw new Exception(re);
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass1)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "String Coerced to String Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass2)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "boolean Coerced to String Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass4)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "byte Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+    if (!pass5)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "char Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+    if (!pass6)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "short Coerced to String Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass7)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "int Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+    if (!pass8)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "long Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+    if (!pass9)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "float Coerced to String Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass10)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "double Coerced to String Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass11)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "enum Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+  }
+
+  /**
+   * @testName: elWrapperToStringCoercionTest
+   * @assertion_ids: EL:SPEC:38.5
+   * @test_Strategy: Validate that the following types coerce to type of String
+   *                 and the expected String value is returned.
+   * 
+   *                 Types: Boolean, Byte, Character, Short, Integer, Long,
+   *                 Float, Double.
+   * 
+   */
+  @Test
+  public void elWrapperToStringCoercionTest() throws Exception {
+
+    boolean pass1, pass2, pass3, pass4, pass5, pass6, pass7, pass8 = false;
+
+    Object result1, result2, result3, result4, result5, result6, result7,
+        result8;
+
+    Class expectedClass = String.class;
+
+    Boolean boo = false; // result1
+    Byte bite = 0; // result2
+    Character funny = '1'; // result3
+    Short tee = 2; // result4
+    Integer i = 3; // result5
+    Long rope = 4L; // result6
+    Float ter = 5.5f; // result7
+    Double down = 6.5d; // result8
+
+    try {
+      // Boolean to String
+      result1 = ExprEval.evaluateValueExpression("${" + boo + "}", null,
+          expectedClass);
+      pass1 = (ExprEval.compareClass(result1, expectedClass)
+          && ExprEval.compareValue(result1, "false"));
+
+      // Byte to String
+      result2 = ExprEval.evaluateValueExpression("#{" + bite + "}", null,
+          expectedClass);
+      pass2 = (ExprEval.compareClass(result2, expectedClass)
+          && ExprEval.compareValue(result2, "0"));
+
+      // Character to String
+      result3 = ExprEval.evaluateValueExpression("#{" + funny + "}", null,
+          expectedClass);
+      pass3 = (ExprEval.compareClass(result3, expectedClass)
+          && ExprEval.compareValue(result3, "1"));
+
+      // Short to String
+      result4 = ExprEval.evaluateValueExpression("#{" + tee + "}", null,
+          expectedClass);
+      pass4 = (ExprEval.compareClass(result4, expectedClass)
+          && ExprEval.compareValue(result4, "2"));
+
+      // Integer to String
+      result5 = ExprEval.evaluateValueExpression("#{" + i + "}", null,
+          expectedClass);
+      pass5 = (ExprEval.compareClass(result5, expectedClass)
+          && ExprEval.compareValue(result5, "3"));
+
+      // Long to String
+      result6 = ExprEval.evaluateValueExpression("#{" + rope + "}", null,
+          expectedClass);
+      pass6 = (ExprEval.compareClass(result6, expectedClass)
+          && ExprEval.compareValue(result6, "4"));
+
+      // Float to String
+      result7 = ExprEval.evaluateValueExpression("#{" + ter + "}", null,
+          expectedClass);
+      pass7 = (ExprEval.compareClass(result7, expectedClass)
+          && ExprEval.compareValue(result7, "5.5"));
+
+      // long to String
+      result8 = ExprEval.evaluateValueExpression("#{" + down + "}", null,
+          expectedClass);
+      pass8 = (ExprEval.compareClass(result8, expectedClass)
+          && ExprEval.compareValue(result8, "6.5"));
+
+    } catch (RuntimeException re) {
+      throw new Exception(re);
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass1)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "String Coerced to String Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass2)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "boolean Coerced to String Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass3)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "null Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+    if (!pass4)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "byte Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+    if (!pass5)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "char Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+    if (!pass6)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "short Coerced to String Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass7)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "int Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+    if (!pass8)
+      throw new Exception(
+          "TEST FAILED: pass = false" + NLINE + "long Coerced to String Failed!"
+              + NLINE + "See above for expected value." + NLINE);
+  }
+
+  /**
+   * @testName: positiveElCharacterCoercionTest
+   * @assertion_ids: EL:SPEC:40.1; EL:SPEC:40.2; EL:SPEC:40.4; EL:SPEC:40.5
+   * @test_Strategy: Validate that the following types coerce to type of
+   *                 Character and the expected Character value is returned.
+   * 
+   *                 Types: String, Byte, Character, Short, Integer, Long,
+   *                 Float, Double, null, empty String.
+   * 
+   */
+  @Test
+  public void positiveElCharacterCoercionTest() throws Exception {
+
+    boolean pass1, pass2, pass3, pass4, pass5, pass6, pass7, pass8,
+        pass10 = false;
+
+    Object result1, result2, result3, result4, result5, result6, result7,
+        result8, result10;
+
+    Class expectedClass = Character.class;
+
+    Byte bite = 7;
+    Character funny = '1';
+    Short tee = 2;
+    Integer i = 3;
+    Long rope = 4L;
+    Float ter = 5f;
+    Double down = 6.5d;
+
+    try {
+      // String to Character
+      result1 = ExprEval.evaluateValueExpression("${'STRING'}", null,
+          expectedClass);
+      pass1 = (ExprEval.compareClass(result1, expectedClass)
+          && ExprEval.compareValue(result1, 'S'));
+
+      // Byte to Character
+      result2 = ExprEval.evaluateValueExpression("${" + bite + "}", null,
+          expectedClass);
+      pass2 = (ExprEval.compareClass(result2, expectedClass)
+          && ExprEval.compareValue(result2, Character.valueOf((char) 7)));
+
+      // Character to Character
+      result3 = ExprEval.evaluateValueExpression("${" + funny + "}", null,
+          expectedClass);
+      pass3 = (ExprEval.compareClass(result3, expectedClass)
+          && ExprEval.compareValue(result3, Character.valueOf((char) 1)));
+
+      // Short to Character
+      result4 = ExprEval.evaluateValueExpression("${" + tee + "}", null,
+          expectedClass);
+      pass4 = (ExprEval.compareClass(result4, expectedClass)
+          && ExprEval.compareValue(result4, Character.valueOf((char) 2)));
+
+      // Integer to Character
+      result5 = ExprEval.evaluateValueExpression("${" + i + "}", null,
+          expectedClass);
+      pass5 = (ExprEval.compareClass(result5, expectedClass)
+          && ExprEval.compareValue(result5, Character.valueOf((char) 3)));
+
+      // Long to Character
+      result6 = ExprEval.evaluateValueExpression("${" + rope + "}", null,
+          expectedClass);
+      pass6 = (ExprEval.compareClass(result6, expectedClass)
+          && ExprEval.compareValue(result6, Character.valueOf((char) 4)));
+
+      // Float to Character
+      result7 = ExprEval.evaluateValueExpression("${" + ter + "}", null,
+          expectedClass);
+      pass7 = (ExprEval.compareClass(result7, expectedClass)
+          && ExprEval.compareValue(result7, Character.valueOf((char) 5)));
+
+      // Double to Character
+      result8 = ExprEval.evaluateValueExpression("${" + down + "}", null,
+          expectedClass);
+      pass8 = (ExprEval.compareClass(result8, expectedClass)
+          && ExprEval.compareValue(result8, Character.valueOf((char) 6)));
+
+      // empty String to Character
+      result10 = ExprEval.evaluateValueExpression("${''}", null, expectedClass);
+      pass10 = (ExprEval.compareClass(result10, expectedClass)
+          && ExprEval.compareValue(result10, Character.valueOf((char) 0)));
+
+    } catch (RuntimeException re) {
+      throw new Exception(re);
+    } catch (Exception e) {
+      ELTestUtil.printStackTrace(e);
+      throw new Exception(e);
+    }
+
+    if (!pass1)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "String Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass2)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "Byte Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass3)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "Character Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass4)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "Short Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass5)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "Integer Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass6)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "Long Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass7)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "Float Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass8)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "Double Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+    if (!pass10)
+      throw new Exception("TEST FAILED: pass = false" + NLINE
+          + "Empty String Coerced to Character Failed!" + NLINE
+          + "See above for expected value." + NLINE);
+
+  }
+
+  /**
+   * @testName: negativeElCharacterCoercionTest
+   * @assertion_ids: EL:SPEC:40.3; EL:JAVADOC:112
+   * @test_Strategy: Validate that an error occurs when an attempt is made to
+   *                 coerce a boolean to Character. The coercion is performed
+   *                 with a call to ValueExpression.getValue(), which must throw
+   *                 an ELException.
+   */
+  @Test
+  public void negativeElCharacterCoercionTest() throws Exception {
+
+    boolean pass = false;
+
+    try {
+      ExprEval.evaluateValueExpression("${" + pass + "}", null,
+          Character.class);
+      logger.log(Logger.Level.ERROR, 
+          "No exception thrown when coercing Boolean " + "to Character!");
+
+    } catch (ELException ee) {
+      pass = true;
+
+    } catch (Exception e) {
+      logger.log(Logger.Level.ERROR, "Exception thrown, but it was not an ELException");
+      ELTestUtil.printStackTrace(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: negativeElNumberCoercionTest
+   * @assertion_ids: EL:SPEC:39.3; EL:SPEC:39.6.1.1; EL:SPEC:39.7.3;
+   *                 EL:SPEC:39.7.1; EL:SPEC:39.6.1.1; EL:JAVADOC:112
+   * @test_Strategy: Validate that an error occurs when an attempt is made to
+   *                 coerce a: -Boolean to Number. -String to a Number. The
+   *                 coercion is performed with a call to
+   *                 ValueExpression.getValue(), which must throw an
+   *                 ELException.
+   */
+  @Test
+  public void negativeElNumberCoercionTest() throws Exception {
+
+    boolean pass;
+    Enumeration keys = numberTable.keys();
+    String name;
+    Class testClass;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      // Coercing Boolean to Number type.
+      try {
+        ExprEval.evaluateValueExpression("${" + pass + "}", null, testClass);
+        logger.log(Logger.Level.ERROR, "No exception thrown when coercing Boolean " + "to "
+            + name + "!" + NLINE);
+
+      } catch (ELException ee) {
+        pass = true;
+
+      } catch (Exception e) {
+        logger.log(Logger.Level.ERROR, "Exception thrown, but it was not an ELException");
+        ELTestUtil.printStackTrace(e);
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+      // Coercing String to Number type.
+      try {
+        ExprEval.evaluateValueExpression("${'A'}", null, testClass);
+        logger.log(Logger.Level.ERROR, "No exception thrown when coercing String " + "to "
+            + name + "!" + NLINE);
+
+      } catch (ELException ee) {
+        pass = true;
+
+      } catch (Exception e) {
+        logger.log(Logger.Level.ERROR, "Exception thrown, but it was not an ELException");
+        ELTestUtil.printStackTrace(e);
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+    }
+
+  }
+
+  /**
+   * @testName: elNullToNumberCoercionTest
+   * @assertion_ids: EL:SPEC:39.1
+   * @test_Strategy: Validate that when null or empty String is given. That the
+   *                 returned value is 0. Test this for the Following types.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   */
+  @Test
+  public void elNullToNumberCoercionTest() throws Exception {
+
+    boolean pass1;
+    Object result1;
+    Enumeration keys = numberTable.keys();
+    String name;
+    Class testClass;
+    Object expectedValue;
+
+    while (keys.hasMoreElements()) {
+      pass1 = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        expectedValue = Byte.valueOf((byte) 0);
+      } else if ("Short".equals(name)) {
+        expectedValue = Short.valueOf((short) 0);
+      } else if ("Integer".equals(name)) {
+        expectedValue = Integer.valueOf(0);
+      } else if ("Long".equals(name)) {
+        expectedValue = Long.valueOf(0L);
+      } else if ("Float".equals(name)) {
+        expectedValue = Float.valueOf(0f);
+      } else if ("Double".equals(name)) {
+        expectedValue = Double.valueOf(0d);
+      } else if ("BigInteger".equals(name)) {
+        expectedValue = BigInteger.valueOf(0);
+      } else if ("BigDecimal".equals(name)) {
+        expectedValue = BigDecimal.valueOf(0);
+      } else {
+        // Default Value, this should never been utilized.
+        expectedValue = "0";
+      }
+
+      try {
+        // Coercing Empty String to Number type.
+        result1 = ExprEval.evaluateValueExpression("${''}", null, testClass);
+        pass1 = (ExprEval.compareClass(result1, testClass)
+            && ExprEval.compareValue(result1, expectedValue));
+        if (!pass1)
+          throw new Exception("TEST FAILED: pass = false" + NLINE
+              + "Empty String Coerced to " + name + " Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+  }
+
+  /**
+   * @testName: elNumberToByteCoercionTest
+   * @assertion_ids: EL:SPEC:39.5.3
+   * @test_Strategy: Validate that following Number types coerce to Byte and the
+   *                 expected Byte value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elNumberToByteCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, testValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass = Byte.class;
+    Byte expectedValue;
+    Class testClass;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = (Byte) numberTable.get(testClass);
+        expectedValue = Byte.valueOf(BYTE);
+      } else if ("Short".equals(name)) {
+        testValue = (Short) numberTable.get(testClass);
+        expectedValue = Byte.valueOf(SHORT);
+      } else if ("Integer".equals(name)) {
+        testValue = (Integer) numberTable.get(testClass);
+        expectedValue = Byte.valueOf(INTEGER);
+      } else if ("Long".equals(name)) {
+        testValue = (Long) numberTable.get(testClass);
+        expectedValue = Byte.valueOf(LONG);
+      } else if ("Float".equals(name)) {
+        testValue = (Float) numberTable.get(testClass);
+        expectedValue = Byte.valueOf((Float.valueOf(FLOAT)).byteValue());
+      } else if ("Double".equals(name)) {
+        testValue = (Double) numberTable.get(testClass);
+        expectedValue = Byte.valueOf((Double.valueOf(DOUBLE)).byteValue());
+      } else if ("BigInteger".equals(name)) {
+        testValue = (BigInteger) numberTable.get(testClass);
+        expectedValue = Byte.valueOf(BIGINT);
+      } else if ("BigDecimal".equals(name)) {
+        testValue = (BigDecimal) numberTable.get(testClass);
+        expectedValue = Byte.valueOf((Double.valueOf(BIGDEC)).byteValue());
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = Byte.valueOf("1");
+      }
+
+      try {
+        // Coercing Numbers to Byte type.
+        result = ExprEval.evaluateValueExpression("${" + testValue + "}", null,
+            expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue(result, expectedValue));
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + name
+              + " Coerced to Byte Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elNumberToShortCoercionTest
+   * @assertion_ids: EL:SPEC:39.5.4
+   * @test_Strategy: Validate that following Number types coerce to Short and
+   *                 the expected Short value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elNumberToShortCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, testValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass = Short.class;
+    Short expectedValue;
+    Class testClass;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = (Byte) numberTable.get(testClass);
+        expectedValue = Short.valueOf(BYTE);
+      } else if ("Short".equals(name)) {
+        testValue = (Short) numberTable.get(testClass);
+        expectedValue = Short.valueOf(SHORT);
+      } else if ("Integer".equals(name)) {
+        testValue = (Integer) numberTable.get(testClass);
+        expectedValue = Short.valueOf(INTEGER);
+      } else if ("Long".equals(name)) {
+        testValue = (Long) numberTable.get(testClass);
+        expectedValue = Short.valueOf(LONG);
+      } else if ("Float".equals(name)) {
+        testValue = (Float) numberTable.get(testClass);
+        expectedValue = Short.valueOf((Float.valueOf(FLOAT)).shortValue());
+      } else if ("Double".equals(name)) {
+        testValue = (Double) numberTable.get(testClass);
+        expectedValue = Short.valueOf((Double.valueOf(DOUBLE)).shortValue());
+      } else if ("BigInteger".equals(name)) {
+        testValue = (BigInteger) numberTable.get(testClass);
+        expectedValue = Short.valueOf(BIGINT);
+      } else if ("BigDecimal".equals(name)) {
+        testValue = (BigDecimal) numberTable.get(testClass);
+        expectedValue = Short.valueOf((Double.valueOf(BIGDEC)).shortValue());
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = Short.valueOf("1");
+      }
+
+      try {
+        // Coercing Number to Short type.
+        result = ExprEval.evaluateValueExpression("${" + testValue + "}", null,
+            expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue(result, expectedValue));
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + name
+              + " Coerced to Short Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elNumberToIntegerCoercionTest
+   * @assertion_ids: EL:SPEC:39.5.5
+   * @test_Strategy: Validate that following Number types coerce to Integer and
+   *                 the expected Integer value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elNumberToIntegerCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, testValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass = Integer.class;
+    Integer expectedValue;
+    Class testClass;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = (Byte) numberTable.get(testClass);
+        expectedValue = Integer.valueOf(BYTE);
+      } else if ("Short".equals(name)) {
+        testValue = (Short) numberTable.get(testClass);
+        expectedValue = Integer.valueOf(SHORT);
+      } else if ("Integer".equals(name)) {
+        testValue = (Integer) numberTable.get(testClass);
+        expectedValue = Integer.valueOf(INTEGER);
+      } else if ("Long".equals(name)) {
+        testValue = (Long) numberTable.get(testClass);
+        expectedValue = Integer.valueOf(LONG);
+      } else if ("Float".equals(name)) {
+        testValue = (Float) numberTable.get(testClass);
+        expectedValue = Integer.valueOf(Float.valueOf(FLOAT).intValue());
+      } else if ("Double".equals(name)) {
+        testValue = (Double) numberTable.get(testClass);
+        expectedValue = Integer.valueOf(Double.valueOf(DOUBLE).intValue());
+      } else if ("BigInteger".equals(name)) {
+        testValue = (BigInteger) numberTable.get(testClass);
+        expectedValue = Integer.valueOf(BIGINT);
+      } else if ("BigDecimal".equals(name)) {
+        testValue = (BigDecimal) numberTable.get(testClass);
+        expectedValue = Integer.valueOf(Double.valueOf(BIGDEC).intValue());
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = Integer.valueOf("1");
+      }
+
+      try {
+        // Coercing Number to Integer type.
+        result = ExprEval.evaluateValueExpression("${" + testValue + "}", null,
+            expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue(result, expectedValue));
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + name
+              + " Coerced to Integer Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+  }
+
+  /**
+   * @testName: elNumberToLongCoercionTest
+   * @assertion_ids: EL:SPEC:39.5.6
+   * @test_Strategy: Validate that following Number types coerce to Long and the
+   *                 expected Long value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elNumberToLongCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, testValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass = Long.class;
+    Long expectedValue;
+    Class testClass;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = (Byte) numberTable.get(testClass);
+        expectedValue = Long.valueOf(BYTE);
+      } else if ("Short".equals(name)) {
+        testValue = (Short) numberTable.get(testClass);
+        expectedValue = Long.valueOf(SHORT);
+      } else if ("Integer".equals(name)) {
+        testValue = (Integer) numberTable.get(testClass);
+        expectedValue = Long.valueOf(INTEGER);
+      } else if ("Long".equals(name)) {
+        testValue = (Long) numberTable.get(testClass);
+        expectedValue = Long.valueOf(LONG);
+      } else if ("Float".equals(name)) {
+        testValue = (Float) numberTable.get(testClass);
+        expectedValue = Long.valueOf(Float.valueOf(FLOAT).longValue());
+      } else if ("Double".equals(name)) {
+        testValue = (Double) numberTable.get(testClass);
+        expectedValue = Long.valueOf(Double.valueOf(DOUBLE).longValue());
+      } else if ("BigInteger".equals(name)) {
+        testValue = (BigInteger) numberTable.get(testClass);
+        expectedValue = Long.valueOf(BIGINT);
+      } else if ("BigDecimal".equals(name)) {
+        testValue = (BigDecimal) numberTable.get(testClass);
+        expectedValue = Long.valueOf(Double.valueOf(BIGDEC).longValue());
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = Long.valueOf("1");
+      }
+
+      try {
+        // Coercing Number to Long type.
+        result = ExprEval.evaluateValueExpression("${" + testValue + "}", null,
+            expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue(result, expectedValue));
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + name
+              + " Coerced to Long Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elNumberToFloatCoercionTest
+   * @assertion_ids: EL:SPEC:39.5.7
+   * @test_Strategy: Validate that following Number types coerce to Float and
+   *                 the expected Float value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elNumberToFloatCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, testValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass = Float.class;
+    Float expectedValue;
+    Class testClass;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = (Byte) numberTable.get(testClass);
+        expectedValue = Float.valueOf(BYTE);
+      } else if ("Short".equals(name)) {
+        testValue = (Short) numberTable.get(testClass);
+        expectedValue = Float.valueOf(SHORT);
+      } else if ("Integer".equals(name)) {
+        testValue = (Integer) numberTable.get(testClass);
+        expectedValue = Float.valueOf(INTEGER);
+      } else if ("Long".equals(name)) {
+        testValue = (Long) numberTable.get(testClass);
+        expectedValue = Float.valueOf(LONG);
+      } else if ("Float".equals(name)) {
+        testValue = (Float) numberTable.get(testClass);
+        expectedValue = Float.valueOf(FLOAT);
+      } else if ("Double".equals(name)) {
+        testValue = (Double) numberTable.get(testClass);
+        expectedValue = Float.valueOf(DOUBLE);
+      } else if ("BigInteger".equals(name)) {
+        testValue = (BigInteger) numberTable.get(testClass);
+        expectedValue = Float.valueOf(BIGINT);
+      } else if ("BigDecimal".equals(name)) {
+        testValue = (BigDecimal) numberTable.get(testClass);
+        expectedValue = Float.valueOf(BIGDEC);
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = Float.valueOf("1");
+      }
+
+      try {
+        // Coercing Number to Float type.
+        result = ExprEval.evaluateValueExpression("${" + testValue + "}", null,
+            expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue((Float) result, expectedValue, 2));
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + name
+              + " Coerced to Float Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elNumberToDoubleCoercionTest
+   * @assertion_ids: EL:SPEC:39.5.8
+   * @test_Strategy: Validate that following Number types coerce to Double and
+   *                 the expected Double value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elNumberToDoubleCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, testValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass = Double.class;
+    Double expectedValue;
+    Class testClass;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = (Byte) numberTable.get(testClass);
+        expectedValue = Double.valueOf(BYTE);
+      } else if ("Short".equals(name)) {
+        testValue = (Short) numberTable.get(testClass);
+        expectedValue = Double.valueOf(SHORT);
+      } else if ("Integer".equals(name)) {
+        testValue = (Integer) numberTable.get(testClass);
+        expectedValue = Double.valueOf(INTEGER);
+      } else if ("Long".equals(name)) {
+        testValue = (Long) numberTable.get(testClass);
+        expectedValue = Double.valueOf(LONG);
+      } else if ("Float".equals(name)) {
+        testValue = (Float) numberTable.get(testClass);
+        expectedValue = Double.valueOf(FLOAT);
+      } else if ("Double".equals(name)) {
+        testValue = (Double) numberTable.get(testClass);
+        expectedValue = Double.valueOf(DOUBLE);
+      } else if ("BigInteger".equals(name)) {
+        testValue = (BigInteger) numberTable.get(testClass);
+        expectedValue = Double.valueOf(BIGINT);
+      } else if ("BigDecimal".equals(name)) {
+        testValue = (BigDecimal) numberTable.get(testClass);
+        expectedValue = Double.valueOf(BIGDEC);
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = Double.valueOf("1");
+      }
+
+      try {
+        // Coercing Number to Double type.
+        result = ExprEval.evaluateValueExpression("${" + testValue + "}", null,
+            expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue(result, expectedValue));
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + name
+              + " Coerced to Double Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elStringToNumberCoercionTest
+   * @assertion_ids: EL:SPEC:39.6.1.2; EL:SPEC:39.7.2; EL:SPEC:39.7.4
+   * @test_Strategy: Validate that String types coerce to the following types
+   *                 and the expected value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elStringToNumberCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, expectedValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass;
+    String name, testValue;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      expectedClass = (Class) keys.nextElement();
+      name = expectedClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = BYTE;
+        expectedValue = Byte.valueOf(BYTE);
+      } else if ("Short".equals(name)) {
+        testValue = SHORT;
+        expectedValue = Short.valueOf(SHORT);
+      } else if ("Integer".equals(name)) {
+        testValue = INTEGER;
+        expectedValue = Integer.valueOf(INTEGER);
+      } else if ("Long".equals(name)) {
+        testValue = LONG;
+        expectedValue = Long.valueOf(LONG);
+      } else if ("Float".equals(name)) {
+
+        // remove non-numeric char
+        testValue = FLOAT.substring(0, FLOAT.length() - 1);
+        expectedValue = Float.valueOf(FLOAT);
+      } else if ("Double".equals(name)) {
+        testValue = DOUBLE.substring(0, DOUBLE.length() - 1);
+        expectedValue = Double.valueOf(DOUBLE);
+      } else if ("BigInteger".equals(name)) {
+        testValue = BIGINT;
+        expectedValue = BigInteger.valueOf(Long.valueOf(BIGINT));
+      } else if ("BigDecimal".equals(name)) {
+        testValue = BIGDEC;
+        expectedValue = BigDecimal.valueOf(Double.valueOf(BIGDEC));
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = "1";
+      }
+
+      try {
+        // Coercing String to Number types.
+        result = ExprEval.evaluateValueExpression("${'" + testValue + "'}",
+            null, expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue(result, expectedValue));
+
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + "Coerced to "
+              + name + " Failed!" + NLINE + "See above for expected value."
+              + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elCharacterToNumberCoercionTest
+   * @assertion_ids: EL:SPEC:39.2
+   * @test_Strategy: Validate that Character types coerce to the following types
+   *                 and the expected value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elCharacterToNumberCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, expectedValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass;
+    Character testValue;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      expectedClass = (Class) keys.nextElement();
+      name = expectedClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = '1';
+        expectedValue = Byte.valueOf("1");
+      } else if ("Short".equals(name)) {
+        testValue = '2';
+        expectedValue = Short.valueOf("2");
+      } else if ("Integer".equals(name)) {
+        testValue = '3';
+        expectedValue = Integer.valueOf(3);
+      } else if ("Long".equals(name)) {
+        testValue = '4';
+        expectedValue = Long.valueOf(4L);
+      } else if ("Float".equals(name)) {
+        testValue = '5';
+        expectedValue = Float.valueOf(5f);
+      } else if ("Double".equals(name)) {
+        testValue = '6';
+        expectedValue = Double.valueOf(6d);
+      } else if ("BigInteger".equals(name)) {
+        testValue = '7';
+        expectedValue = BigInteger.valueOf(7);
+      } else if ("BigDecimal".equals(name)) {
+        testValue = '8';
+        expectedValue = BigDecimal.valueOf(8);
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = '0';
+        expectedValue = '1';
+      }
+
+      try {
+        // Coercing Character to Number types.
+        result = ExprEval.evaluateValueExpression("${'" + testValue + "'}",
+            null, expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue(result, expectedValue));
+
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + "Coerced to "
+              + name + " Failed!" + NLINE + "See above for expected value."
+              + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elNumberToBigIntegerCoercionTest
+   * @assertion_ids: EL:SPEC:39.5.1.1; EL:SPEC:39.5.1.2
+   * @test_Strategy: Validate that following Number types coerce to BigInteger
+   *                 and the expected value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elNumberToBigIntegerCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, testValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass = BigInteger.class;
+    BigInteger expectedValue;
+    Class testClass;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = (Byte) numberTable.get(testClass);
+        expectedValue = BigInteger.valueOf(Long.valueOf(BYTE));
+      } else if ("Short".equals(name)) {
+        testValue = (Short) numberTable.get(testClass);
+        expectedValue = BigInteger.valueOf(Long.valueOf(SHORT));
+      } else if ("Integer".equals(name)) {
+        testValue = (Integer) numberTable.get(testClass);
+        expectedValue = BigInteger.valueOf(Long.valueOf(INTEGER));
+      } else if ("Long".equals(name)) {
+        testValue = (Long) numberTable.get(testClass);
+        expectedValue = BigInteger.valueOf(Long.valueOf(LONG));
+      } else if ("Float".equals(name)) {
+        testValue = (Float) numberTable.get(testClass);
+        expectedValue = BigInteger.valueOf(Float.valueOf(FLOAT).longValue());
+      } else if ("Double".equals(name)) {
+        testValue = (Double) numberTable.get(testClass);
+        expectedValue = BigInteger.valueOf(Double.valueOf(DOUBLE).longValue());
+      } else if ("BigInteger".equals(name)) {
+        testValue = (BigInteger) numberTable.get(testClass);
+        expectedValue = BigInteger.valueOf(Long.valueOf(BIGINT));
+      } else if ("BigDecimal".equals(name)) {
+        testValue = (BigDecimal) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Double.valueOf(BIGDEC))
+            .toBigInteger();
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = BigInteger.valueOf(Long.valueOf("1"));
+      }
+
+      try {
+        // Coercing Number to BigInteger type.
+        result = ExprEval.evaluateValueExpression("${" + testValue + "}", null,
+            expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue((BigInteger) result, expectedValue, 1));
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + name
+              + " Coerced to BigInteger Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elNumberToBigDecimalCoercionTest
+   * @assertion_ids: EL:SPEC:39.5.2.1; EL:SPEC:39.5.2.2
+   * @test_Strategy: Validate that following Number types coerce to BigDecimal
+   *                 and the expected value is returned.
+   * 
+   *                 Types: Byte, Short, Integer, Long, Float, Double,
+   *                 BigDecimal, BigInteger.
+   * 
+   */
+  @Test
+  public void elNumberToBigDecimalCoercionTest() throws Exception {
+
+    boolean pass;
+    Object result, testValue;
+    Enumeration keys = numberTable.keys();
+    Class expectedClass = BigDecimal.class;
+    BigDecimal expectedValue;
+    Class testClass;
+    String name;
+
+    while (keys.hasMoreElements()) {
+      pass = false;
+      testClass = (Class) keys.nextElement();
+      name = testClass.getSimpleName();
+
+      if ("Byte".equals(name)) {
+        testValue = (Byte) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Double.valueOf(BYTE));
+      } else if ("Short".equals(name)) {
+        testValue = (Short) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Double.valueOf(SHORT));
+      } else if ("Integer".equals(name)) {
+        testValue = (Integer) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Double.valueOf(INTEGER));
+      } else if ("Long".equals(name)) {
+        testValue = (Long) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Double.valueOf(LONG));
+      } else if ("Float".equals(name)) {
+        testValue = (Float) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Float.valueOf(FLOAT).doubleValue());
+      } else if ("Double".equals(name)) {
+        testValue = (Double) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Double.valueOf(DOUBLE));
+      } else if ("BigInteger".equals(name)) {
+        testValue = (BigInteger) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Double.valueOf(BIGINT));
+      } else if ("BigDecimal".equals(name)) {
+        testValue = (BigDecimal) numberTable.get(testClass);
+        expectedValue = BigDecimal.valueOf(Double.valueOf(BIGDEC));
+      } else {
+        // Default Values, this should never been utilized.
+        testValue = "0";
+        expectedValue = BigDecimal.valueOf(Double.valueOf("1"));
+      }
+
+      try {
+        // Coercing Number to BigInteger type.
+        result = ExprEval.evaluateValueExpression("${" + testValue + "}", null,
+            expectedClass);
+        pass = (ExprEval.compareClass(result, expectedClass)
+            && ExprEval.compareValue((BigDecimal) result, expectedValue, 1));
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false" + NLINE + name
+              + " Coerced to BigDecimal Failed!" + NLINE
+              + "See above for expected value." + NLINE);
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+    }
+
+  }
+
+  /**
+   * @testName: elCoerceToEnumTypeTest
+   * @assertion_ids: EL:SPEC:42.1; EL:SPEC:42.2; EL:SPEC:42.3; EL:SPEC:42.4
+   * @test_Strategy: Validate that - an assignable enum type can be coerced to
+   *                 an enum - coercing a null value to an enum type returns a
+   *                 null value - coercing an empty string to an enum type
+   *                 returns a null value - coercing a string to an enum is
+   *                 successful if the string is identical to one of the enum
+   *                 values. If not, an ELException is thrown.
+   */
+  @Test
+  public void elCoerceToEnumTypeTest() throws Exception {
+
+    boolean fail = false;
+    boolean[] pass = { false, false, false, false, false };
+    Object result = null;
+
+    try {
+      // assignable types
+      NameValuePair[] earthNV = NameValuePair
+          .buildUnaryNameValue(planets.EARTH);
+      result = ExprEval.evaluateValueExpression("${A}", earthNV, planets.class);
+      pass[0] = ExprEval.compareClass(result, planets.class)
+          && ExprEval.compareValue(result, planets.EARTH);
+
+      // type is null
+      result = ExprEval.evaluateValueExpression("${null}", null, planets.class);
+      pass[1] = (result == null) ? true : false;
+
+      // type is empty string
+      NameValuePair[] emptyNV = NameValuePair.buildUnaryNameValue("");
+      result = ExprEval.evaluateValueExpression("#{A}", emptyNV, planets.class);
+      pass[2] = (result == null) ? true : false;
+
+      // String value that matches enum identifier
+      NameValuePair[] marsNV = NameValuePair.buildUnaryNameValue("MARS");
+      result = ExprEval.evaluateValueExpression("${A}", marsNV, planets.class);
+      pass[3] = ExprEval.compareClass(result, planets.class)
+          && ExprEval.compareValue(result, planets.MARS);
+
+      // String value that does not match
+      NameValuePair[] plutoNV = NameValuePair.buildUnaryNameValue("PLUTO");
+      try {
+        result = ExprEval.evaluateValueExpression("${A}", plutoNV,
+            planets.class);
+      } catch (ELException e) {
+        pass[4] = true;
+      }
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    } finally {
+      ExprEval.cleanup();
+    }
+
+    for (int i = 0; i < pass.length; ++i) {
+      if (!pass[i]) {
+        fail = true;
+        logger.log(Logger.Level.ERROR, "Unexpected result for test case " + i);
+      }
+    }
+
+    if (fail)
+      throw new Exception("TEST FAILED");
+  }
+
+  /**
+   * @testName: elCoerceToArrayTest
+   * @assertion_ids: EL:SPEC:81.1; EL:SPEC:81.2; EL:SPEC:81.3; EL:SPEC:81.4;
+   *                 EL:SPEC:81.5
+   * @test_Strategy: Validate that - coercing a null to an array returns a null
+   *                 value, coercing an array of type T returns an array of type
+   *                 T, coercing an array coerces each member of the array to
+   *                 the expected type, coercing an array where at least one
+   *                 element cannot be coerced results in an ELException. If
+   *                 not, an ELException is thrown.
+   */
+  @Test
+  public void elCoerceToArrayTest() throws Exception {
+
+    boolean fail = false;
+    boolean[] pass = { false, false, false, false, false };
+    Object result = null;
+
+    try {
+      // If A is null, return null
+      ELProcessor elp0 = new ELProcessor();
+      elp0.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPrimitiveBooleanArray");
+      result = elp0.eval("testPrimitiveBooleanArray(null)");
+      pass[0] = ExprEval.compareClass(result, Integer.class)
+          && ExprEval.compareValue(result, Integer.valueOf(-1));
+      
+      // If A is an array of T, coerce quietly
+      ELProcessor elp1 = new ELProcessor();
+      elp1.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPrimitiveBooleanArray");
+      result = elp1.eval("testPrimitiveBooleanArray([true, false].toArray())");
+      pass[1] = ExprEval.compareClass(result, Integer.class)
+          && ExprEval.compareValue(result, Integer.valueOf(2));
+
+      // If A is an array of other types, coerce each element
+      ELProcessor elp2 = new ELProcessor();
+      elp2.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPrimitiveBooleanArray");
+      result = elp2.eval("testPrimitiveBooleanArray([\"true\", false, true, 'false', null, \"\"].toArray())");
+      pass[2] = ExprEval.compareClass(result, Integer.class)
+          && ExprEval.compareValue(result, Integer.valueOf(6));
+
+      // If A is an array of other types, where at least one cannot be coerced
+      ELProcessor elp3 = new ELProcessor();
+      elp3.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPrimitiveBooleanArray");
+      try {
+        result = elp3.eval("testPrimitiveBooleanArray(['true', 'false', 1234].toArray())");
+      } catch (ELException e) {
+        pass[3] = true;
+      }
+      
+      // If A is not an array, error
+      ELProcessor elp4 = new ELProcessor();
+      elp4.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPrimitiveBooleanArray");
+      try {
+        result = elp4.eval("testPrimitiveBooleanArray([true, false, true, false, true])");
+      } catch (ELException e) {
+        pass[4] = true;
+      }
+
+    } catch (Exception e) {
+      logger.log(Logger.Level.ERROR, "Testing coercion to arrays " +
+          "threw an Exception!" + ELTestUtil.NL + "Received: " + e.toString() + ELTestUtil.NL);
+
+      throw new Exception(e);
+    } finally {
+      ExprEval.cleanup();
+    }
+
+    for (int i = 0; i < pass.length; ++i) {
+      if (!pass[i]) {
+        fail = true;
+        logger.log(Logger.Level.ERROR, "Unexpected result for test case " + i);
+      }
+    }
+
+    if (fail)
+      throw new Exception("TEST FAILED");
+  }
+
+
+  public static int testPrimitiveBooleanArray(boolean input[]) {
+    if (input == null) {
+      return -1;
+    }
+    
+    return input.length;
+  }
+
+  
+  /**
+   * @testName: elCoerceLambdaExpressionToFunctionalInterfaceTest
+   * @assertion_ids: EL:SPEC:79.1; EL:SPEC:79.2; EL:SPEC:79.3
+   * @test_Strategy: Validate that - a lambda expression can be coerced to a
+   *                 functional interface invocation if the parameter types
+   *                 match or can be made to match via the standard coercion
+   *                 rules.
+   */
+  @Test
+  public void elCoerceLambdaExpressionToFunctionalInterfaceTest() throws Exception {
+
+    boolean fail = false;
+    boolean[] pass = { false, false, false, false, false, false };
+    Object result = null;
+
+    try {
+      // Coercible lambda expression where filter matches
+      ELProcessor elp0 = new ELProcessor();
+      elp0.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPredicateString");
+      result = elp0.eval("testPredicateString(x -> x.equals('data'))");
+      pass[0] = ExprEval.compareClass(result, String.class) && ExprEval.compareValue(result, "PASS");
+      
+      // Coercible lambda expression where filter does not match
+      ELProcessor elp1 = new ELProcessor();
+      elp1.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPredicateString");
+      result = elp1.eval("testPredicateString(x -> x.equals('other'))");
+      pass[1] = ExprEval.compareClass(result, String.class) && ExprEval.compareValue(result, "BLOCK");
+
+      // Not a lambda expression
+      ELProcessor elp2 = new ELProcessor();
+      elp2.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPredicateString");
+      try {
+        result = elp2.eval("testPredicateString('notLambdaExpression')");
+      } catch (ELException e) {
+        pass[2] = true;
+      }
+
+      /*
+       * Note: The following tests use compareTo(). When the target object (Long or String) is examined by reflection
+       * both compareTo(Object) and compareTo(Long)/compareTo(String) methods will be found as potential matches. The
+       * method matching rules (see section 1.2.1.2 of the specification) require that overload resolution has a higher
+       * precedence than coercion resolution so it is always the compareTo(Object) method that will be used for the
+       * following tests resulting in a ClassCastException (which is wrapped in an ELException).
+       */
+
+      // Coercible lambda expression with wrong type
+      ELProcessor elp3 = new ELProcessor();      
+      elp3.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPredicateLong");
+      try {
+        result = elp3.eval("testPredicateLong(x -> x.compareTo('data') == 0)");
+      } catch (ELException e) {
+        // String 'data' cannot be cast to Long
+        pass[3] = true;
+      }
+
+      // Coercible lambda expression where filter does not match and parameter needs to be coerced
+      ELProcessor elp4 = new ELProcessor();
+      elp4.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPredicateString");
+      try {
+        result = elp4.eval("testPredicateString(x -> x.compareTo(1234) == 0)");
+      } catch (ELException e) {
+        // Long 1234 cannot be cast to String. It is coercible but that should not used here.
+        pass[4] = true;
+      }
+
+      // Coercible lambda expression with coercible type but coercion rules mean this test fails
+      ELProcessor elp5 = new ELProcessor();
+      elp5.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClientIT", "testPredicateLong");
+      try {
+        result = elp5.eval("testPredicateLong(x -> x.compareTo('1234') == 0)");
+      } catch (ELException e) {
+        // String '1234' cannot be cast to String. It is coercible but that should not used here.
+        pass[5] = true;
+      }
+    } catch (Exception e) {
+      logger.log(Logger.Level.ERROR, "Testing coercion of lambda expressions to functional interfaces " +
+          "threw an Exception!" + ELTestUtil.NL + "Received: " + e.toString() + ELTestUtil.NL);
+
+      throw new Exception(e);
+    } finally {
+      ExprEval.cleanup();
+    }
+
+    for (int i = 0; i < pass.length; ++i) {
+      if (!pass[i]) {
+        fail = true;
+        logger.log(Logger.Level.ERROR, "Unexpected result for test case " + i);
+      }
+    }
+
+    if (fail)
+      throw new Exception("TEST FAILED");
+  }
+
+  
+  public static String testPredicateString(Predicate<String> filter) {
+    String s = "data";
+    if (filter.test(s)) {
+      return "PASS";
+    } else {
+      return "BLOCK";
+    }
+  }
+
+  public static String testPredicateLong(Predicate<Long> filter) {
+    Long l = Long.valueOf("1234");
+    if (filter.test(l)) {
+      return "PASS";
+    } else {
+      return "BLOCK";
+    }
+  }
+
+  /**
+   * @testName: elCoerceToOtherTypeTest
+   * @assertion_ids: EL:SPEC:43.1; EL:SPEC:43.2
+   * @test_Strategy: Validate that - an assignable "other" type can be coerced
+   *                 to an "other" type. We coerce an instance of the class
+   *                 java.sql.Time to its parent class java.util.Date. -
+   *                 coercing a null value to an "other" type returns a null
+   *                 value
+   * 
+   */
+  @Test
+  public void elCoerceToOtherTypeTest() throws Exception {
+
+    Time time = new Time(1000000000000L);
+    boolean pass1, pass2 = false;
+
+    try {
+      NameValuePair[] timeNV = NameValuePair.buildUnaryNameValue(time);
+      Object result = ExprEval.evaluateValueExpression("${A}", timeNV,
+          Date.class);
+      pass1 = ExprEval.compareClass(result, Date.class)
+          && ExprEval.compareValue(result, (Date) time);
+
+      result = ExprEval.evaluateValueExpression("#{null}", null, Date.class);
+      pass2 = (result == null) ? true : false;
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    } finally {
+      ExprEval.cleanup();
+    }
+
+    if (!pass1 || !pass2)
+      throw new Exception("TEST FAILED");
+
+  }
+
+  // ------------------------------------------------- private methods
+
+  /**
+   * The HashTable is of this format.
+   * 
+   * Key = Test Class Value = Test Value
+   */
+  private void initializeNumberTable() {
+    numberTable = new Hashtable();
+
+    numberTable.put(Byte.class, Byte.valueOf(BYTE));
+    numberTable.put(Short.class, Short.valueOf(SHORT));
+    numberTable.put(Integer.class, Integer.valueOf(INTEGER));
+    numberTable.put(Long.class, Long.valueOf(LONG));
+    numberTable.put(Float.class, Float.valueOf(FLOAT));
+    numberTable.put(Double.class, Double.valueOf(DOUBLE));
+    numberTable.put(BigInteger.class, BigInteger.valueOf(Long.valueOf(BIGINT)));
+    numberTable.put(BigDecimal.class,
+        BigDecimal.valueOf(Double.valueOf(BIGDEC)));
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/collectionoperators/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/collectionoperators/ELClientIT.java
new file mode 100644
index 0000000..6995d1f
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/collectionoperators/ELClientIT.java
@@ -0,0 +1,767 @@
+/*
+ * Copyright (c) 2013, 2021 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.collectionoperators;
+
+import java.lang.reflect.Array;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.DataBase;
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+
+import jakarta.el.ELProcessor;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private ELProcessor elp;
+
+  private DataBase database;
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /**
+   * @testName: elCollectionMapFilterTest
+   * 
+   * @assertion_ids: EL:SPEC:53; EL:SPEC:53.1; EL:SPEC:53.2; EL:SPEC:53.3;
+   *                 EL:SPEC:59; EL:SPEC:59.1; EL:SPEC:58.1; EL:SPEC:58.2
+   * 
+   * @test_Strategy: Test to make sure the 'map'& "filter' operator works
+   *                 properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionMapFilterTest() throws Exception {
+    buildELContext();
+
+    String[] expr1 = { "[Toy Story, 10.0]", "[History of Golf, 11.0]" };
+
+    String[] expr2 = { "20", "30", "40" };
+
+    testIterable("map-filter-one",
+        "products.stream().filter(p->p.unitPrice >= 10 && "
+            + "p.unitPrice < 12).sorted("
+            + "(p,q)->p.unitPrice-q.unitPrice).map("
+            + "p->[p.name,p.unitPrice]).toList()",
+        expr1);
+
+    testIterable("map-filter-two",
+        "[1,2,3,4].stream().filter(i->i > 1).map(i->i*10).toList()", expr2);
+
+  } // End elCollectionMapFilterTest
+
+  /**
+   * @testName: elCollectionMinTest
+   * 
+   * @assertion_ids: EL:SPEC:72; EL:SPEC:72.1; EL:SPEC:72.2
+   * 
+   * @test_Strategy: Test to make sure the 'min' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionMinTest() throws Exception {
+    buildELContext();
+
+    testStream("min", "[2,3,1,5].stream().min().get()", Long.valueOf(1));
+    elp.eval("comparing = map->(x,y)->map(x).compareTo(map(y))");
+    testStream("min", "[3,2,1].stream().min((i,j)->i-j).get()",
+        Long.valueOf(1));
+    testStream("min",
+        "customers.stream().min((x,y)->x.orders.size()-y.orders.size()).get().name",
+        "Charlie Yeh");
+    elp.eval("comparing = map->(x,y)->map(x).compareTo(map(y))");
+    testStream("min",
+        "customers.stream().min(comparing(c->c.orders.size())).get().name",
+        "Charlie Yeh");
+
+  } // End elCollectionMinTest()
+
+  /**
+   * @testName: elCollectionMaxTest
+   * 
+   * @assertion_ids: EL:SPEC:71; EL:SPEC:71.1; EL:SPEC:71.2
+   * 
+   * @test_Strategy: Test to make sure the 'max' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionMaxTest() throws Exception {
+    buildELContext();
+
+    testStream("max", "[2,3,1,5].stream().max().get()", Long.valueOf(5));
+    testStream("max", "['xy', 'xyz', 'abc'].stream().max().get()", "xyz");
+    testStream("max", "[2].stream().max((i,j)->i-j).get()", Long.valueOf(2));
+    elp.eval("comparing = map->(x,y)->map(x).compareTo(map(y))");
+    testStream("max",
+        "customers.stream().max((x,y)->x.orders.size()-y.orders.size()).get().name",
+        "John Doe");
+    testStream("max",
+        "customers.stream().max(comparing(c->c.orders.size())).get().name",
+        "John Doe");
+
+  } // End elCollectionMaxTest()
+
+  /**
+   * @testName: elCollectionDistinctTest
+   * 
+   * @assertion_ids: EL:SPEC:61; EL:SPEC:61.1
+   * 
+   * @test_Strategy: Test to make sure the 'distinct' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionDistinctTest() throws Exception {
+    buildELContext();
+
+    this.testIterable("distinct",
+        " ['a', 'b', 'b', 'c'].stream().distinct().toList()",
+        new String[] { "a", "b", "c" });
+
+  } // End elCollectionDistinctTest()
+
+  /**
+   * @testName: elCollectionForEachTest
+   * 
+   * @assertion_ids: EL:SPEC:63; EL:SPEC:63.1
+   * 
+   * @test_Strategy: Test to make sure the 'forEach' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionForEachTest() throws Exception {
+    buildELContext();
+
+    String expr1[] = { "Eagle", "Coming Home", "Greatest Hits",
+        "History of Golf", "Toy Story", "iSee" };
+
+    testIterable("forEach",
+        "lst = []; products.stream().forEach(p->lst.add(p.name)); lst", expr1);
+
+  } // End elCollectionForEachTest()
+
+  /**
+   * @testName: elCollectionFindFirstTest
+   * 
+   * @assertion_ids: EL:SPEC:78; EL:SPEC:78.1; EL:SPEC:62; EL:SPEC:62.1;
+   *                 EL:SPEC:62.2
+   * 
+   * @test_Strategy: Test to make sure the 'findFirst' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionFindFirstTest() throws Exception {
+    buildELContext();
+
+    String[] expr1 = { "Product: 200, Eagle, book, 12.5, 100" };
+
+    testIterable("findFirst",
+        "products.stream().sorted(p->p.unitPrice).findFirst().get()", expr1);
+
+  } // End elCollectionFindFirstTest()
+
+  /**
+   * @testName: elCollectionLimitTest
+   * 
+   * @assertion_ids: EL:SPEC:66; EL:SPEC:66.1
+   * 
+   * @test_Strategy: Test to make sure the 'limit' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionLimitTest() throws Exception {
+    buildELContext();
+
+    String[] expr1 = { "[Product: 202, Greatest Hits, cd, 6.5, 200]" };
+
+    String[] expr2 = { "Product: 202, Greatest Hits, cd, 6.5, 200",
+        "Product: 201, Coming Home, dvd, 8.0, 50", };
+
+    testIterable("limit",
+        "products.stream().sorted((p,q)->p.unitPrice-q.unitPrice)."
+            + "limit(1).toList()",
+        expr1);
+
+    testIterable("limit",
+        "products.stream().sorted((p,q)->p.unitPrice-q.unitPrice)."
+            + "limit(2).toList()",
+        expr2);
+
+  } // End elCollectionLimitTest()
+
+  /**
+   * testName: elCollectionAnyMatchTest
+   * 
+   * @assertion_ids: EL:SPEC:75; EL:SPEC:75.1
+   * 
+   * @test_Strategy: Test to make sure the 'anyMatch' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   *         Bug 20438221 : Commented the test for now
+   */
+  public void elCollectionAnyMatchTest() throws Exception {
+    buildELContext();
+
+    testIterable("anyMatch_True",
+        "products.stream().anyMatch(p->p.unitPrice >= 10)", true);
+
+    testIterable("anyMatch_False",
+        "products.stream().anyMatch(p->p.unitPrice == 100)", false);
+
+  } // End elCollectionAnyMatchTest()
+
+  /**
+   * testName: elCollectionNoneMatchTest
+   * 
+   * @assertion_ids: EL:SPEC:77; EL:SPEC:77.1
+   * 
+   * @test_Strategy: Test to make sure the 'noneMatch' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   *         Bug 20438221 : Commented the test for now
+   */
+  public void elCollectionNoneMatchTest() throws Exception {
+    buildELContext();
+
+    testIterable("noneMatch_False",
+        "products.stream().noneMatch(p->p.unitPrice >= 10)", false);
+
+    testIterable("noneMatch_True",
+        "products.stream().noneMatch(p->p.unitPrice == 100)", true);
+
+  } // End elCollectionNoneMatchTest()
+
+  /**
+   * testName: elCollectionAllMatchTest
+   * 
+   * @assertion_ids: EL:SPEC:76; EL:SPEC:76.1
+   * 
+   * @test_Strategy: Test to make sure the 'allMatch' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   *         Bug 20438221 : Commented the test for now.
+   */
+  public void elCollectionAllMatchTest() throws Exception {
+    buildELContext();
+
+    testIterable("allMatch_true",
+        "products.stream().allMatch(p->p.unitPrice >= 1)", true);
+
+    testIterable("allMatch_false",
+        "products.stream().allMatch(p->p.unitPrice == 100)", false);
+
+  } // End elCollectionAllMatchTest()
+
+  /**
+   * @testName: elCollectionSumTest
+   * 
+   * @assertion_ids: EL:SPEC:74; EL:SPEC:74.1
+   * 
+   * @test_Strategy: Test to make sure the 'sum' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionSumTest() throws Exception {
+    buildELContext();
+
+    testIterable("sum", "['10', '12', '13'].stream().sum()",
+        new String[] { "35" });
+
+    testIterable("sum_Empty", "[].stream().sum()", new String[] { "0" });
+
+  } // End elCollectionSumTest()
+
+  /**
+   * @testName: elCollectionCountTest
+   * 
+   * @assertion_ids: EL:SPEC:79; EL:SPEC:79.1
+   * 
+   * @test_Strategy: Test to make sure the 'count' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionCountTest() throws Exception {
+    buildELContext();
+
+    testIterable("count", "[1,2,3,4,5].stream().count()", new String[] { "5" });
+
+  } // End elCollectionCountTest()
+
+  /**
+   * @testName: elCollectionAverageTest
+   * 
+   * @assertion_ids: EL:SPEC:73; EL:SPEC:73.1
+   * 
+   * @test_Strategy: Test to make sure the 'average' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionAverageTest() throws Exception {
+
+    buildELContext();
+
+    this.testStream("average_ints", "ints.stream().average().get()",
+        Double.valueOf(4.5));
+
+  } // End elCollectionAverageTest()
+
+  /**
+   * @testName: elCollectionToArrayTest
+   * 
+   * @assertion_ids: EL:SPEC:68; EL:SPEC:68.1
+   * 
+   * @test_Strategy: Test to make sure the 'toArray' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionToArrayTest() throws Exception {
+    buildELContext();
+
+    String[] expr1 = { "Product: 200, Eagle, book, 12.5, 100",
+        "Product: 205, iSee, book, 12.5, 150",
+        "Product: 203, History of Golf, book, 11.0, 30",
+        "Product: 202, Greatest Hits, cd, 6.5, 200",
+        "Product: 204, Toy Story, dvd, 10.0, 1000",
+        "Product: 201, Coming Home, dvd, 8.0, 50" };
+
+    this.testArray("toArray",
+        "products.stream().sorted(p->p.unitPrice).toArray()", expr1);
+
+  }// End elCollectionToArrayTest()
+
+  /**
+   * @testName: elCollectionReduceTest
+   * 
+   * @assertion_ids: EL:SPEC:70; EL:SPEC:70.1; EL:SPEC:70.2; EL:SPEC:56.2;
+   *                 EL:SPEC:56.3
+   * 
+   * @test_Strategy: Test to make sure the 'reduce' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionReduceTest() throws Exception {
+    buildELContext();
+
+    testStream("reduce-one", "[1,2,3,4,5].stream().reduce(0, (l,r)->l+r)",
+        Long.valueOf(15));
+    testStream("reduce-two", "[1,2,3,4,5].stream().reduce((l,r)->l+r).get()",
+        Long.valueOf(15));
+    testStream("reduce-three", "[].stream().reduce((l,r)->l+r).orElse(101)",
+        Long.valueOf(101));
+    testStream("reduce-four",
+        "[].stream().reduce((l,r)->l+r).orElseGet(()->101)", Long.valueOf(101));
+    testStream("reduce-five",
+        "c = 0; [1,2,3,4,5,6].stream().reduce(0, (l,r)->(c = c+1; "
+            + "c % 2 == 0? l+r: l-r))",
+        Long.valueOf(3));
+
+  }// End elCollectionReduceTest()
+
+  /**
+   * @testName: elCollectionSubStreamTest
+   * 
+   * @assertion_ids: EL:SPEC:67; EL:SPEC:67.1; EL:SPEC:67.2
+   * 
+   * @test_Strategy: Test to make sure the 'substream' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionSubStreamTest() throws Exception {
+    buildELContext();
+
+    String[] expr1 = { "2", "3", "4" };
+
+    testIterable("substream-one", "[0,1,2,3,4].stream().substream(2).toList()",
+        expr1);
+    testIterable("substream-two",
+        "[0,1,2,3,4,5,6].stream().substream(2,5).toList()", expr1);
+
+  }// End elCollectionSubStreamTest()
+
+  /**
+   * @testName: elCollectionPeekTest
+   * 
+   * @assertion_ids: EL:SPEC:4; EL:SPEC:64.1
+   * 
+   * @test_Strategy: Test to make sure the 'peek' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionPeekTest() throws Exception {
+    buildELContext();
+
+    String expr1[] = { "1", "2", "3", "4" };
+
+    testIterable("peek-one",
+        "lst = []; [1,2,3,4].stream().peek(i->lst.add(i)).toList()", expr1);
+    testIterable("peek-two", "lst.stream().toList()", expr1);
+
+  }// End elCollectionPeekTest()
+
+  /**
+   * @testName: elCollectionFlatMapTest
+   * 
+   * @assertion_ids: EL:SPEC:60; EL:SPEC:60.1
+   * 
+   * @test_Strategy: Test to make sure the 'flatMap' operator works properly.
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elCollectionFlatMapTest() throws Exception {
+    buildELContext();
+
+    String[] expr1 = { "Order: 10, 100, 2/18/2010, 20.8",
+        "Order: 11, 100, 5/3/2011, 34.5", "Order: 12, 100, 8/2/2011, 210.75",
+        "Order: 13, 101, 1/15/2011, 50.23",
+        "Order: 14, 101, 1/3/2012, 126.77" };
+
+    testIterable("flatMap",
+        "customers.stream().filter(c->c.country=='USA').flatMap("
+            + "c->c.orders.stream()).toList()",
+        expr1);
+
+  }// End elCollectionFlatMapTest()
+
+  
+  /**
+   * @testName: elCollectionSetLiteralTest
+   * @assertion_ids: EL:SPEC:51; EL:SPEC:51.1; EL:SPEC:51.2; EL:SPEC:51.3;
+   * @test+Strategy: Verify that a value in a literal List constructed from
+   *                 variables can be retrieved using the associated index.
+   */
+  @Test
+  public void elCollectionSetLiteralTest() throws Exception {
+    boolean pass = false;
+    
+    try {
+      ELProcessor elp = new ELProcessor();
+      
+      String valueA = "myValueA";
+      String valueB = "myValueB";
+      
+      elp.setVariable("aaa", "'" + valueA + "'");
+      elp.setVariable("bbb", "'" + valueB + "'");
+      
+      Boolean result = (Boolean) elp.eval("{aaa,bbb}.contains(aaa)");
+      
+      pass = result.booleanValue();
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Construction and use of a valid Set literal threw an Exception!" +
+          ELTestUtil.NL + "Received: " + e.toString() + ELTestUtil.NL);
+
+      e.printStackTrace();
+    }
+    
+    if (!pass) {
+      throw new Exception("TEST FAILED!");
+    }
+  }
+  
+  
+  /**
+   * @testName: elCollectionListLiteralTest
+   * @assertion_ids: EL:SPEC:52; EL:SPEC:52.1; EL:SPEC:52.2; EL:SPEC:52.3;
+   * @test+Strategy: Verify that a value in a literal List constructed from
+   *                 variables can be retrieved using the associated index.
+   */
+  @Test
+  public void elCollectionListLiteralTest() throws Exception {
+    boolean pass = false;
+    
+    try {
+      ELProcessor elp = new ELProcessor();
+      
+      String valueA = "myValueA";
+      String valueB = "myValueB";
+      
+      elp.setVariable("aaa", "'" + valueA + "'");
+      elp.setVariable("bbb", "'" + valueB + "'");
+      
+      Object result = elp.eval("[aaa,bbb].get(1)");
+      
+      pass = valueB.equals(result);
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Construction and use of a valid List literal threw an Exception!" +
+          ELTestUtil.NL + "Received: " + e.toString() + ELTestUtil.NL);
+
+      e.printStackTrace();
+    }
+    
+    if (!pass) {
+      throw new Exception("TEST FAILED!");
+    }
+  }
+  
+  
+  /**
+   * @testName: elCollectionMapLiteralTest
+   * @assertion_ids: EL:SPEC:53; EL:SPEC:53.1; EL:SPEC:53.2; EL:SPEC:53.3;
+   * @test+Strategy: Verify that a value in a literal Map constructed from
+   *                 variables can be retrieved using the associated key.
+   */
+  @Test
+  public void elCollectionMapLiteralTest() throws Exception {
+    boolean pass = false;
+    
+    try {
+      ELProcessor elp = new ELProcessor();
+      
+      String key = "myKey";
+      String value = "myValue";
+      
+      elp.setVariable("aaa", "'" + key + "'");
+      elp.setVariable("bbb", "'" + value + "'");
+      
+      Object result = elp.eval("{aaa:bbb}.get(aaa)");
+      
+      pass = value.equals(result);
+    } catch (Exception e) {
+      pass = false;
+      logger.log(Logger.Level.ERROR, "Construction and use of a valid Map literal threw an Exception!" +
+          ELTestUtil.NL + "Received: " + e.toString() + ELTestUtil.NL);
+
+      e.printStackTrace();
+    }
+    
+    if (!pass) {
+      throw new Exception("TEST FAILED!");
+    }
+  }
+  
+  
+  // --------------------------- private methods
+
+  private void logLine(String s) {
+    logger.log(Logger.Level.INFO, s);
+  }
+
+  private void buildELContext() {
+    elp = new ELProcessor();
+    database = new DataBase();
+
+    database.init();
+    elp.defineBean("customers", database.getCustomers());
+    elp.defineBean("products", database.getProducts());
+    elp.defineBean("orders", database.getOrders());
+    elp.defineBean("ints", database.getInts());
+  }
+
+  /**
+   * Test a Collection query that returns an Iterable.
+   * 
+   * @param name
+   *          The Name of the test
+   * @param query
+   *          The EL query string
+   * @param expected
+   *          The expected result of the Iterable. The array element should
+   *          equal the Iterable element, when enumerated.
+   */
+  private void testIterable(String name, String query, String[] expected)
+      throws Exception {
+    String result;
+    String golden;
+    int explength = 0;
+
+    if (expected != null) {
+      explength = expected.length;
+    }
+
+    logLine("=== Testing " + name + " ===");
+    logLine(query);
+    Object ret = elp.eval(query);
+    int indx = 0;
+    logLine(" = returns =");
+
+    if (expected == null) {
+
+      if (!(ret == null)) {
+        throw new Exception("TEST FAILED, Unexpected Value!" + ELTestUtil.NL
+            + "Expected: null");
+
+      } else {
+        logLine(" null ");
+      }
+
+    } else if (expected.length == 1) {
+      golden = expected[0];
+      result = ret.toString();
+      logLine(" " + result);
+
+      if (!golden.equals(result)) {
+        throw new Exception("TEST FAILED, Unexpected Value!" + ELTestUtil.NL
+            + "Expected: " + golden + ELTestUtil.NL + "Received: " + result);
+      }
+
+    } else {
+      for (Object item : (Iterable<?>) ret) {
+        result = item.toString();
+        golden = expected[indx++];
+        logLine(" " + result);
+
+        if (!golden.equals(result)) {
+          throw new Exception("TEST FAILED, Unexpected Value!" + ELTestUtil.NL
+              + "Expected: " + golden + ELTestUtil.NL + "Received: " + result);
+        }
+      }
+
+      if (indx != explength) {
+        throw new Exception(ELTestUtil.FAIL + " lenght incorrect!" + ELTestUtil.NL
+            + "Expected: " + explength + ELTestUtil.NL + "Found: " + indx);
+      }
+    }
+  }
+
+  /**
+   * 
+   * @param name
+   *          The Name of the test.
+   * 
+   * @param query
+   *          The EL query string
+   * @param expected
+   *          The expected boolean value for the given query.
+   * 
+   * @throws Exception
+   */
+  private void testIterable(String name, String query, Boolean expected)
+      throws Exception {
+
+    this.testIterable(name, query, new String[] { expected.toString() });
+  }
+
+  /**
+   * Test a Collection query that returns a Array
+   * 
+   * @param name
+   *          The Name of the test
+   * @param query
+   *          The EL query string
+   * @param expected
+   *          The expected result of the Array. The element of the expected
+   *          array should equals the resulted array.
+   */
+  private void testArray(String name, String query, String[] expected)
+      throws Exception {
+    logLine("=== Test " + name + "===");
+    logLine(query);
+
+    Object arry = elp.eval(query);
+    String item;
+    String golden;
+
+    int gldLength = Array.getLength(arry);
+    logLine(" = returns =");
+
+    if (gldLength != expected.length) {
+      throw new Exception(
+          ELTestUtil.FAIL + " lenght incorrect!" + ELTestUtil.NL + "Expected: "
+              + expected.length + ELTestUtil.NL + "Found: " + gldLength);
+    }
+
+    for (int indx = 0; gldLength < indx; indx++) {
+      item = (String) Array.get(arry, indx);
+      golden = expected[indx];
+
+      if (item.equals(golden)) {
+        logLine(" " + item);
+
+      } else {
+        throw new Exception(ELTestUtil.FAIL + ELTestUtil.NL + "Expected: " + item
+            + ELTestUtil.NL + "Received: " + golden);
+      }
+    }
+
+  }
+
+  private void testStream(String name, String query, Object exp_value)
+      throws Exception {
+
+    logLine("=== Testing " + name + " ===");
+
+    Object result = elp.eval(query);
+    logLine("EL Quuery String: '" + query + "' -returns: " + result + "("
+        + result.getClass() + ")");
+
+    // Test expected value.
+    if (!exp_value.equals(result)) {
+      throw new Exception(ELTestUtil.FAIL + ELTestUtil.NL + "Expected: " + exp_value
+          + ELTestUtil.NL + "Received: " + result);
+    }
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/concatoperator/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/concatoperator/ELClientIT.java
new file mode 100644
index 0000000..d257385
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/concatoperator/ELClientIT.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2013, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.concatoperator;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.util.TestNum;
+import com.sun.ts.tests.el.common.util.Validator;
+
+import jakarta.el.ELProcessor;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: elBigDecimalConcatenationTest
+   * 
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * 
+   * @test_Strategy: Validate that if one of the operands is BigDecimal that the
+   *                 operator is '+=' that both operands are coerced to type
+   *                 String and concatenated.
+   * 
+   *                 Equations tested: BigDecimal += BigDecimal BigDecimal +=
+   *                 Double BigDecimal += Float BigDecimal += String
+   *                 containing".", "e", or "E" BigDecimal += BigInteger
+   *                 BigDecimal += Integer BigDecimal += Long BigDecimal +=
+   *                 Short BigDecimal += Byte
+   */
+  @Test
+  public void elBigDecimalConcatenationTest() throws Exception {
+
+    BigDecimal testValue = BigDecimal.valueOf(10.531);
+    /*
+     * The expected result is actually computed in the testBigDecimal method for
+     * the '+=' operator!
+     */
+    Validator.testBigDecimal(testValue, null, "+=");
+
+  }
+
+  /**
+   * @testName: elBigIntegerConcatenationTest
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * @test_Strategy: Validate that if one of the operands is BigInteger that the
+   *                 operator is '+=' that both operands are coerced to type
+   *                 String and concatenated.
+   * 
+   *                 Equations tested: BigInteger += BigInteger BigInteger +=
+   *                 Integer BigInteger += Long BigInteger += Short BigInteger
+   *                 += Byte
+   */
+  @Test
+  public void elBigIntegerConcatenationTest() throws Exception {
+
+    BigInteger testValue = BigInteger.valueOf(10531);
+    /*
+     * The expected result is actually computed in the testBigInteger method for
+     * the '+=' operator!
+     */
+    Validator.testBigInteger(testValue, null, "+=");
+
+  }
+
+  /**
+   * @testName: elFloatConcatenationTest
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * @test_Strategy: Validate when the operator is '+=' that the operands are
+   *                 coerced to Strings and the result is a Concatenation.
+   * 
+   *                 Equations tested: Float + Double Float + Float Float +
+   *                 String containing ".", "e", or "E" Float + BigInteger Float
+   *                 + Integer Float + Long Float + Short Float + Byte
+   */
+  @Test
+  public void elFloatConcatenationTest() throws Exception {
+
+    // For each float in this List.
+    for (Iterator<?> it = TestNum.getFloatList().iterator(); it.hasNext();) {
+      Float testValue = (Float) it.next();
+      /*
+       * The expected result is actually computed in the testFloat method for
+       * the '+=' operator!
+       */
+      Validator.testFloat(testValue, null, "+=");
+    }
+
+  }
+
+  /**
+   * @testName: elDoubleConcatenationTest
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * @test_Strategy: Validate when the operator is '+=' that the operands are
+   *                 coerced to Strings and the result is a Concatenation.
+   * 
+   *                 Equations tested: Double += Double Double += String
+   *                 containing ".", "e", or "E" Double += BigInteger Double +=
+   *                 Integer Double += Long Double += Short Double += Byte
+   */
+  @Test
+  public void elDoubleConcatenationTest() throws Exception {
+
+    Double testValue = Double.valueOf(2.5);
+    /*
+     * The expected result is actually computed in the testDouble method for the
+     * '+=' operator!
+     */
+    Validator.testDouble(testValue, null, "+=");
+
+  }
+
+  /**
+   * @testName: elLongConcatenationTest
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * @test_Strategy: Validate when the operator is '+=' that the operands are
+   *                 coerced to Strings and the result is a Concatenation.
+   * 
+   *                 Equations tested: Long += Integer Long += Long Long +=
+   *                 Short Long += Byte
+   */
+  @Test
+  public void elLongConcatenationTest() throws Exception {
+
+    Long testValue = Long.valueOf(25000);
+    /*
+     * The expected result is actually computed in the testLong method for the
+     * '+=' operator!
+     */
+    Validator.testLong(testValue, null, "+=");
+
+  }
+
+  /**
+   * @testName: elIntegerConcatenationTest
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * @test_Strategy: Validate when the operator is '+=' that the operands are
+   *                 coerced to Strings and the result is a Concatenation.
+   * 
+   *                 Equations tested: Integer += Integer Integer += Short
+   *                 Integer += Byte
+   */
+  @Test
+  public void elIntegerConcatenationTest() throws Exception {
+
+    Integer testValue = Integer.valueOf(25);
+    /*
+     * The expected result is actually computed in the testInteger method for
+     * the '+=' operator!
+     */
+    Validator.testInteger(testValue, null, "+=");
+
+  }
+
+  /**
+   * @testName: elShortConcatenationTest
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * @test_Strategy: Validate when the operator is '+=' that the operands are
+   *                 coerced to Strings and the result is a Concatenation.
+   * 
+   *                 Equations tested: Short += Short Short += Byte
+   */
+  @Test
+  public void elShortConcatenationTest() throws Exception {
+
+    Short testValue = Short.valueOf("2");
+    /*
+     * The expected result is actually computed in the testShort method for the
+     * '+=' operator!
+     */
+    Validator.testShort(testValue, null, "+=");
+
+  }
+
+  /**
+   * @testName: elByteConcatenationTest
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * @test_Strategy: Validate that if the operator is '+=' that both operands
+   *                 are coerced to String and the result is a Concatenation of
+   *                 the operands.
+   * 
+   *                 Equations tested: Byte += Byte
+   */
+  @Test
+  public void elByteConcatenationTest() throws Exception {
+
+    Byte testValue = Byte.valueOf("2");
+    /*
+     * The expected result is actually computed in the testByte method for the
+     * '+=' operator!
+     */
+    Validator.testByte(testValue, null, "+=");
+
+  }
+
+  /**
+   * @testName: elBooleanConcatenationTest
+   * @assertion_ids: EL:SPEC:38; EL:SPEC:47.1; EL:SPEC:47.1.1; EL:SPEC:47.1.2
+   * @test_Strategy: Validate when the operator is '+=' that both operands are
+   *                 coerced to Strings and that they result is a Concatenation
+   *                 of the operands.
+   * 
+   *                 Equations tested: Boolean += String Boolean += Boolean
+   * 
+   */
+  @Test
+  public void elBooleanConcatenationTest() throws Exception {
+
+    /*
+     * The expected result is actually computed in the testBoolean method for
+     * the '+=' operator!
+     */
+    Validator.testBoolean(false, "true", null, "+=");
+    Validator.testBoolean(false, true, null, "+=");
+
+  }
+
+  // ------------------------------------------------------- private methods
+  private void logLine(String s) {
+    logger.log(Logger.Level.TRACE, s);
+  }
+
+  /**
+   * Test a query for the correct value.
+   * 
+   * @param name
+   *          The Name of the test
+   * @param query
+   *          The EL query string
+   * @param expected
+   *          The expected result of the query.
+   */
+  private void testQuery(String name, String query, String expected)
+      throws Exception {
+    ELProcessor elp = new ELProcessor();
+
+    logLine("=== Testing " + name + " ===");
+    logLine(query);
+
+    logLine(" = returns =");
+    Object ret = elp.eval(query);
+
+    if (!expected.equals(ret.toString())) {
+
+      throw new Exception(
+          ELTestUtil.FAIL + "  Unexpected Value!" + ELTestUtil.NL + "Expected: "
+              + expected + ELTestUtil.NL + "Received: " + ret.toString());
+
+    }
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/conditionaloperator/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/conditionaloperator/ELClientIT.java
new file mode 100644
index 0000000..1d51df9
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/conditionaloperator/ELClientIT.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.conditionaloperator;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ExprEval;
+import com.sun.ts.tests.el.common.util.NameValuePair;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private final boolean[] deferred = { true, false };
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /*
+   * @testName: elConditionalStringTest
+   * 
+   * @assertion_ids: EL:SPEC:26.1.1; EL:SPEC:26.1.2
+   * 
+   * @test_Strategy: Validate that if a String is passed with the conditional
+   * operator, the type is coerced to Boolean and the operator is applied.
+   *
+   * Example Equation: ${true ? true : false}
+   */
+  @Test
+  public void elConditionalStringTest() throws Exception {
+
+    this.testConditionals("true", true);
+    this.testConditionals("false", false);
+
+  }
+
+  /*
+   * @testName: elConditionalBooleanTest
+   * 
+   * @assertion_ids: EL:SPEC:26.1.1; EL:SPEC:26.1.2
+   * 
+   * @test_Strategy: Validate that if a Boolean is passed with the conditional
+   * operator, that the operator is applied.
+   *
+   * Example Equation: ${true ? true : false}
+   */
+  @Test
+  public void elConditionalBooleanTest() throws Exception {
+
+    this.testConditionals(true, true);
+    this.testConditionals(false, false);
+
+  }
+
+  // ---------------------------------------------------------- private methods
+
+  private void testConditionals(String testVal, boolean expectedResult)
+      throws Exception {
+
+    boolean pass = false;
+
+    NameValuePair value[] = NameValuePair.buildConditionalNameValue(testVal,
+        true, false);
+
+    try {
+      for (boolean tf : deferred) {
+        String expr = ExprEval.buildElExpr(tf, "conditional");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && ExprEval.compareValue((Boolean) result, expectedResult));
+
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false");
+      }
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  private void testConditionals(boolean testVal, boolean expectedResult)
+      throws Exception {
+
+    boolean pass = false;
+
+    NameValuePair value[] = NameValuePair.buildConditionalNameValue(testVal,
+        true, false);
+
+    try {
+      for (boolean tf : deferred) {
+        String expr = ExprEval.buildElExpr(tf, "conditional");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && ExprEval.compareValue((Boolean) result, expectedResult));
+
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false");
+      }
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/emptyoperator/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/emptyoperator/ELClientIT.java
new file mode 100644
index 0000000..956c79d
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/emptyoperator/ELClientIT.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.emptyoperator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ExprEval;
+import com.sun.ts.tests.el.common.util.NameValuePair;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private final boolean[] deferred = { true, false };
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /*
+   * @testName: elEmptyNullTest
+   * 
+   * @assertion_ids: EL:SPEC:25.1
+   * 
+   * @test_Strategy: Validate that if "null" is passed with the Empty operator,
+   * the correct Boolean result is returned.
+   */
+  @Test
+  public void elEmptyNullTest() throws Exception {
+
+    boolean pass = false;
+
+    String[] symbols = { "$", "#" };
+    boolean expectedResult = true;
+
+    try {
+      for (String prefix : symbols) {
+        String expr = prefix + "{empty null}";
+        Object result = ExprEval.evaluateValueExpression(expr, null,
+            Object.class);
+
+        if (result == null) {
+          logger.log(Logger.Level.TRACE, "result is null");
+        } else {
+          logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        }
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && ExprEval.compareValue((Boolean) result, expectedResult));
+
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false");
+      }
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+  }
+
+  /*
+   * @testName: elEmptyStringTest
+   * 
+   * @assertion_ids: EL:SPEC:25.2; EL:SPEC:25.6
+   * 
+   * @test_Strategy: Validate that if a String is passed with the Empty
+   * operator, the correct Boolean result is returned.
+   */
+  @Test
+  public void elEmptyStringTest() throws Exception {
+
+    this.testEmptyOperator("", true);
+
+    this.testEmptyOperator("something", false);
+
+  }
+
+  /*
+   * @testName: elEmptyArrayTest
+   * 
+   * @assertion_ids: EL:SPEC:25.3; EL:SPEC:25.6
+   * 
+   * @test_Strategy: Validate that if a Array is passed with the Empty operator,
+   * the correct Boolean result is returned.
+   */
+  @Test
+  public void elEmptyArrayTest() throws Exception {
+
+    this.testEmptyOperator(new String[0], true);
+
+    String[] testArray = { "Apple" };
+    this.testEmptyOperator(testArray, false);
+
+  }
+
+  /*
+   * @testName: elEmptyMapTest
+   * 
+   * @assertion_ids: EL:SPEC:25.4; EL:SPEC:25.6
+   * 
+   * @test_Strategy: Validate that if a Map is passed with the Empty operator,
+   * the correct Boolean result is returned.
+   */
+  @Test
+  public void elEmptyMapTest() throws Exception {
+
+    HashMap testMap = new HashMap();
+
+    this.testEmptyOperator(testMap, true);
+
+    testMap.put("Fruit", "Apple");
+    this.testEmptyOperator(testMap, false);
+
+    // Clean out the Map.
+    testMap.clear();
+  }
+
+  /*
+   * @testName: elEmptyCollectionTest
+   * 
+   * @assertion_ids: EL:SPEC:25.5; EL:SPEC:25.6
+   * 
+   * @test_Strategy: Validate that if a Collection is passed with the Empty
+   * operator, the correct Boolean result is returned.
+   */
+  @Test
+  public void elEmptyCollectionTest() throws Exception {
+
+    ArrayList testCollection = new ArrayList();
+
+    this.testEmptyOperator(testCollection, true);
+
+    testCollection.add("Apple");
+    this.testEmptyOperator(testCollection, false);
+
+    // Clean out the Collection.
+    testCollection.clear();
+  }
+
+  // ---------------------------------------------------------- private methods
+
+  // Test Empty operator.
+  private void testEmptyOperator(Object testVal, boolean expectedResult)
+      throws Exception {
+
+    boolean pass = false;
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(testVal);
+
+    try {
+      for (boolean tf : deferred) {
+        String expr = ExprEval.buildElExpr(tf, "empty");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && ExprEval.compareValue((Boolean) result, expectedResult));
+
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false");
+      }
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/lambda/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/lambda/ELClientIT.java
new file mode 100644
index 0000000..20246a4
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/lambda/ELClientIT.java
@@ -0,0 +1,904 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.lambda;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.TypesBean;
+import com.sun.ts.tests.el.common.util.Validator;
+
+import jakarta.el.ELProcessor;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+@AfterEach
+public void cleanup() throws Exception {
+  logger.log(Logger.Level.INFO, "Cleanup method called");
+}
+
+@BeforeEach
+void logStartTest(TestInfo testInfo) {
+  logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+}
+
+@AfterEach
+void logFinishTest(TestInfo testInfo) {
+  logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+}
+
+
+  /**
+   * @testName: elLambdaExprBigDecimalTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expressions: "(((x, y)-> x [operator] y)(a, b))", "z =
+   *                 (x,y)->x [operator] y" "z(a, b)", "func = (x,y)->x
+   *                 [operator] y; func(a, b)", "(cond->[true/false]? a
+   *                 [operator] b: a [operator] 2)(a)"
+   * 
+   *                 Variable A - BigDecimal
+   * 
+   *                 Variable B - Rotating through the following types:
+   *                 BigDecimal, BigInteger, Integer, Float, Long, Short,
+   *                 Double, Byte
+   * 
+   *                 Excluded: none
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprBigDecimalTest() throws Exception {
+    String comparitorA = "BigDecimal";
+
+    Iterator<Class<?>> iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      // (+ operator)
+      this.runLambdaExpressions("+", BigDecimal.valueOf(2), comparitorA, bValue,
+          bName);
+
+      // (- operator)
+      this.runLambdaExpressions("-", BigDecimal.valueOf(0), comparitorA, bValue,
+          bName);
+
+      // (* operator)
+      this.runLambdaExpressions("*", BigDecimal.valueOf(1), comparitorA, bValue,
+          bName);
+
+      // (/ operator)
+      this.runLambdaExpressions("/", BigDecimal.valueOf(1), comparitorA, bValue,
+          bName);
+
+      // (div operator)
+      this.runLambdaExpressions("div", BigDecimal.valueOf(1), comparitorA,
+          bValue, bName);
+
+      // (% operator)
+      this.runLambdaExpressions("%", Double.valueOf(0), comparitorA, bValue,
+          bName);
+
+      // (mod operator)
+      this.runLambdaExpressions("mod", Double.valueOf(0), comparitorA, bValue,
+          bName);
+    }
+
+  } // End elLambdaExprBigDecimalTest
+
+  /**
+   * @testName: elLambdaExprFloatTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expressions: "(((x, y)-> x [operator] y)(a, b))", "z =
+   *                 (x,y)->x [operator] y" "z(a, b)", "func = (x,y)->x
+   *                 [operator] y; func(a, b)", "(cond->[true/false]? a
+   *                 [operator] b: a [operator] 2)(a)"
+   * 
+   *                 Variable A - Float
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprFloatTest() throws Exception {
+    String comparitorA = "Float";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+
+    Iterator<Class<?>> iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if (excludeList.contains(bName)) {
+        logger.log(Logger.Level.INFO, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+
+        if ("BigInteger".equals(bName)) {
+          // (+ operator)
+          this.runLambdaExpressions("+", BigDecimal.valueOf(2), comparitorA,
+              bValue, bName);
+
+          // (- operator)
+          this.runLambdaExpressions("-", BigDecimal.valueOf(0), comparitorA,
+              bValue, bName);
+
+          // (* operator)
+          this.runLambdaExpressions("*", BigDecimal.valueOf(1), comparitorA,
+              bValue, bName);
+
+          // (/ operator)
+          this.runLambdaExpressions("/", BigDecimal.valueOf(1), comparitorA,
+              bValue, bName);
+
+          // (div operator)
+          this.runLambdaExpressions("div", BigDecimal.valueOf(1), comparitorA,
+              bValue, bName);
+
+        } else {
+          // (+ operator)
+          this.runLambdaExpressions("+", Double.valueOf(2), comparitorA, bValue,
+              bName);
+
+          // (- operator)
+          this.runLambdaExpressions("-", Double.valueOf(0), comparitorA, bValue,
+              bName);
+
+          // (* operator)
+          this.runLambdaExpressions("*", Double.valueOf(1), comparitorA, bValue,
+              bName);
+
+          // (/ operator)
+          this.runLambdaExpressions("/", Double.valueOf(1), comparitorA, bValue,
+              bName);
+
+          // (div operator)
+          this.runLambdaExpressions("div", Double.valueOf(1), comparitorA,
+              bValue, bName);
+
+        }
+
+        /*
+         * The same for all other tested data types.
+         */
+
+        // (% operator)
+        this.runLambdaExpressions("%", Double.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (mod operator)
+        this.runLambdaExpressions("mod", Double.valueOf(0), comparitorA, bValue,
+            bName);
+      }
+    }
+
+  } // End elLambdaExprFloatTest
+
+  /**
+   * @testName: elLambdaExprDoubleTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expressions: "(((x, y)-> x [operator] y)(a, b))", "z =
+   *                 (x,y)->x [operator] y" "z(a, b)", "func = (x,y)->x
+   *                 [operator] y; func(a, b)", "(cond->[true/false]? a
+   *                 [operator] b: a [operator] 2)(a)"
+   * 
+   *                 Variable A - Double
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, Float
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprDoubleTest() throws Exception {
+    String comparitorA = "Double";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if (excludeList.contains(bName)) {
+        logger.log(Logger.Level.INFO, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        if ("BigInteger".equals(bName)) {
+          // (+ operator)
+          this.runLambdaExpressions("+", BigDecimal.valueOf(2), comparitorA,
+              bValue, bName);
+
+          // (- operator)
+          this.runLambdaExpressions("-", BigDecimal.valueOf(0), comparitorA,
+              bValue, bName);
+
+          // (* operator)
+          this.runLambdaExpressions("*", BigDecimal.valueOf(1), comparitorA,
+              bValue, bName);
+
+          // (/ operator)
+          this.runLambdaExpressions("/", BigDecimal.valueOf(1), comparitorA,
+              bValue, bName);
+
+          // (div operator)
+          this.runLambdaExpressions("div", BigDecimal.valueOf(1), comparitorA,
+              bValue, bName);
+
+        } else {
+          // (+ operator)
+          this.runLambdaExpressions("+", Double.valueOf(2), comparitorA, bValue,
+              bName);
+
+          // (- operator)
+          this.runLambdaExpressions("-", Double.valueOf(0), comparitorA, bValue,
+              bName);
+
+          // (* operator)
+          this.runLambdaExpressions("*", Double.valueOf(1), comparitorA, bValue,
+              bName);
+
+          // (/ operator)
+          this.runLambdaExpressions("/", Double.valueOf(1), comparitorA, bValue,
+              bName);
+
+          // (div operator)
+          this.runLambdaExpressions("div", Double.valueOf(1), comparitorA,
+              bValue, bName);
+
+        }
+
+        /*
+         * The same for all other tested data types.
+         */
+
+        // (% operator)
+        this.runLambdaExpressions("%", Double.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (mod operator)
+        this.runLambdaExpressions("mod", Double.valueOf(0), comparitorA, bValue,
+            bName);
+      }
+    }
+
+  } // End elLambdaExprDoubleTest
+
+  /**
+   * @testName: elLambdaExprBigIntegerTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expressions: "(((x, y)-> x [operator] y)(a, b))", "z =
+   *                 (x,y)->x [operator] y" "z(a, b)"
+   * 
+   *                 Variable A - BigInteger
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, Float, Double
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprBigIntegerTest() throws Exception {
+    String comparitorA = "BigInteger";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.INFO, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        // (+ operator)
+        this.runLambdaExpressions("+", BigInteger.valueOf(2), comparitorA,
+            bValue, bName);
+
+        // (- operator)
+        this.runLambdaExpressions("-", BigInteger.valueOf(0), comparitorA,
+            bValue, bName);
+
+        // (* operator)
+        this.runLambdaExpressions("*", BigInteger.valueOf(1), comparitorA,
+            bValue, bName);
+
+        // (/ operator)
+        this.runLambdaExpressions("/", BigDecimal.valueOf(1), comparitorA,
+            bValue, bName);
+
+        // (div operator)
+        this.runLambdaExpressions("div", BigDecimal.valueOf(1), comparitorA,
+            bValue, bName);
+
+        // (% operator)
+        this.runLambdaExpressions("%", BigInteger.valueOf(0), comparitorA,
+            bValue, bName);
+
+        // (mod operator)
+        this.runLambdaExpressions("mod", BigInteger.valueOf(0), comparitorA,
+            bValue, bName);
+      }
+    }
+
+  } // End elLambdaExprBigIntegerTest
+
+  /**
+   * @testName: elLambdaExprIntegerTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expressions: "(((x, y)-> x [operator] y)(a, b))", "z =
+   *                 (x,y)->x [operator] y" "z(a, b)"
+   * 
+   *                 Variable A - Integer
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprIntegerTest() throws Exception {
+    String comparitorA = "Integer";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.INFO, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        // (+ operator)
+        this.runLambdaExpressions("+", Long.valueOf(2), comparitorA, bValue,
+            bName);
+
+        // (- operator)
+        this.runLambdaExpressions("-", Long.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (* operator)
+        this.runLambdaExpressions("*", Long.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (/ operator)
+        this.runLambdaExpressions("/", Double.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (div operator)
+        this.runLambdaExpressions("div", Double.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (% operator)
+        this.runLambdaExpressions("%", Long.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (mod operator)
+        this.runLambdaExpressions("mod", Long.valueOf(0), comparitorA, bValue,
+            bName);
+      }
+    }
+
+  } // End elLambdaExprIntegerTest
+
+  /**
+   * @testName: elLambdaExprLongTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expressions: "(((x, y)-> x [operator] y)(a, b))", "z =
+   *                 (x,y)->x [operator] y" "z(a, b)"
+   * 
+   *                 Variable A - Long
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprLongTest() throws Exception {
+    String comparitorA = "Long";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.INFO, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        // (+ operator)
+        this.runLambdaExpressions("+", Long.valueOf(2), comparitorA, bValue,
+            bName);
+
+        // (- operator)
+        this.runLambdaExpressions("-", Long.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (* operator)
+        this.runLambdaExpressions("*", Long.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (/ operator)
+        this.runLambdaExpressions("/", Double.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (div operator)
+        this.runLambdaExpressions("div", Double.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (% operator)
+        this.runLambdaExpressions("%", Long.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (mod operator)
+        this.runLambdaExpressions("mod", Long.valueOf(0), comparitorA, bValue,
+            bName);
+      }
+    }
+
+  } // End elLambdaExprLongTest
+
+  /**
+   * @testName: elLambdaExprShortTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expressions: "(((x, y)-> x [operator] y)(a, b))", "z =
+   *                 (x,y)->x [operator] y" "z(a, b)"
+   * 
+   *                 Variable A - Short
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer,
+   *                 Long
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprShortTest() throws Exception {
+    String comparitorA = "Short";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+    excludeList.add("Long");
+
+    Iterator<Class<?>> iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.INFO, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        // (+ operator)
+        this.runLambdaExpressions("+", Long.valueOf(2), comparitorA, bValue,
+            bName);
+
+        // (- operator)
+        this.runLambdaExpressions("-", Long.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (* operator)
+        this.runLambdaExpressions("*", Long.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (/ operator)
+        this.runLambdaExpressions("/", Double.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (div operator)
+        this.runLambdaExpressions("div", Double.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (% operator)
+        this.runLambdaExpressions("%", Long.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (mod operator)
+        this.runLambdaExpressions("mod", Long.valueOf(0), comparitorA, bValue,
+            bName);
+      }
+    }
+
+  } // End elLambdaExprShortTest
+
+  /**
+   * @testName: elLambdaExprByteTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expressions: "(((x, y)-> x [operator] y)(a, b))", "z =
+   *                 (x,y)->x [operator] y" "z(a, b)"
+   * 
+   *                 Variable A - Byte
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer,
+   *                 Long, Short
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprByteTest() throws Exception {
+    String comparitorA = "Byte";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+    excludeList.add("Long");
+    excludeList.add("Short");
+
+    Iterator<Class<?>> iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.INFO, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        // (+ operator)
+        this.runLambdaExpressions("+", Long.valueOf(2), comparitorA, bValue,
+            bName);
+
+        // (- operator)
+        this.runLambdaExpressions("-", Long.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (* operator)
+        this.runLambdaExpressions("*", Long.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (/ operator)
+        this.runLambdaExpressions("/", Double.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (div operator)
+        this.runLambdaExpressions("div", Double.valueOf(1), comparitorA, bValue,
+            bName);
+
+        // (% operator)
+        this.runLambdaExpressions("%", Long.valueOf(0), comparitorA, bValue,
+            bName);
+
+        // (mod operator)
+        this.runLambdaExpressions("mod", Long.valueOf(0), comparitorA, bValue,
+            bName);
+      }
+    }
+
+  } // End elLambdaExprByteTest
+
+  /**
+   * @testName: elLambdaExprStringTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +
+   * 
+   *                 Expression: "(((x, y)-> x cat y)(a, b))"
+   * 
+   *                 Variable A - String
+   * 
+   *                 Variable B - String
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprStringTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+
+    String aValue = "a='Testing'";
+    String bValue = "b='Testing'";
+
+    elp.eval(aValue);
+    elp.eval(bValue);
+
+    // (+= operator)
+    Validator.testExpression(elp, "(((x, y)-> x += y)(a, b))", "TestingTesting",
+        "'Testing' += 'Testing'");
+
+  } // End elLambdaExprStringTest
+
+  /**
+   * @testName: elLambdaExprNullTest
+   * 
+   * @assertion_ids: EL:SPEC:50.1; EL:SPEC:50.2; EL:SPEC:50.3; EL:SPEC:50.4;
+   *                 EL:SPEC:50.5; EL:SPEC:50.6; EL:JAVADOC:212
+   * 
+   * @test_Strategy: Evaluate the Lambda Expression, making sure the coercion
+   *                 rules are followed.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "(((x, y)-> x [operator] y)(a, b))"
+   * 
+   *                 Variable A - null
+   * 
+   *                 Variable B - null
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elLambdaExprNullTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    elp.defineBean("types", new TypesBean());
+
+    Long expected = Long.valueOf(0);
+    String aValue = "a = types.tckNull";
+    String bValue = "b = types.tckNull";
+
+    elp.eval(aValue);
+    elp.eval(bValue);
+    String operator;
+
+    // (+ operator)
+    operator = "+";
+    Validator.testExpression(elp, "(((x, y)-> x " + operator + " y)(a, b))",
+        expected, "null + null");
+
+    // (- operator)
+    operator = "-";
+    Validator.testExpression(elp, "(((x, y)-> x " + operator + " y)(a, b))",
+        expected, "null - null");
+
+    // (* operator)
+    operator = "*";
+    Validator.testExpression(elp, "(((x, y)-> x " + operator + " y)(a, b))",
+        expected, "null * null");
+
+    // (/ operator)
+    operator = "/";
+    Validator.testExpression(elp, "(((x, y)-> x " + operator + " y)(a, b))",
+        expected, "null / null");
+
+    // (div operator)
+    operator = "div";
+    Validator.testExpression(elp, "(((x, y)-> x " + operator + " y)(a, b))",
+        expected, "null div null");
+
+    // (% operator)
+    operator = "%";
+    Validator.testExpression(elp, "(((x, y)-> x " + operator + " y)(a, b))",
+        expected, "null % null");
+
+    // (mod operator)
+    operator = "mod";
+    Validator.testExpression(elp, "(((x, y)-> x " + operator + " y)(a, b))",
+        expected, "null mod null");
+
+  } // End elLambdaExprNullTest
+
+  // ----------------------------- private methods.
+
+  private void runLambdaExpressions(String operator, Number expectedResult,
+      String aType, String comparitorB, String bName) throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    elp.defineBean("types", new TypesBean());
+
+    String comparitorA = "a=types.tck" + aType;
+
+    elp.eval(comparitorA);
+    elp.eval(comparitorB);
+
+    Validator.testExpression(elp, "(x->(y->x " + operator + " y)(a))(b)",
+        expectedResult, aType + " " + operator + " " + bName);
+
+    Validator.testExpression(elp, "(()->y->y " + operator + " a)()(b)",
+        expectedResult, aType + " " + operator + " " + bName);
+
+    Validator.testExpression(elp,
+        "f = (x)->(tem=x; y->tem " + operator + " y); f(a)(b)", expectedResult,
+        aType + " " + operator + " " + bName);
+
+    Validator.testExpression(elp, "f = ()->y->y " + operator + " a; f()(b)",
+        expectedResult, aType + " " + operator + " " + bName);
+
+    Validator.testExpression(elp,
+        "f = (x)->(tem=x; y->tem " + operator + " y); f(a)(b)", expectedResult,
+        aType + " " + operator + " " + bName);
+
+    Validator.testExpression(elp, "(((x, y)-> x " + operator + " y)(a, b))",
+        expectedResult, aType + " " + operator + " " + bName);
+
+    String zValue = "z = (x,y)->x " + operator + " y";
+    elp.eval(zValue);
+    Validator.testExpression(elp, "z(a, b)", expectedResult,
+        aType + " " + operator + " " + bName);
+
+    Validator.testExpression(elp,
+        "func = (x,y)->x " + operator + " y; func(a, b)", expectedResult,
+        aType + " " + operator + " " + bName);
+
+    elp.eval("cond = true");
+    Validator.testExpression(elp,
+        "(cond->true? a " + operator + " b: a " + operator + " 2)(a)",
+        expectedResult, aType + " " + operator + " " + bName);
+
+    elp.eval("cond = false");
+    Validator.testExpression(elp,
+        "(cond->false? a " + operator + " 2: a " + operator + " b)(a)",
+        expectedResult, aType + " " + operator + " " + bName);
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/language/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/language/ELClientIT.java
new file mode 100644
index 0000000..7824aef
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/language/ELClientIT.java
@@ -0,0 +1,611 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.language;
+
+import java.util.Hashtable;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.spec.Book;
+import com.sun.ts.tests.el.common.util.ExprEval;
+import com.sun.ts.tests.el.common.util.ResolverType;
+
+import jakarta.el.ELException;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private static String NLINE = System.getProperty("line.separator", "\n");
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  // ------------------------------------------------------------- Test Methods
+
+  /*
+   * @testName: poundDollarSameMeaning1Test
+   * 
+   * @assertion_ids: EL:SPEC:1
+   * 
+   * @test_Strategy: Confirm that two EL expressions, identical except for the
+   * '$' and '#' delimiters, are evaluated the same. Case 1: base is null.
+   */
+  @Test
+  public void poundDollarSameMeaning1Test() throws Exception {
+
+    boolean pass = true;
+
+    String testExpr = "\"foo\"";
+
+    try {
+      Object dollarResult = ExprEval
+          .evaluateValueExpression("${" + testExpr + "}", null, String.class);
+      Object poundResult = ExprEval
+          .evaluateValueExpression("#{" + testExpr + "}", null, String.class);
+
+      logger.log(Logger.Level.TRACE, "Comparing  ${" + dollarResult.toString() + "} "
+          + "to #{" + poundResult.toString() + "}");
+
+      pass = (ExprEval.compareClass(poundResult, String.class)
+          && ExprEval.compareClass(dollarResult, String.class)
+          && ExprEval.compareValue(poundResult, dollarResult));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: poundDollarSameMeaning2Test
+   * 
+   * @assertion_ids: EL:SPEC:1
+   * 
+   * @test_Strategy: Confirm that two EL expressions, identical except for the
+   * '$' and '#' delimiters, are evaluated the same. Case 2: base is non-null.
+   */
+  @Test
+  public void poundDollarSameMeaning2Test() throws Exception {
+
+    boolean pass = true;
+
+    try {
+      Object firstNameDollar = ExprEval.evaluateValueExpression(
+          "${worker.firstName}", null, String.class,
+          ResolverType.EMPLOYEE_ELRESOLVER);
+
+      Object firstNamePound = ExprEval.evaluateValueExpression(
+          "#{worker.firstName}", null, String.class,
+          ResolverType.EMPLOYEE_ELRESOLVER);
+
+      logger.log(Logger.Level.TRACE, "Comparing  ${" + firstNameDollar.toString() + "} to #{"
+          + firstNamePound.toString() + "}");
+
+      if (!(firstNamePound.toString().equals(firstNameDollar.toString()))) {
+
+        logger.log(Logger.Level.TRACE, 
+            "Dollar & Pound symbols return different" + "expression values!");
+        pass = false;
+
+      }
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: nestedEvalExpressionsTest
+   * 
+   * @assertion_ids: EL:SPEC:2
+   * 
+   * @test_Strategy: Verify that nested eval-expressions are illegal.
+   */
+  @Test
+  public void nestedEvalExpressionsTest() throws Exception {
+
+    boolean pass = true;
+    String[] expr = { "${worker[${worker}]}", "${worker[#{worker}]}",
+        "#{worker[${worker}]}", "#{worker[#{worker}]}" };
+
+    for (int i = 0; i < expr.length; ++i) {
+
+      try {
+        ExprEval.evaluateValueExpression(expr[i], null, String.class,
+            ResolverType.EMPLOYEE_ELRESOLVER);
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Test FAILED. No exception thrown for ");
+        logger.log(Logger.Level.ERROR, expr[i]);
+
+      } catch (ELException ee) {
+        // Test passes
+        logger.log(Logger.Level.ERROR, "Expected Exception thrown.");
+
+      } catch (Exception e) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Test FAILED. " + expr[i] + " caused ");
+        logger.log(Logger.Level.ERROR, "an exception, but it was not an ");
+        logger.log(Logger.Level.ERROR, "ELException.");
+        ELTestUtil.printStackTrace(e);
+      }
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: mixedCompositeExpressionsTest
+   * 
+   * @assertion_ids: EL:SPEC:12
+   * 
+   * @test_Strategy: Verify that composite expressions that mix the '$' and '#'
+   * delimiters are illegal.
+   */
+  @Test
+  public void mixedCompositeExpressionsTest() throws Exception {
+
+    boolean pass = true;
+    String[] expr = { "${worker}#{worker}", "#{worker}${worker}",
+        "${worker}#{worker}${worker}", "#{worker}${worker}#{worker}" };
+
+    for (int i = 0; i < expr.length; ++i) {
+
+      try {
+        ExprEval.evaluateValueExpression(expr[i], null, String.class,
+            ResolverType.EMPLOYEE_ELRESOLVER);
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Test FAILED. No exception thrown for ");
+        logger.log(Logger.Level.ERROR, expr[i]);
+
+      } catch (ELException ee) {
+        // Test passes
+        logger.log(Logger.Level.ERROR, "Expected Exception thrown.");
+
+      } catch (Exception e) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Test FAILED. " + expr[i] + " caused ");
+        logger.log(Logger.Level.ERROR, "an exception, but it was not an ");
+        logger.log(Logger.Level.ERROR, "ELException.");
+        ELTestUtil.printStackTrace(e);
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED!");
+    }
+  }
+
+  /*
+   * @testName: compositeExprEval1Test
+   * 
+   * @assertion_ids: EL:SPEC:11
+   * 
+   * @test_Strategy: Verify that in a composite expression eval-expressions are
+   * coerced to Strings according to the EL type conversion rules and
+   * concatenated with any intervening literal-expressions.
+   */
+  @Test
+  public void compositeExprEval1Test() throws Exception {
+
+    boolean pass = true;
+
+    String streetName = "${'Network Circle'}";
+    String city = "${'Santa Clara'}";
+    String state = "${'CA'}";
+
+    String expected = "4140 Network Circle, Santa Clara, CA 95054";
+
+    try {
+      Object address = ExprEval.evaluateValueExpression(
+          4140 + " " + streetName + ", " + city + ", " + state + " " + 95054,
+          null, String.class);
+
+      logger.log(Logger.Level.TRACE, "Testing for Address: " + expected);
+
+      pass = (ExprEval.compareClass(address, String.class)
+          && ExprEval.compareValue(address, expected));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: compositeExprEval2Test
+   * 
+   * @assertion_ids: EL:SPEC:11
+   * 
+   * @test_Strategy: Verify that in a composite expression eval-expressions are
+   * evaluated left to right, coerced to Strings according to the EL type
+   * conversion rules, and concatenated with any intervening
+   * literal-expressions.
+   */
+  @Test
+  public void compositeExprEval2Test() throws Exception {
+
+    boolean pass = true;
+
+    int num = 2;
+    String expected = "total = 3.0";
+
+    try {
+      Object div = ExprEval.evaluateValueExpression(
+          "total = " + "${" + num + "+2/" + num + "}", null, String.class);
+
+      logger.log(Logger.Level.TRACE, "Testing for: " + expected);
+
+      pass = (ExprEval.compareClass(div, String.class)
+          && ExprEval.compareValue(div, expected));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: dotAndIndexOperatorsSameTest
+   * 
+   * @assertion_ids: EL:SPEC:15
+   * 
+   * @test_Strategy: [DotAndIndexOperatorsSame] Verify that the dot and index
+   * operators are evaluated in the same way.
+   */
+  @Test
+  public void dotAndIndexOperatorsSameTest() throws Exception {
+
+    boolean pass = true;
+
+    try {
+      // ELResolver empResolver = new EmployeeELResolver();
+
+      Object firstnameDot = ExprEval.evaluateValueExpression(
+          "${worker.firstName}", null, String.class,
+          ResolverType.EMPLOYEE_ELRESOLVER);
+
+      Object firstnameBracket = ExprEval.evaluateValueExpression(
+          "${worker['firstName']}", null, String.class,
+          ResolverType.EMPLOYEE_ELRESOLVER);
+
+      pass = firstnameDot.equals(firstnameBracket);
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: elSyntaxEscapeTest
+   * 
+   * @assertion_ids: EL:SPEC:8
+   * 
+   * @test_Strategy: [ELSyntaxEscape] Verify that the EL special characters '$'
+   * and '#' are treated as literals when preceded with '\'.
+   */
+  @Test
+  public void elSyntaxEscapeTest() throws Exception {
+
+    boolean pass = true;
+
+    try {
+      Object firstnameDollar = ExprEval.evaluateValueExpression(
+          "\\${worker.firstName}", null, String.class,
+          ResolverType.EMPLOYEE_ELRESOLVER);
+
+      Object firstnamePound = ExprEval.evaluateValueExpression(
+          "\\#{worker.firstName}", null, String.class,
+          ResolverType.EMPLOYEE_ELRESOLVER);
+
+      if (!(ExprEval.compareValue(firstnameDollar, "${worker.firstName}")
+          && ExprEval.compareValue(firstnamePound, "#{worker.firstName}"))) {
+
+        logger.log(Logger.Level.TRACE, "Escape character failed to work.");
+        pass = false;
+      }
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: literalExprEval1Test
+   * 
+   * @assertion_ids: EL:SPEC:6
+   * 
+   * @test_Strategy: [LiteralExprEval] Set the value of a ValueExpression to a
+   * literal String type. Verify that the value retrieved when the expression is
+   * evaluated is a String equal to the value set.
+   */
+  @Test
+  public void literalExprEval1Test() throws Exception {
+
+    boolean pass = true;
+
+    String exprStr = "foo";
+    String expected = exprStr;
+
+    try {
+      Object expr = ExprEval.evaluateValueExpression(exprStr, null,
+          String.class);
+
+      pass = (ExprEval.compareClass(expr, String.class)
+          && ExprEval.compareValue(expr, expected));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: literalExprEval2Test
+   * 
+   * @assertion_ids: EL:SPEC:6
+   * 
+   * @test_Strategy: [LiteralExprEval] Coerce a String literal to a Boolean in a
+   * ValueExpression. Verify that the value retrieved when the expression is
+   * evaluated is a Boolean of the expected value.
+   */
+  @Test
+  public void literalExprEval2Test() throws Exception {
+
+    boolean pass = true;
+
+    String exprStr = "true";
+
+    try {
+      Object expr = ExprEval.evaluateValueExpression(exprStr, null,
+          Boolean.class);
+
+      pass = (ExprEval.compareClass(expr, Boolean.class)
+          && ExprEval.compareValue(expr, true));
+
+    } catch (Exception e) {
+      ELTestUtil.printStackTrace(e);
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: literalExprAsMethodExpr1Test
+   * 
+   * @assertion_ids: EL:SPEC:10
+   * 
+   * @test_Strategy: [LiteralExprAsMethodExpr] Verify that a literal-expression
+   * can also be used as a method expression that returns a non-void value.
+   */
+  @Test
+  public void literalExprAsMethodExpr1Test() throws Exception {
+
+    boolean pass = true;
+
+    try {
+      // literal expression returning String
+      Class[] params = {};
+
+      Object value1 = ExprEval.evaluateMethodExpression("true", params,
+          String.class, ResolverType.VECT_ELRESOLVER);
+
+      if (!("true".equals(value1))) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Literal Expression, Return String Failed!");
+      }
+
+      // literal expression returning non-String value
+      Object value2 = ExprEval.evaluateMethodExpression("true", params,
+          Boolean.class, ResolverType.VECT_ELRESOLVER);
+      if (!((Boolean) value2).booleanValue()) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, "Literal Expression, Return non-String " + "Failed!");
+      }
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("Test Failed!");
+  }
+
+  /*
+   * @testName: literalExprAsMethodExpr2Test
+   * 
+   * @assertion_ids: EL:SPEC:10
+   * 
+   * @test_Strategy: [LiteralExprAsMethodExpr] Verify that a literal-expression
+   * can also be used as a method expression that returns a non-void value.
+   * Verify that the standard coercion rules apply if the return type is not
+   * java.lang.String.
+   */
+  @Test
+  public void literalExprAsMethodExpr2Test() throws Exception {
+
+    boolean pass = true;
+    int testNum = 496;
+
+    try {
+      // literal expression returning String
+      Class[] params = {};
+
+      Object value = ExprEval.evaluateMethodExpression("496", params,
+          Integer.class, ResolverType.VECT_ELRESOLVER);
+
+      if (!(value instanceof Integer)) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, "MethodExpression invocation does not return"
+            + " instance of expected class");
+      }
+
+      else if (((Integer) value).intValue() != testNum) {
+        pass = false;
+        logger.log(Logger.Level.ERROR, 
+            "Expected: " + testNum + NLINE + "Received: " + value.toString());
+      }
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("Test Failed!");
+  }
+
+  /*
+   * @testName: rValueCoercion1Test
+   * 
+   * @assertion_ids: EL:SPEC:3
+   * 
+   * @test_Strategy: [RValueCoercion] Set the value of a ValueExpression to a
+   * String type and verify that the value retrieved when the expression is
+   * evaluated is also a String type.
+   */
+  @Test
+  public void rValueCoercion1Test() throws Exception {
+    boolean pass = false;
+
+    String expr = "${foo}";
+    String expected = "bar";
+
+    try {
+      Object value = ExprEval.evaluateCoerceValueExpression(expr, expected,
+          String.class);
+
+      pass = (ExprEval.compareClass(value, String.class)
+          && ExprEval.compareValue(value, expected));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: rValueCoercion2Test
+   * 
+   * @assertion_ids: EL:SPEC:3
+   * 
+   * @test_Strategy: [RValueCoercion] Set the value of a ValueExpression to a
+   * complex type and verify that the value retrieved when the expression is
+   * evaluated is a String type in accordance with the coercion rules.
+   */
+  @Test
+  public void rValueCoercion2Test() throws Exception {
+    boolean pass = false;
+
+    String expr = "${javabook}";
+    String expected = "The Java Programming Language";
+
+    try {
+      Book jbook = new Book(expected, "Arnold and Gosling", "Addison Wesley",
+          1996);
+
+      Object value = ExprEval.evaluateCoerceValueExpression(expr, jbook,
+          String.class);
+
+      pass = (ExprEval.compareClass(value, String.class)
+          && ExprEval.compareValue(value, expected));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+  /*
+   * @testName: parseOnceEvalManyTest
+   * 
+   * @assertion_ids: EL:SPEC:45
+   * 
+   * @test_Strategy: [ExprParsedEvalMany] Verify that once an expression is
+   * parsed, it can be evaluated multiple times, and that the result of the
+   * evaluation will be the same even when the EL context is modified.
+   */
+  @Test
+  public void parseOnceEvalManyTest() throws Exception {
+    boolean pass = false;
+
+    String expr = "${foo}";
+    String expected = "bar";
+
+    Hashtable contextObjects = new Hashtable();
+    contextObjects.put(String.class, "string context");
+    contextObjects.put(Integer.class, Integer.valueOf(1));
+    contextObjects.put(Boolean.class, Boolean.TRUE);
+
+    try {
+      pass = ExprEval.evaluateManyValueExpression(expr, expected, String.class,
+          contextObjects);
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+    if (!pass)
+      throw new Exception("TEST FAILED!");
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/literal/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/literal/ELClientIT.java
new file mode 100644
index 0000000..56b98e0
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/literal/ELClientIT.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/**
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.literal;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+
+import com.sun.ts.tests.el.common.util.ExprEval;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  // ------------------------------------------------------------- Test
+  // Methods
+
+  /**
+   * @testName: elBooleanLiteralTest
+   * @assertion_ids: EL:SPEC:13.1
+   * @test_Strategy: Validate that the EL Boolean literal: - 'true' is evaluated
+   *                 as expected. - 'false' is evaluated as expected.
+   */
+  @Test
+  public void elBooleanLiteralTest() throws Exception {
+
+    boolean pass1, pass2;
+    Boolean expectedResult = Boolean.TRUE;
+
+    // Literal true.
+    try {
+      pass1 = false;
+      expectedResult = Boolean.TRUE;
+
+      Object result = ExprEval.evaluateValueExpression("${true}", null,
+          Object.class);
+      logger.log(Logger.Level.TRACE, "result is " + result.toString());
+      pass1 = (ExprEval.compareClass(result, Boolean.class)
+          && ExprEval.compareValue(result, expectedResult));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    // Literal false.
+    try {
+      pass2 = false;
+      expectedResult = Boolean.FALSE;
+
+      Object result = ExprEval.evaluateValueExpression("${false}", null,
+          Object.class);
+      logger.log(Logger.Level.TRACE, "result is " + result.toString());
+      pass2 = (ExprEval.compareClass(result, Boolean.class)
+          && ExprEval.compareValue(result, expectedResult));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass1)
+      throw new Exception("TEST FAILED: Literal true evaluated incorrectly.");
+    if (!pass2)
+      throw new Exception("TEST FAILED: Literal false evaluated " + "incorrectly.");
+  }
+
+  /**
+   * @testName: elIntegerLiteralTest
+   * @assertion_ids: EL:SPEC:13.2
+   * @test_Strategy: Validate that the EL Integer literal with the: - '$' is
+   *                 evaluated as expected. - '#' is evaluated as expected.
+   */
+  @Test
+  public void elIntegerLiteralTest() throws Exception {
+
+    boolean pass1, pass2;
+    Long expectedResult;
+
+    List ilist = this.getIntegerList();
+
+    for (Iterator it = ilist.iterator(); it.hasNext();) {
+      Integer tInteger = (Integer) it.next();
+      expectedResult = Long.valueOf(tInteger);
+
+      // test "$" symbol
+      try {
+        pass1 = false;
+
+        Object result = ExprEval.evaluateValueExpression(
+            "${" + tInteger.toString() + "}", null, Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass1 = (ExprEval.compareClass(result, Long.class)
+            && ExprEval.compareValue((Long) result, expectedResult));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+
+      // Test "#" symbol
+      try {
+        pass2 = false;
+
+        Object result = ExprEval.evaluateValueExpression(
+            "#{" + tInteger.toString() + "}", null, Object.class);
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass2 = (ExprEval.compareClass(result, Long.class)
+            && ExprEval.compareValue((Long) result, expectedResult));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+
+      if (!pass1)
+        throw new Exception(
+            "TEST FAILED: Literal Integer \"$\" evaluated" + " incorrectly.");
+      if (!pass2)
+        throw new Exception(
+            "TEST FAILED: Literal Integer \"#\" evaluated" + " incorrectly.");
+    }
+  }
+
+  /**
+   * @testName: elFloatingPointLiteralTest
+   * @assertion_ids: EL:SPEC:13.3
+   * @test_Strategy: Validate that the EL Float literal with the: - '$' is
+   *                 evaluated as expected. - '#' is evaluated as expected.
+   */
+  @Test
+  public void elFloatingPointLiteralTest() throws Exception {
+
+    boolean pass1, pass2;
+    Float expectedResult;
+
+    List flist = this.getFloatList();
+
+    for (Iterator it = flist.iterator(); it.hasNext();) {
+      Float tFloat = (Float) it.next();
+      expectedResult = Float.valueOf(tFloat);
+
+      // test "$" symbol
+      try {
+        pass1 = false;
+
+        Object result = ExprEval.evaluateValueExpression(
+            "${" + tFloat.toString() + "}", null, Object.class);
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass1 = (ExprEval.compareClass(result, Double.class)
+            && ExprEval.compareValue((Double) result, expectedResult, 1));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+
+      // Test "#" symbol
+      try {
+        pass2 = false;
+
+        Object result = ExprEval.evaluateValueExpression(
+            "#{" + tFloat.toString() + "}", null, Object.class);
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass2 = (ExprEval.compareClass(result, Double.class)
+            && ExprEval.compareValue((Double) result, expectedResult, 1));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+
+      if (!pass1)
+        throw new Exception(
+            "TEST FAILED: Literal Float \"$\" evaluated" + " incorrectly.");
+      if (!pass2)
+        throw new Exception(
+            "TEST FAILED: Literal Float \"#\" evaluated" + " incorrectly.");
+    }
+  }
+
+  /**
+   * @testName: elStringLiteralTest
+   * @assertion_ids: EL:SPEC:13.4; EL:SPEC:13.5
+   * @test_Strategy: Validate that the EL String literal with the: - '$' is
+   *                 evaluated as expected. - '#' is evaluated as expected.
+   */
+  @Test
+  public void elStringLiteralTest() throws Exception {
+
+    boolean pass1, pass2;
+    String expectedResult;
+    String testString;
+
+    Hashtable sMap = this.getStringTable();
+    Enumeration keys = sMap.keys();
+
+    while (keys.hasMoreElements()) {
+
+      expectedResult = keys.nextElement().toString();
+      testString = sMap.get(expectedResult).toString();
+
+      // test "$" symbol
+      try {
+        pass1 = false;
+
+        Object result = ExprEval.evaluateValueExpression(
+            "${" + testString + "}", null, Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass1 = (ExprEval.compareClass(result, String.class)
+            && ExprEval.compareValue((String) result, expectedResult));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+
+      // Test "#" symbol
+      try {
+        pass2 = false;
+
+        Object result = ExprEval.evaluateValueExpression(
+            "#{" + testString + "}", null, Object.class);
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass2 = (ExprEval.compareClass(result, String.class)
+            && ExprEval.compareValue((String) result, expectedResult));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+
+      if (!pass1)
+        throw new Exception(
+            "TEST FAILED: Literal String \"$\" evaluated" + " incorrectly.");
+      if (!pass2)
+        throw new Exception(
+            "TEST FAILED: Literal String \"#\" evaluated" + " incorrectly.");
+    }
+  }
+
+  /**
+   * @testName: elNullLiteralTest
+   * @assertion_ids: EL:SPEC:13.6
+   * @test_Strategy: Validate that the EL 'null' literal evalutes correctly.
+   */
+  @Test
+  public void elNullLiteralTest() throws Exception {
+
+    boolean pass1, pass2;
+
+    // Test "$" symbol
+    try {
+      Object result = ExprEval.evaluateValueExpression("${null}", null,
+          Object.class);
+      pass1 = (result == null) ? true : false;
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    // Test "#" symbol
+
+    try {
+      Object result = ExprEval.evaluateValueExpression("#{null}", null,
+          Object.class);
+      pass2 = (result == null) ? true : false;
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass1)
+      throw new Exception(
+          "TEST FAILED: Literal 'null' \"$\" evaluated" + " incorrectly.");
+
+    if (!pass2)
+      throw new Exception(
+          "TEST FAILED: Literal 'null \"#\" evaluated" + " incorrectly.");
+
+  }
+
+  /**
+   * @testName: elSyntaxAsLiteralTest
+   * @assertion_ids: EL:SPEC:7
+   * @test_Strategy: [ELSyntaxAsLiteral] Verify that to generate literal values
+   *                 that include the character sequence "${" or "#{" a
+   *                 composite expression can be used.
+   */
+  @Test
+  public void elSyntaxAsLiteralTest() throws Exception {
+    boolean pass = false;
+
+    // Hashtable layout.
+    // key - expected value
+    // value - test expression
+    Hashtable testValues = new Hashtable();
+    testValues.put("${foo}", "#{'${'}foo}");
+    testValues.put("${foo}", "${'${'}foo}");
+    testValues.put("#{foo}", "${'#{'}foo}");
+    testValues.put("#{foo}", "#{'#{'}foo}");
+
+    String exprStr;
+    String expected;
+
+    Set<String> tvalue = testValues.keySet();
+    Iterator<String> itr = tvalue.iterator();
+
+    while (itr.hasNext()) {
+      expected = itr.next();
+      exprStr = (String) testValues.get(expected);
+
+      try {
+        Object expr = ExprEval.evaluateValueExpression(exprStr, null,
+            String.class);
+
+        pass = (ExprEval.compareClass(expr, String.class)
+            && ExprEval.compareValue(expr, expected));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED!");
+    }
+  }
+
+  // ---------------------------------------------------------- Private
+  // methods
+
+  private List getFloatList() {
+    List<Float> floatList = new ArrayList<Float>();
+    floatList.add(new Float("8.1F"));
+    floatList.add(new Float("-70.2F"));
+    floatList.add(new Float("8.1e4F"));
+    floatList.add(new Float("8.1E6F"));
+    floatList.add(new Float("8.1e-9F"));
+    floatList.add(new Float("8.1E+3F"));
+    floatList.add(new Float("-.72F"));
+    floatList.add(new Float(".999F"));
+    floatList.add(new Float("-.1e1F"));
+    floatList.add(new Float(".234E22F"));
+    floatList.add(new Float("-.3444e-2F"));
+    floatList.add(new Float(".5E+7F"));
+    floatList.add(new Float("-1e1F"));
+    floatList.add(new Float("234E2F"));
+    floatList.add(new Float("-3444e-2F"));
+    floatList.add(new Float("-3444e+2F"));
+
+    return floatList;
+  }
+
+  private List getIntegerList() {
+    List<Integer> integerList = new ArrayList<Integer>();
+    integerList.add(1);
+    integerList.add(-2);
+    integerList.add(2147483647);
+    integerList.add(-2147483647);
+
+    return integerList;
+  }
+
+  /**
+   * The returned Hashtable is in the form of: "Expected String" - "Test String"
+   */
+  private Hashtable getStringTable() {
+    Hashtable testStrings = new Hashtable();
+    testStrings.put("string", "'string'");
+    testStrings.put("str\\ing", "'str\\\\ing'");
+    testStrings.put("\"catstring\"", "'\"catstring\"'");
+    testStrings.put("\'pullstring\'", "'\\\'pullstring\\\''");
+
+    return testStrings;
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/mapper/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/mapper/ELClientIT.java
new file mode 100644
index 0000000..75ee1d0
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/mapper/ELClientIT.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.mapper;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ELTestUtil;
+import com.sun.ts.tests.el.common.elcontext.FuncMapperELContext;
+import com.sun.ts.tests.el.common.elcontext.VarMapperELContext;
+import com.sun.ts.tests.el.common.functionmapper.TCKFunctionMapper;
+import com.sun.ts.tests.el.common.util.ExprEval;
+
+import jakarta.el.ELException;
+import jakarta.el.ExpressionFactory;
+import jakarta.el.ValueExpression;
+import jakarta.el.VariableMapper;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  Properties testProps;
+
+  public ELClientIT(){
+    this.testProps =System.getProperties();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /**
+   * @testName: ELFunctionBindingTest
+   *
+   * @assertion_ids: EL:SPEC:31
+   * @test_Strategy: [ELFunctionsBinding] Create an ELContext that uses a
+   *                 non-null FunctionMapper. Create a ValueExpression from the
+   *                 ELContext that references a function assigned by the
+   *                 FunctionMapper. Change the function mapping in the
+   *                 FunctionMapper. Show that the ValueExpression evaluates as
+   *                 before and that the original method mapped to the function
+   *                 is being invoked.
+   */
+  @Test
+  public void ELFunctionBindingTest() throws Exception {
+
+    Class expectedClass = Integer.class;
+    Integer expectedValue = Integer.valueOf(10);
+
+    // Create ValueExpressions from a function mapped by the
+    // FunctionMapper: Int:val() -> Integer.valueOf(String s)
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    FuncMapperELContext context = new FuncMapperELContext();
+    ValueExpression vexp1 = expFactory.createValueExpression(context,
+        "${Int:val(10)}", Object.class);
+    ValueExpression vexp2 = expFactory.createValueExpression(context,
+        "${Int:val(\"string\")}", Object.class);
+
+    // Make sure the expression evaluates as we expect
+    Object initialResult = vexp1.getValue(context);
+    if (!ExprEval.compareClass(initialResult, expectedClass)) {
+      throw new Exception("Wrong class for initial Expression evaluation");
+    }
+    if (!ExprEval.compareValue(initialResult, expectedValue)) {
+      throw new Exception("Wrong value for initial Expression evaluation");
+    }
+
+    // Get the FunctionMapper and change the method mapped to Int:val
+    TCKFunctionMapper mapper = (TCKFunctionMapper) context.getFunctionMapper();
+    mapper.update();
+
+    // Now re-evaluate the expression; results should be the same
+    Object finalResult = vexp1.getValue(context);
+    if (!ExprEval.compareClass(finalResult, expectedClass)) {
+      throw new Exception("Wrong class for final Expression evaluation");
+    }
+    if (!ExprEval.compareValue(finalResult, expectedValue)) {
+      throw new Exception("Wrong value for final Expression evaluation");
+    }
+
+    // Verify the method bound to the function behaves as expected for
+    // invalid arguments
+    try {
+      vexp2.getValue(context);
+
+    } catch (Throwable t) {
+      if (!(t instanceof ELException)) {
+        logger.log(Logger.Level.ERROR, "Expected ELException to be thrown");
+        logger.log(Logger.Level.ERROR, "instead threw " + t.toString());
+        ELTestUtil.printStackTrace(t);
+        throw new Exception("ELException not thrown");
+      }
+      Throwable cause = t.getCause();
+      if (!(cause instanceof NumberFormatException)) {
+        logger.log(Logger.Level.ERROR, "Expected cause to be NumberFormatException");
+        logger.log(Logger.Level.ERROR, "instead cause is " + cause.toString());
+        ELTestUtil.printStackTrace(cause);
+        throw new Exception("NumberFormatException not cause");
+      }
+    }
+  }
+
+  /**
+   * @testName: ELVariableBindingTest
+   *
+   * @assertion_ids: EL:SPEC:34
+   * @test_Strategy: [ELVariablesBinding] Create an ELContext that uses a
+   *                 non-null VariableMapper. Create a ValueExpression from the
+   *                 ELContext that references a variable assigned by the
+   *                 VariableMapper. Remove the assignment from the
+   *                 VariableMapper. Verify that the ValueExpression evaluates
+   *                 as before.
+   */
+  @Test
+  public void ELVariableBindingTest() throws Exception {
+
+    Class expectedClass = Double.class;
+    Double expectedValue = Double.valueOf(10.0);
+
+    // Create a ValueExpression and use it to set a variable
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    VarMapperELContext context = new VarMapperELContext(testProps);
+    VariableMapper varMapper = context.getVariableMapper();
+    ValueExpression vexp1 = expFactory.createValueExpression(context, "#{1e1}",
+        Object.class);
+    varMapper.setVariable("ten", vexp1);
+
+    // Make sure the variable evaluates as we expect
+    ValueExpression vexp2 = varMapper.resolveVariable("ten");
+    Object initialResult = vexp2.getValue(context);
+    if (!ExprEval.compareClass(initialResult, expectedClass)) {
+      throw new Exception("Wrong class for initial Expression evaluation");
+    }
+    if (!ExprEval.compareValue(initialResult, expectedValue)) {
+      throw new Exception("Wrong value for initial Expression evaluation");
+    }
+
+    // Remove the variable assignment
+    varMapper.setVariable("ten", null);
+
+    // Now re-evaluate the variable; results should be the same
+    Object finalResult = vexp2.getValue(context);
+    if (!ExprEval.compareClass(finalResult, expectedClass)) {
+      throw new Exception("Wrong class for final Expression evaluation");
+    }
+    if (!ExprEval.compareValue(finalResult, expectedValue)) {
+      throw new Exception("Wrong value for final Expression evaluation");
+    }
+
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/operatorprecedence/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/operatorprecedence/ELClientIT.java
new file mode 100644
index 0000000..6967543
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/operatorprecedence/ELClientIT.java
@@ -0,0 +1,532 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.operatorprecedence;
+
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.elcontext.FuncMapperELContext;
+import com.sun.ts.tests.el.common.util.ExprEval;
+
+import jakarta.el.ELException;
+import jakarta.el.ExpressionFactory;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private static final String[] MODOPER = { "%", "mod" };
+
+  private static final String[] DIVOPER = { "/", "div" };
+
+  private static final String[] ANDOPER = { "&&", "and" };
+
+  private static final String[] OROPER = { "||", "or" };
+
+  private final boolean[] deferred = { true, false };
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /*
+   * @testName: elMultiPreBinaryTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "*" is evaluated before "+" "*" is evaluated before "-"
+   */
+  @Test
+  public void elMultiPreBinaryTest() throws Exception {
+
+    this.testOrderPrecedence("{1 + 5 * 2}", Long.valueOf(11));
+    this.testOrderPrecedence("{1 - 5 * 2}", Long.valueOf(-9));
+
+  }
+
+  /*
+   * @testName: elDivPreBinaryTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "div, /" is evaluated before "+" "div, /" is evaluated before
+   * "-"
+   */
+  @Test
+  public void elDivPreBinaryTest() throws Exception {
+
+    for (String s : DIVOPER) {
+      this.testOrderPrecedence("{1 + 4 " + s + " 2}", Double.valueOf(3));
+      this.testOrderPrecedence("{1 - 4 " + s + " 2}", Double.valueOf(-1));
+    }
+
+  }
+
+  /*
+   * @testName: elModPreBinaryTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "mod, %" is evaluated before "+" "mod, %" is evaluated before
+   * "-"
+   */
+  @Test
+  public void elModPreBinaryTest() throws Exception {
+
+    for (String s : MODOPER) {
+      this.testOrderPrecedence("{1 + 7 " + s + " 2}", Long.valueOf(2));
+      this.testOrderPrecedence("{1 - 7 " + s + " 2}", Long.valueOf(0));
+    }
+
+  }
+
+  /*
+   * @testName: elMultiPreRelationalTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "*" is evaluated before ">" "*" is evaluated before "<" "*"
+   * is evaluated before ">=" "*" is evaluated before "<=" "*" is evaluated
+   * before "lt" "*" is evaluated before "gt" "*" is evaluated before "le" "*"
+   * is evaluated before "ge"
+   *
+   * "*" is evaluated before "==" "*" is evaluated before "!=" "*" is evaluated
+   * before "eq" "*" is evaluated before "ne"
+   */
+  @Test
+  public void elMultiPreRelationalTest() throws Exception {
+
+    this.testOrderPrecedence("{6 > 5 * 2}", false);
+    this.testOrderPrecedence("{3 * 2 < 8}", true);
+    this.testOrderPrecedence("{6 >= 5 * 2}", false);
+    this.testOrderPrecedence("{6 * 2 <= 12}", true);
+    this.testOrderPrecedence("{5 * 1 gt 6}", false);
+    this.testOrderPrecedence("{6 lt 5 * 2}", true);
+    this.testOrderPrecedence("{5 * 1 ge 6}", false);
+    this.testOrderPrecedence("{6 le 5 * 2}", true);
+
+    this.testOrderPrecedence("{5 == 5 * 2}", false);
+    this.testOrderPrecedence("{5 * 2 != 10}", false);
+    this.testOrderPrecedence("{10 eq 5 * 2}", true);
+    this.testOrderPrecedence("{15 * 1 ne 1}", true);
+
+  }
+
+  /*
+   * @testName: elDivPreRelationalTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "div, /" is evaluated before ">" "div, /" is evaluated before
+   * "<" "div, /" is evaluated before ">=" "div, /" is evaluated before "<="
+   * "div, /" is evaluated before "lt" "div, /" is evaluated before "gt"
+   * "div, /" is evaluated before "le" "div, /" is evaluated before "ge"
+   *
+   * "div, /" is evaluated before "==" "div, /" is evaluated before "!="
+   * "div, /" is evaluated before "eq" "div, /" is evaluated before "ne"
+   */
+  @Test
+  public void elDivPreRelationalTest() throws Exception {
+
+    for (String s : DIVOPER) {
+      this.testOrderPrecedence("{3 > 4  " + s + " 2}", true);
+      this.testOrderPrecedence("{12 " + s + " 2 < 5}", false);
+      this.testOrderPrecedence("{4 >= 6 " + s + " 24}", true);
+      this.testOrderPrecedence("{16 " + s + " 2 <= 5}", false);
+      this.testOrderPrecedence("{6 gt 5 " + s + " 2}", true);
+      this.testOrderPrecedence("{12 " + s + " 1 lt 5}", false);
+      this.testOrderPrecedence("{6 ge 5 " + s + " 2}", true);
+      this.testOrderPrecedence("{50 " + s + " 2 le 5}", false);
+
+      this.testOrderPrecedence("{1 == 2 " + s + " 2}", true);
+      this.testOrderPrecedence("{10 " + s + " 5 != 5}", true);
+      this.testOrderPrecedence("{5 eq 5 " + s + " 2}", false);
+      this.testOrderPrecedence("{2 ne 4 " + s + " 2}", false);
+    }
+
+  }
+
+  /*
+   * @testName: elModPreRelationalTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "mod, %" is evaluated before ">" "mod, %" is evaluated before
+   * "<" "mod, %" is evaluated before ">=" "mod, %" is evaluated before "<="
+   * "mod, %" is evaluated before "lt" "mod, %" is evaluated before "gt"
+   * "mod, %" is evaluated before "le" "mod, %" is evaluated before "ge"
+   *
+   * "mod, %" is evaluated before "==" "mod, %" is evaluated before "!="
+   * "mod, %" is evaluated before "eq" "mod, %" is evaluated before "ne"
+   */
+  @Test
+  public void elModPreRelationalTest() throws Exception {
+
+    for (String s : MODOPER) {
+      this.testOrderPrecedence("{4 " + s + " 15 > 1}", true);
+      this.testOrderPrecedence("{5 < 6 " + s + " 2}", false);
+      this.testOrderPrecedence("{6 " + s + " 29 >= 5}", true);
+      this.testOrderPrecedence("{6 <= 5 " + s + " 2}", false);
+      this.testOrderPrecedence("{3 " + s + " 8 gt 1}", true);
+      this.testOrderPrecedence("{6 lt 5 " + s + " 2}", false);
+      this.testOrderPrecedence("{8 " + s + " 5 ge 2}", true);
+      this.testOrderPrecedence("{6 le 5 " + s + " 2}", false);
+
+      this.testOrderPrecedence("{3 " + s + " 2 == 1}", true);
+      this.testOrderPrecedence("{5 != 5 " + s + " 2}", true);
+      this.testOrderPrecedence("{6 " + s + " 2 eq 5}", false);
+      this.testOrderPrecedence("{2 ne 5 " + s + " 3}", false);
+    }
+
+  }
+
+  /*
+   * @testName: elMultiEqualPreAndTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "*, ==" is evaluated before "&&, and"
+   */
+  @Test
+  public void elMultiEqualPreAndTest() throws Exception {
+
+    for (String a : ANDOPER) {
+      this.testOrderPrecedence("{10 == 5 * 2 " + a + " 6 * 2 == 15}", false);
+      this.testOrderPrecedence("{10 == 5 * 2 " + a + " 6 * 2 == 12}", true);
+    }
+
+  }
+
+  /*
+   * @testName: elDivEqualPreAndTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "div, /, ==" is evaluated before "&&, and"
+   */
+  @Test
+  public void elDivEqualPreAndTest() throws Exception {
+
+    for (String d : DIVOPER) {
+      for (String a : ANDOPER) {
+        this.testOrderPrecedence(
+            "{12 " + d + " 2 == 6 " + a + " 10 " + d + " 2  == 5}", true);
+        this.testOrderPrecedence(
+            "{12 " + d + " 3 == 6 " + a + " 10 " + d + " 2  == 5}", false);
+      }
+    }
+
+  }
+
+  /*
+   * @testName: elModEqualPreAndTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "mod, %, ==" is evaluated before "&&, and"
+   */
+  @Test
+  public void elModEqualPreAndTest() throws Exception {
+
+    for (String m : MODOPER) {
+      for (String a : ANDOPER) {
+        this.testOrderPrecedence(
+            "{15 " + m + " 4 == 3 " + a + " 3 " + m + " 3 == 0}", true);
+        this.testOrderPrecedence(
+            "{15 " + m + " 3 == 3 " + a + " 3 " + m + " 3 == 0}", false);
+      }
+    }
+
+  }
+
+  /*
+   * @testName: elMultiEqualOrCondTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "*, ==" is evaluated before "||, or"
+   */
+  @Test
+  public void elMultiEqualOrCondTest() throws Exception {
+
+    for (String o : OROPER) {
+      this.testOrderPrecedence("{10 == 5 * 2 " + o + " 6 * 2 == 15}", true);
+      this.testOrderPrecedence("{10 == 5 * 5 " + o + " 6 * 2 == 12}", true);
+      this.testOrderPrecedence("{10 == 5 * 5 " + o + " 6 * 6 == 12}", false);
+    }
+
+  }
+
+  /*
+   * @testName: elDivEqualPreOrTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "div, /, ==" is evaluated before "||, or"
+   */
+  @Test
+  public void elDivEqualPreOrTest() throws Exception {
+
+    for (String d : DIVOPER) {
+      for (String o : OROPER) {
+        this.testOrderPrecedence(
+            "{12 " + d + " 2 == 6 " + o + " 10 " + d + " 5  == 5}", true);
+        this.testOrderPrecedence(
+            "{12 " + d + " 3 == 6 " + o + " 10 " + d + " 2  == 5}", true);
+        this.testOrderPrecedence(
+            "{12 " + d + " 3 == 6 " + o + " 10 " + d + " 5  == 5}", false);
+      }
+    }
+
+  }
+
+  /*
+   * @testName: elModEqualPreOrTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "mod, %, ==" is evaluated before "||, or"
+   */
+  @Test
+  public void elModEqualPreOrTest() throws Exception {
+
+    for (String m : MODOPER) {
+      for (String o : OROPER) {
+        this.testOrderPrecedence(
+            "{15 " + m + " 4 == 3 " + o + " 4 " + m + " 3 == 0}", true);
+        this.testOrderPrecedence(
+            "{15 " + m + " 3 == 3 " + o + " 3 " + m + " 3 == 0}", true);
+        this.testOrderPrecedence(
+            "{15 " + m + " 3 == 3 " + o + " 8 " + m + " 3 == 0}", false);
+      }
+    }
+  }
+
+  /*
+   * @testName: elMultiEqualPreCondTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "*" is evaluated before "? :"
+   */
+  @Test
+  public void elMultiEqualPreCondTest() throws Exception {
+
+    // These tests are designed to return the false if correct.
+    this.testOrderPrecedence("{5 * 2 == 10 ? false : true}", false);
+    this.testOrderPrecedence("{5 * 5 == 10 ? false : true}", true);
+
+  }
+
+  /*
+   * @testName: elDivEqualPreCondTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "div, /, ==" is evaluated before "? :"
+   */
+  @Test
+  public void elDivEqualPreCondTest() throws Exception {
+
+    // These tests are designed to return the false if correct.
+    for (String d : DIVOPER) {
+      this.testOrderPrecedence("{20 " + d + " 2 == 10 ? false : true}", false);
+      this.testOrderPrecedence("{24 " + d + " 2 == 10 ? false : true}", true);
+    }
+  }
+
+  /*
+   * @testName: elModEqualPreCondTest
+   * 
+   * @assertion_ids: EL:SPEC:28
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "mod, %, ==" is evaluated before "||, or"
+   */
+  @Test
+  public void elModEqualPreCondTest() throws Exception {
+
+    for (String m : MODOPER) {
+      this.testOrderPrecedence("{21 " + m + " 2 == 1 ? false : true}", false);
+      this.testOrderPrecedence("{15 " + m + " 3 == 3 ? false : true}", true);
+    }
+  }
+
+  /*
+   * @testName: elParenPreBinaryTest
+   * 
+   * @assertion_ids: EL:SPEC:28; EL:SPEC:27
+   * 
+   * @test_Strategy: Validate that the order of precedence is followed when an
+   * EL Expression is evaluated.
+   *
+   * Rules tested: "( )" is evaluated before "+" "( )" is evaluated before "-"
+   * "( )" is evaluated before "*" "( )" is evaluated before "/" "( )" is
+   * evaluated before "%"
+   */
+  @Test
+  public void elParenPreBinaryTest() throws Exception {
+
+    // "+" tests
+    this.testOrderPrecedence("{(2 + 3) - 10}", Long.valueOf(-5));
+    this.testOrderPrecedence("{10 - (2 + 3)}", Long.valueOf(5));
+
+    // "-" tests
+    this.testOrderPrecedence("{(1 - 5) + 2}", Long.valueOf(-2));
+    this.testOrderPrecedence("{2 + (5 - 1)}", Long.valueOf(6));
+
+    // "*" tests
+    this.testOrderPrecedence("{(1 + 5) * 2}", Long.valueOf(12));
+    this.testOrderPrecedence("{2 * (1 + 5)}", Long.valueOf(12));
+
+    // "/" tests
+    this.testOrderPrecedence("{(4 + 4) / 2}", Double.valueOf(4));
+    this.testOrderPrecedence("{2 / (4 + 4)}", Double.valueOf(0.25));
+
+    // "%" tests
+    this.testOrderPrecedence("{(2 + 7) % 2}", Long.valueOf(1));
+    this.testOrderPrecedence("{18 % (8 + 7)}", Long.valueOf(3));
+
+  }
+
+  /*
+   * @testName: functionPrecedenceTest
+   * 
+   * @assertion_ids: EL:SPEC:29
+   * 
+   * @test_Strategy: Validate that qualified functions with a namespace prefix
+   * have precedence over the operators by constructing an expression which
+   * cannot be parsed due to this rule.
+   */
+  @Test
+  public void functionPrecedenceTest() throws Exception {
+
+    boolean pass = false;
+
+    ExpressionFactory expFactory = ExpressionFactory.newInstance();
+    FuncMapperELContext context = new FuncMapperELContext();
+    expFactory.createValueExpression(context, "${Int:val(10)}", Object.class);
+    try {
+      expFactory.createValueExpression(context, "${a?Int:val(10)}",
+          Object.class);
+    } catch (ELException ex) {
+      pass = true;
+    }
+
+    if (!pass)
+      throw new Exception("function precedence failed");
+
+  }
+
+  // ---------------------------------------------------------- private methods
+
+  private void testOrderPrecedence(String testExpr, Object expectedResult)
+      throws Exception {
+
+    boolean pass = false;
+
+    String[] symbol = { "$", "#" };
+    String expr;
+
+    try {
+      for (String prefix : symbol) {
+        expr = prefix + testExpr;
+
+        logger.log(Logger.Level.TRACE, "Expression to test: " + expr);
+
+        Object result = ExprEval.evaluateValueExpression(expr, null,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareValue(result, expectedResult));
+
+        if (!pass)
+          throw new Exception("TEST FAILED: pass = false");
+      }
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/relationaloperator/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/relationaloperator/ELClientIT.java
new file mode 100644
index 0000000..95d60e7
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/relationaloperator/ELClientIT.java
@@ -0,0 +1,2430 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/**
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.relationaloperator;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ExprEval;
+import com.sun.ts.tests.el.common.util.NameValuePair;
+import com.sun.ts.tests.el.common.util.TestNum;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private List numberList;
+
+  private enum TestEnum {
+    APPLE, PEAR
+  };
+
+  // Data Type to test String Coercion.
+  private static final DougType DT = new DougType();
+
+  private static final NickType NT = new NickType();
+
+  public ELClientIT(){
+    numberList = TestNum.getNumberList();
+  }
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /**
+   * @testName: elEqualOperandLessThanOrEqualTest
+   * @assertion_ids: EL:SPEC:21.1
+   * @test_Strategy: Validate that if the operands in an EL <= or le operation
+   *                 are equal, the result is true.
+   */
+  @Test
+  public void elEqualOperandLessThanOrEqualTest() throws Exception {
+
+    boolean pass = false;
+
+    try {
+      // Expression One
+      String expr1 = ExprEval.buildElExpr(false, "<=");
+      logger.log(Logger.Level.TRACE, "first expression to be evaluated is " + expr1);
+
+      NameValuePair values1[] = NameValuePair
+          .buildNameValuePair(new Float(-1.0f), new Float(-1.0));
+
+      Object result1 = ExprEval.evaluateValueExpression(expr1, values1,
+          Boolean.class);
+      logger.log(Logger.Level.TRACE, "first result is " + result1.toString());
+
+      // Expression Two
+      String expr2 = ExprEval.buildElExpr(true, "le");
+      logger.log(Logger.Level.TRACE, "second expression to be evaluated is " + expr2);
+
+      NameValuePair values2[] = NameValuePair
+          .buildNameValuePair(new BigDecimal("1.0"), BigDecimal.ONE);
+      Object result2 = ExprEval.evaluateValueExpression(expr2, values2,
+          Boolean.class);
+
+      logger.log(Logger.Level.TRACE, "second result is " + result2.toString());
+
+      pass = (ExprEval.compareClass(result1, Boolean.class)
+          && ExprEval.compareValue((Boolean) result1, Boolean.TRUE)
+          && ExprEval.compareClass(result2, Boolean.class)
+          && ExprEval.compareValue((Boolean) result2, Boolean.TRUE));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    } finally {
+      ExprEval.cleanup();
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elEqualOperandGreaterThanOrEqualTest
+   * @assertion_ids: EL:SPEC:21.1
+   * @test_Strategy: Validate that if the operands in an EL >= or ge operation
+   *                 are equal, the result is true.
+   */
+  @Test
+  public void elEqualOperandGreaterThanOrEqualTest() throws Exception {
+
+    boolean pass = false;
+
+    try {
+      // Expression One
+      String expr1 = ExprEval.buildElExpr(false, ">=");
+      logger.log(Logger.Level.TRACE, "first expression to be evaluated is " + expr1);
+
+      NameValuePair values1[] = NameValuePair
+          .buildNameValuePair(new Float(-1.0f), new Float(-1.0));
+
+      Object result1 = ExprEval.evaluateValueExpression(expr1, values1,
+          Boolean.class);
+      logger.log(Logger.Level.TRACE, "first result is " + result1.toString());
+
+      // Expression Two
+      String expr2 = ExprEval.buildElExpr(true, "ge");
+      logger.log(Logger.Level.TRACE, "second expression to be evaluated is " + expr2);
+
+      NameValuePair values2[] = NameValuePair
+          .buildNameValuePair(new BigInteger("1010"), BigInteger.TEN);
+
+      Object result2 = ExprEval.evaluateValueExpression(expr2, values2,
+          Boolean.class);
+      logger.log(Logger.Level.TRACE, "second result is " + result2.toString());
+
+      pass = (ExprEval.compareClass(result1, Boolean.class)
+          && ExprEval.compareValue((Boolean) result1, Boolean.TRUE)
+          && ExprEval.compareClass(result2, Boolean.class)
+          && ExprEval.compareValue((Boolean) result2, Boolean.TRUE));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    } finally {
+      ExprEval.cleanup();
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elNullOperandLessThanOrEqualTest
+   * @assertion_ids: EL:SPEC:21.2
+   * @test_Strategy: Validate that if one of the operands in an EL <= or le
+   *                 operation is null, the result is false.
+   */
+  @Test
+  public void elNullOperandLessThanOrEqualTest() throws Exception {
+
+    boolean pass = false;
+
+    try {
+
+      Object result1 = ExprEval.evaluateValueExpression("${1 <= nullValue}",
+          null, Object.class);
+      logger.log(Logger.Level.TRACE, "first result is " + result1.toString());
+
+      Object result2 = ExprEval.evaluateValueExpression("#{2 le nullValue}",
+          null, Object.class);
+      logger.log(Logger.Level.TRACE, "second result is " + result2.toString());
+
+      pass = (ExprEval.compareClass(result1, Boolean.class)
+          && ExprEval.compareValue((Boolean) result1, Boolean.FALSE)
+          && ExprEval.compareClass(result2, Boolean.class)
+          && ExprEval.compareValue((Boolean) result2, Boolean.FALSE));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elNullOperandGreaterThanOrEqualTest
+   * @assertion_ids: EL:SPEC:21.2
+   * @test_Strategy: Validate that if one of the operands in an EL >= or ge
+   *                 operation is null, the result is false.
+   */
+  @Test
+  public void elNullOperandGreaterThanOrEqualTest() throws Exception {
+
+    boolean pass = false;
+
+    try {
+
+      Object result1 = ExprEval.evaluateValueExpression("${1 >= nullValue}",
+          null, Object.class);
+      logger.log(Logger.Level.TRACE, "first result is " + result1.toString());
+
+      Object result2 = ExprEval.evaluateValueExpression("#{2 ge nullValue}",
+          null, Object.class);
+      logger.log(Logger.Level.TRACE, "second result is " + result2.toString());
+
+      pass = (ExprEval.compareClass(result1, Boolean.class)
+          && ExprEval.compareValue((Boolean) result1, Boolean.FALSE)
+          && ExprEval.compareClass(result2, Boolean.class)
+          && ExprEval.compareValue((Boolean) result2, Boolean.FALSE));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+  }
+
+  /**
+   * @testName: elNullOperandNotEqualTest
+   * @assertion_ids: EL:SPEC:22.2
+   * @test_Strategy: Validate that if one of the operands is null in an EL !=,
+   *                 ne operation return true.
+   */
+  @Test
+  public void elNullOperandNotEqualTest() throws Exception {
+
+    boolean pass = false;
+
+    try {
+
+      Object result1 = ExprEval.evaluateValueExpression("${1 != nullValue}",
+          null, Object.class);
+      logger.log(Logger.Level.TRACE, "first result is " + result1.toString());
+
+      Object result2 = ExprEval.evaluateValueExpression("#{2 ne nullValue}",
+          null, Object.class);
+      logger.log(Logger.Level.TRACE, "second result is " + result2.toString());
+
+      pass = (ExprEval.compareClass(result1, Boolean.class)
+          && ExprEval.compareValue((Boolean) result1, Boolean.TRUE)
+          && ExprEval.compareClass(result2, Boolean.class)
+          && ExprEval.compareValue((Boolean) result2, Boolean.TRUE));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+
+  } // End elNullOperandNotEqualTest
+
+  /**
+   * @testName: elNullOperandEqualTest
+   * @assertion_ids: EL:SPEC:22.2
+   * @test_Strategy: Validate that if one of the operands is null in an EL =, eq
+   *                 operation return false.
+   */
+  @Test
+  public void elNullOperandEqualTest() throws Exception {
+
+    boolean pass = false;
+
+    try {
+
+      Object result1 = ExprEval.evaluateValueExpression("${1 == nullValue}",
+          null, Object.class);
+      logger.log(Logger.Level.TRACE, "first result is " + result1.toString());
+
+      Object result2 = ExprEval.evaluateValueExpression("#{2 eq nullValue}",
+          null, Object.class);
+      logger.log(Logger.Level.TRACE, "second result is " + result2.toString());
+
+      pass = (ExprEval.compareClass(result1, Boolean.class)
+          && ExprEval.compareValue((Boolean) result1, Boolean.FALSE)
+          && ExprEval.compareClass(result2, Boolean.class)
+          && ExprEval.compareValue((Boolean) result2, Boolean.FALSE));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+
+  } // End elNullOperandEqualTest
+
+  /**
+   * @testName: elBigDecimalLessThanTest
+   * @assertion_ids: EL:SPEC:21.3
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is a BigDecimal, the result is coerced to
+   *                 BigDecimal and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigDecimal "<" & "lt" BigDecimal
+   *                 BigDecimal "<" & "lt" Double BigDecimal "<" & "lt" Float
+   *                 BigDecimal "<" & "lt" BigInteger BigDecimal "<" & "lt"
+   *                 Integer BigDecimal "<" & "lt" Long BigDecimal "<" & "lt"
+   *                 Short BigDecimal "<" & "lt" Byte
+   */
+  @Test
+  public void elBigDecimalLessThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(10.531), false, "<");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(1.0000), false, "lt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(0.531), true, "lt");
+
+  }
+
+  /**
+   * @testName: elBigDecimalLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.3
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is a BigDecimal, the result is coerced to
+   *                 BigDecimal and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigDecimal "<=" & "le" BigDecimal
+   *                 BigDecimal "<=" & "le" Double BigDecimal "<=" & "le" Float
+   *                 BigDecimal "<=" & "le" BigInteger BigDecimal "<=" & "le"
+   *                 Integer BigDecimal "<=" & "le" Long BigDecimal "<=" & "le"
+   *                 Short BigDecimal "<=" & "le" Byte
+   */
+  @Test
+  public void elBigDecimalLessThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(10.531), false, "<=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(1.0000), true, "le");
+
+    // Value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(-10.531), true, "<=");
+  }
+
+  /**
+   * @testName: elBigDecimalGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.3
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is a BigDecimal, the result is coerced to
+   *                 BigDecimal and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigDecimal ">" & "gt" BigDecimal
+   *                 BigDecimal ">" & "gt" Double BigDecimal ">" & "gt" Float
+   *                 BigDecimal ">" & "gt" BigInteger BigDecimal ">" & "gt"
+   *                 Integer BigDecimal ">" & "gt" Long BigDecimal ">" & "gt"
+   *                 Short BigDecimal ">" & "gt" Byte
+   */
+  @Test
+  public void elBigDecimalGreaterThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(10.531), true, ">");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(1.0000), false, ">");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(0.531), false, "gt");
+
+  }
+
+  /**
+   * @testName: elBigDecimalGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.3
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is a BigDecimal, the result is coerced to
+   *                 BigDecimal and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigDecimal ">=" & "ge" BigDecimal
+   *                 BigDecimal ">=" & "ge" Double BigDecimal ">=" & "ge" Float
+   *                 BigDecimal ">=" & "ge" BigInteger BigDecimal ">=" & "ge"
+   *                 Integer BigDecimal ">=" & "ge" Long BigDecimal ">=" & "ge"
+   *                 Short BigDecimal ">=" & "ge" Byte
+   */
+  @Test
+  public void elBigDecimalGreaterThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(10.531), true, ">=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(1.0000), true, "ge");
+
+    // value passed in is smaller than the COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(-1.0000), false, "ge");
+
+  }
+
+  /**
+   * @testName: elBigDecimalEqualToTest
+   * @assertion_ids: EL:SPEC:22.1; EL:SPEC:22.3.1
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is a BigDecimal, the result is coerced to
+   *                 BigDecimal and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigDecimal "==" & "eq" BigDecimal
+   *                 BigDecimal "==" & "eq" Double BigDecimal "==" & "eq" Float
+   *                 BigDecimal "==" & "eq" BigInteger BigDecimal "==" & "eq"
+   *                 Integer BigDecimal "==" & "eq" Long BigDecimal "==" & "eq"
+   *                 Short BigDecimal "==" & "eq" Byte
+   */
+  @Test
+  public void elBigDecimalEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(10.531), false, "==");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(1), true, "eq");
+
+  }
+
+  /**
+   * @testName: elBigDecimalNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.3.2
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is a BigDecimal, the result is coerced to
+   *                 BigDecimal and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigDecimal "!=" & "ne" BigDecimal
+   *                 BigDecimal "!=" & "ne" Double BigDecimal "!=" & "ne" Float
+   *                 BigDecimal "!=" & "ne" BigInteger BigDecimal "!=" & "ne"
+   *                 Integer BigDecimal "!=" & "ne" Long BigDecimal "!=" & "ne"
+   *                 Short BigDecimal "!=" & "ne" Byte
+   */
+  @Test
+  public void elBigDecimalNotEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(10.531), true, "!=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigDecimal.valueOf(1), false, "ne");
+
+  }
+
+  /**
+   * @testName: elFloatLessThanTest
+   * @assertion_ids: EL:SPEC:21.4
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is a Float, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Float "<" & "lt" Double Float "<" & "lt"
+   *                 Float Float "<" & "lt" BigInteger Float "<" & "lt" Integer
+   *                 Float "<" & "lt" Long Float "<" & "lt" Short Float "<" &
+   *                 "lt" Byte
+   */
+  @Test
+  public void elFloatLessThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(10f), false, "<");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(1f), false, "<");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(-10f), true, "lt");
+
+  }
+
+  /**
+   * @testName: elFloatLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.4
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is a Float, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Float "<=" & "le" Double Float "<=" &
+   *                 "le" Float Float "<=" & "le" BigInteger Float "<=" & "le"
+   *                 Integer Float "<=" & "le" Long Float "<=" & "le" Short
+   *                 Float "<=" & "le" Byte
+   */
+  @Test
+  public void elFloatLessThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(10f), false, "<=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(1f), true, "le");
+
+    // Value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(-10f), true, "<=");
+  }
+
+  /**
+   * @testName: elFloatGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.4
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is a Float, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Float ">" & "gt" Double Float ">" & "gt"
+   *                 Float Float ">" & "gt" BigInteger Float ">" & "gt" Integer
+   *                 Float ">" & "gt" Long Float ">" & "gt" Short Float ">" &
+   *                 "gt" Byte
+   */
+  @Test
+  public void elFloatGreaterThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(10531f), true, ">");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(1f), false, ">");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(-531f), false, "gt");
+
+  }
+
+  /**
+   * @testName: elFloatGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.4
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is a Float, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Float ">=" & "ge" Double Float ">=" &
+   *                 "ge" Float Float ">=" & "ge" BigInteger Float ">=" & "ge"
+   *                 Integer Float ">=" & "ge" Long Float ">=" & "ge" Short
+   *                 Float ">=" & "ge" Byte
+   */
+  @Test
+  public void elFloatGreaterThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(10531f), true, ">=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(1f), true, "ge");
+
+    // value passed in is smaller than the COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(-1f), false, "ge");
+
+  }
+
+  /**
+   * @testName: elFloatEqualToTest
+   * @assertion_ids: EL:SPEC:22.1; EL:SPEC:22.4
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is a Float, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Float "==" & "eq" Double Float "==" &
+   *                 "eq" Float Float "==" & "eq" BigInteger Float "==" & "eq"
+   *                 Integer Float "==" & "eq" Long Float "==" & "eq" Short
+   *                 Float "==" & "eq" Byte
+   */
+  @Test
+  public void elFloatEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(10531), false, "==");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(1), true, "eq");
+
+  }
+
+  /**
+   * @testName: elFloatNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.4
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is a Float, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Float "!=" & "ne" Double Float "!=" &
+   *                 "ne" Float Float "!=" & "ne" BigInteger Float "!=" & "ne"
+   *                 Integer Float "!=" & "ne" Long Float "!=" & "ne" Short
+   *                 Float "!=" & "ne" Byte
+   */
+  @Test
+  public void elFloatNotEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(10531), true, "!=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Float.valueOf(1), false, "ne");
+
+  }
+
+  /**
+   * @testName: elDoubleLessThanTest
+   * @assertion_ids: EL:SPEC:21.4
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is a Double, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Double "<" & "lt" Double Double "<" &
+   *                 "lt" BigInteger Double "<" & "lt" Integer Double "<" & "lt"
+   *                 Long Double "<" & "lt" Short Double "<" & "lt" Byte
+   */
+  @Test
+  public void elDoubleLessThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(2.5), false, "<");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(1.0), false, "lt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(-2.5), true, "lt");
+
+  }
+
+  /**
+   * @testName: elDoubleLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.4
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is a Double, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Double "<=" & "le" Double Double "<=" &
+   *                 "le" BigInteger Double "<=" & "le" Integer Double "<=" &
+   *                 "le" Long Double "<=" & "le" Short Double "<=" & "le" Byte
+   */
+  @Test
+  public void elDoubleLessThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(2.5), false, "<=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(1.0), true, "le");
+
+    // Value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(-1.5), true, "<=");
+  }
+
+  /**
+   * @testName: elDoubleGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.4
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is a Double, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Double ">" & "gt" Double Double ">" &
+   *                 "gt" BigInteger Double ">" & "gt" Integer Double ">" & "gt"
+   *                 Long Double ">" & "gt" Short Double ">" & "gt" Byte
+   */
+  @Test
+  public void elDoubleGreaterThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(10.5), true, ">");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(1.0), false, "gt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(-10.5), false, "gt");
+
+  }
+
+  /**
+   * @testName: elDoubleGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.4
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is a Double, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Double ">=" & "ge" Double Double ">=" &
+   *                 "ge" BigInteger Double ">=" & "ge" Integer Double ">=" &
+   *                 "ge" Long Double ">=" & "ge" Short Double ">=" & "ge" Byte
+   */
+  @Test
+  public void elDoubleGreaterThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(10.0), true, ">=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(1.0), true, "ge");
+
+    // value passed in is smaller than the COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(-10.0), false, "ge");
+
+  }
+
+  /**
+   * @testName: elDoubleEqualToTest
+   * @assertion_ids: EL:SPEC:22.1; EL:SPEC:22.4
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is a Double, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Double "==" & "eq" Double Double "==" &
+   *                 "eq" BigInteger Double "==" & "eq" Integer Double "==" &
+   *                 "eq" Long Double "==" & "eq" Short Double "==" & "eq" Byte
+   */
+  @Test
+  public void elDoubleEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(10531), false, "==");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(1.00), true, "eq");
+
+  }
+
+  /**
+   * @testName: elDoubleNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.4
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is a Double, the result is coerced to Double and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Double "!=" & "ne" Double Double "!=" &
+   *                 "ne" BigInteger Double "!=" & "ne" Integer Double "!=" &
+   *                 "ne" Long Double "!=" & "ne" Short Double "!=" & "ne" Byte
+   */
+  @Test
+  public void elDoubleNotEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(10531), true, "!=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Double.valueOf(1), false, "ne");
+
+  }
+
+  /**
+   * @testName: elBigIntegerLessThanTest
+   * @assertion_ids: EL:SPEC:21.5
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is a BigInteger, the result is coerced to
+   *                 BigInteger and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigInteger "<" & "lt" BigInteger
+   *                 BigInteger "<" & "lt" Integer BigInteger "<" & "lt" Long
+   *                 BigInteger "<" & "lt" Short BigInteger "<" & "lt" Byte
+   */
+  @Test
+  public void elBigIntegerLessThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(10531), false, "<");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(1), false, "lt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(-10531), true, "lt");
+
+  }
+
+  /**
+   * @testName: elBigIntegerLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.5
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is a BigInteger, the result is coerced to
+   *                 BigInteger and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigInteger "<=" & "le" BigInteger
+   *                 BigInteger "<=" & "le" Integer BigInteger "<=" & "le" Long
+   *                 BigInteger "<=" & "le" Short BigInteger "<=" & "le" Byte
+   */
+  @Test
+  public void elBigIntegerLessThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(10531), false, "<=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(1), true, "le");
+
+    // Value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(-10531), true, "<=");
+  }
+
+  /**
+   * @testName: elBigIntegerGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.5
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is a BigInteger, the result is coerced to
+   *                 BigInteger and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigInteger ">" & "gt" BigInteger
+   *                 BigInteger ">" & "gt" Integer BigInteger ">" & "gt" Long
+   *                 BigInteger ">" & "gt" Short BigInteger ">" & "gt" Byte
+   */
+  @Test
+  public void elBigIntegerGreaterThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(10531), true, ">");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(1), false, "gt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(-10531), false, "gt");
+
+  }
+
+  /**
+   * @testName: elBigIntegerGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.5
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is a BigInteger, the result is coerced to
+   *                 BigInteger and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigInteger ">=" & "ge" BigInteger
+   *                 BigInteger ">=" & "ge" Integer BigInteger ">=" & "ge" Long
+   *                 BigInteger ">=" & "ge" Short BigInteger ">=" & "ge" Byte
+   */
+  @Test
+  public void elBigIntegerGreaterThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(10531), true, ">=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(1), true, "ge");
+
+    // value passed in is smaller than the COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(-10531), false, "ge");
+
+  }
+
+  /**
+   * @testName: elBigIntegerEqualToTest
+   * @assertion_ids: EL:SPEC:22.1; EL:SPEC:22.5.1
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is a BigInteger, the result is coerced to
+   *                 BigInteger and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigInteger "==" & "eq" BigInteger
+   *                 BigInteger "==" & "eq" Integer BigInteger "==" & "eq" Long
+   *                 BigInteger "==" & "eq" Short BigInteger "==" & "eq" Byte
+   */
+  @Test
+  public void elBigIntegerEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(10531), false, "==");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(1), true, "eq");
+
+  }
+
+  /**
+   * @testName: elBigIntegerNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.5.2
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is a BigInteger, the result is coerced to
+   *                 BigInteger and the correct boolean value is returned.
+   * 
+   *                 Equations tested: BigInteger "!=" & "ne" BigInteger
+   *                 BigInteger "!=" & "ne" Integer BigInteger "!=" & "ne" Long
+   *                 BigInteger "!=" & "ne" Short BigInteger "!=" & "ne" Byte
+   */
+  @Test
+  public void elBigIntegerNotEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(10531), true, "!=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(BigInteger.valueOf(1), false, "ne");
+
+  }
+
+  /**
+   * @testName: elLongLessThanTest
+   * @assertion_ids: EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is a Long, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Long "<" & "lt" Integer Long "<" & "lt"
+   *                 Long Long "<" & "lt" Short Long "<" & "lt" Byte
+   */
+  @Test
+  public void elLongLessThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(25000), false, "<");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(1), false, "<");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(-25000), true, "lt");
+
+  }
+
+  /**
+   * @testName: elLongLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is a Long, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Long "<=" & "le" Integer Long "<=" & "le"
+   *                 Long Long "<=" & "le" Short Long "<=" & "le" Byte
+   */
+  @Test
+  public void elLongLessThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(25000), false, "<=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(1), true, "le");
+
+    // Value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(-25000), true, "<=");
+  }
+
+  /**
+   * @testName: elLongGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is a Long, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Long ">" & "gt" Integer Long ">" & "gt"
+   *                 Long Long ">" & "gt" Short Long ">" & "gt" Byte
+   */
+  @Test
+  public void elLongGreaterThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(10531), true, ">");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(1), false, ">");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(-10531), false, "gt");
+
+  }
+
+  /**
+   * @testName: elLongGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is a Long, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Long ">=" & "ge" Integer Long ">=" & "ge"
+   *                 Long Long ">=" & "ge" Short Long ">=" & "ge" Byte
+   */
+  @Test
+  public void elLongGreaterThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(25000), true, ">=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(1), true, "ge");
+
+    // value passed in is smaller than the COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(-25000), false, "ge");
+
+  }
+
+  /**
+   * @testName: elLongEqualToTest
+   * @assertion_ids: EL:SPEC:22.1; EL:SPEC:22.6
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is a Long, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Long "==" & "eq" Integer Long "==" & "eq"
+   *                 Long Long "==" & "eq" Short Long "==" & "eq" Byte
+   */
+  @Test
+  public void elLongEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(25000), false, "==");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(1), true, "eq");
+
+  }
+
+  /**
+   * @testName: elLongNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.6
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is a Long, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Long "!=" & "ne" Integer Long "!=" & "ne"
+   *                 Long Long "!=" & "ne" Short Long "!=" & "ne" Byte
+   */
+  @Test
+  public void elLongNotEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(25000), true, "!=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Long.valueOf(1), false, "ne");
+
+  }
+
+  /**
+   * @testName: elIntegerLessThanTest
+   * @assertion_ids: EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is an Integer, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Integer "<" & "lt" Integer Integer "<" &
+   *                 "lt" Short Integer "<" & "lt" Byte
+   */
+  @Test
+  public void elIntegerLessThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(25), false, "<");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(1), false, "lt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(-25), true, "lt");
+
+  }
+
+  /**
+   * @testName: elIntegerLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is an Integer, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Integer "<=" & "le" Integer Integer "<="
+   *                 & "le" Short Integer "<=" & "le" Byte
+   */
+  @Test
+  public void elIntegerLessThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(25), false, "<=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(1), true, "le");
+
+    // Value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(-25), true, "<=");
+  }
+
+  /**
+   * @testName: elIntegerGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is an Integer, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Integer ">" & "gt" Integer Integer ">" &
+   *                 "gt" Short Integer ">" & "gt" Byte
+   */
+  @Test
+  public void elIntegerGreaterThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(105), true, ">");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(1), false, "gt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(-105), false, "gt");
+
+  }
+
+  /**
+   * @testName: elIntegerGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is an Integer, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Integer ">=" & "ge" Integer Integer ">="
+   *                 & "ge" Short Integer ">=" & "ge" Byte
+   */
+  @Test
+  public void elIntegerGreaterThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(250), true, ">=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(1), true, "ge");
+
+    // value passed in is smaller than the COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(-250), false, "ge");
+
+  }
+
+  /**
+   * @testName: elIntegerEqualToTest
+   * @assertion_ids: EL:SPEC:22.1; EL:SPEC:22.6
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is an Integer, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Integer "==" & "eq" Integer Integer "=="
+   *                 & "eq" Short Integer "==" & "eq" Byte
+   */
+  @Test
+  public void elIntegerEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(25), false, "==");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(1), true, "eq");
+
+  }
+
+  /**
+   * @testName: elIntegerNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.6
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is an Integer, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Integer "!=" & "ne" Integer Integer "!="
+   *                 & "ne" Short Integer "!=" & "ne" Byte
+   */
+  @Test
+  public void elIntegerNotEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(25), true, "!=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Integer.valueOf(1), false, "ne");
+
+  }
+
+  /**
+   * @testName: elShortLessThanTest
+   * @assertion_ids: EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is an Short, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Short "<" & "lt" Short Short "<" & "lt"
+   *                 Byte
+   */
+  @Test
+  public void elShortLessThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("2"), false, "<");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("1"), false, "<");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("-2"), true, "lt");
+
+  }
+
+  /**
+   * @testName: elShortLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is an Short, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Short "<=" & "le" Short Short "<=" & "le"
+   *                 Byte
+   */
+  @Test
+  public void elShortLessThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("2"), false, "<=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("1"), true, "le");
+
+    // Value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("-2"), true, "<=");
+  }
+
+  /**
+   * @testName: elShortGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is an Short, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Short ">" & "gt" Short Short ">" & "gt"
+   *                 Byte
+   */
+  @Test
+  public void elShortGreaterThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("2"), true, ">");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("1"), false, ">");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("-2"), false, "gt");
+
+  }
+
+  /**
+   * @testName: elShortGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is an Short, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Short ">=" & "ge" Short Short ">=" & "ge"
+   *                 Byte
+   */
+  @Test
+  public void elShortGreaterThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("2"), true, ">=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("1"), true, "ge");
+
+    // value passed in is smaller than the COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("-2"), false, "ge");
+
+  }
+
+  /**
+   * @testName: elShortEqualToTest
+   * @assertion_ids: EL:SPEC:22.1; EL:SPEC:22.6
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is an Short, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Short "==" & "eq" Short Short "==" & "eq"
+   *                 Byte
+   */
+  @Test
+  public void elShortEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("2"), false, "==");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("1"), true, "eq");
+
+  }
+
+  /**
+   * @testName: elShortNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.6
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is an Short, the result is coerced to Long and
+   *                 the correct boolean value is returned.
+   * 
+   *                 Equations tested: Short "!=" & "ne" Short Short "!=" & "ne"
+   *                 Byte
+   */
+  @Test
+  public void elShortNotEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("2"), true, "!=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Short.valueOf("1"), false, "ne");
+
+  }
+
+  /**
+   * @testName: elByteLessThanTest
+   * @assertion_ids: EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is an Byte, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Byte "<" & "lt" Byte
+   */
+  @Test
+  public void elByteLessThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("2"), false, "<");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("1"), false, "lt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("-2"), true, "lt");
+
+  }
+
+  /**
+   * @testName: elByteLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is an Byte, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Byte "<=" & "le" Byte
+   */
+  @Test
+  public void elByteLessThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("2"), false, "<=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("1"), true, "le");
+
+    // Value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("-2"), true, "<=");
+  }
+
+  /**
+   * @testName: elByteGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.1
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is an Byte, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Byte ">" & "gt" Byte
+   */
+  @Test
+  public void elByteGreaterThanTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("2"), true, ">");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("1"), false, "gt");
+
+    // value passed in is smaller than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("-2"), false, "gt");
+
+  }
+
+  /**
+   * @testName: elByteGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.1; EL:SPEC:21.6
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is an Byte, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Byte ">=" & "ge" Byte
+   */
+  @Test
+  public void elByteGreaterThanEqualTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("2"), true, ">=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("1"), true, "ge");
+
+    // value passed in is smaller than the COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("-2"), false, "ge");
+
+  }
+
+  /**
+   * @testName: elByteEqualToTest
+   * @assertion_ids: EL:SPEC:22.1; EL:SPEC:22.6
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is an Byte, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Byte "==" & "eq" Byte
+   */
+  @Test
+  public void elByteEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("2"), false, "==");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("1"), true, "eq");
+
+  }
+
+  /**
+   * @testName: elByteNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.6
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is an Byte, the result is coerced to Long and the
+   *                 correct boolean value is returned.
+   * 
+   *                 Equations tested: Byte "!=" & "ne" Byte
+   */
+  @Test
+  public void elByteNotEqualToTest() throws Exception {
+
+    // Value passed in is larger than COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("2"), true, "!=");
+
+    // value passed in is equal to the COMPARATOR.
+    this.testOperatorBoolean(Byte.valueOf("1"), false, "ne");
+
+  }
+
+  /**
+   * @testName: elStringLessThanTest
+   * @assertion_ids: EL:SPEC:21.7
+   * @test_Strategy: Validate that if one of the operands in an EL "<" or "lt"
+   *                 operation is an String, that both operands are coerced to
+   *                 type String and the correct boolean value is returned.
+   * 
+   *                 Equations tested: String "<" & "lt" String
+   */
+  @Test
+  public void elStringLessThanTest() throws Exception {
+
+    // Value A is less than value B. (true)
+    this.testOperatorBoolean("Alpha", DT, true, "<");
+
+    // Value A is less than value B. (false)
+    this.testOperatorBoolean("Beta", DT, false, "lt");
+
+    // Value A is less than value B. (true)
+    this.testOperatorBoolean("Gamma", DT, false, "lt");
+
+  }
+
+  /**
+   * @testName: elStringLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.7
+   * @test_Strategy: Validate that if one of the operands in an EL "<=" or "le"
+   *                 operation is a String, that both operands are coerced to
+   *                 type String and the correct boolean value is returned.
+   * 
+   *                 Equations tested: String "<=" & "le" String
+   */
+  @Test
+  public void elStringLessThanEqualTest() throws Exception {
+
+    // Value A is less than or equal to value B. (false)
+    this.testOperatorBoolean("Gamma", DT, false, "<=");
+
+    // Value A is less than or equal to value B. (true)
+    this.testOperatorBoolean("Beta", DT, true, "le");
+
+    // Value A is less than or equal to value B. (true)
+    this.testOperatorBoolean("Alpha", DT, true, "<=");
+  }
+
+  /**
+   * @testName: elStringGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.7
+   * @test_Strategy: Validate that if one of the operands in an EL ">" or "gt"
+   *                 operation is an String, that both operands are coerced to
+   *                 type String and the correct boolean value is returned.
+   * 
+   *                 Equations tested: String ">" & "gt" String
+   */
+  @Test
+  public void elStringGreaterThanTest() throws Exception {
+
+    // Value A is greater than value B. (false)
+    this.testOperatorBoolean("Gamma", DT, true, ">");
+
+    // Value A greater than value B. (false)
+    this.testOperatorBoolean("Beta", DT, false, "gt");
+
+    // Value A is greater than value B. (false)
+    this.testOperatorBoolean("Alpha", DT, false, "gt");
+
+  }
+
+  /**
+   * @testName: elStringGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.7
+   * @test_Strategy: Validate that if one of the operands in an EL ">=" or "ge"
+   *                 operation is an String, that both operands are coerced to
+   *                 type String and the correct boolean value is returned.
+   * 
+   *                 Equations tested: String ">=" & "ge" String
+   */
+  @Test
+  public void elStringGreaterThanEqualTest() throws Exception {
+
+    // Value A is greater than or equal to value B. (true)
+    this.testOperatorBoolean("Gamma", DT, true, ">=");
+
+    // Value A is greater than or equal to value B. (true)
+    this.testOperatorBoolean("Beta", DT, true, "ge");
+
+    // Value A is greater than or equal to value B. (false)
+    this.testOperatorBoolean("Alpha", DT, false, "ge");
+
+  }
+
+  /**
+   * @testName: elStringEqualToTest
+   * @assertion_ids: EL:SPEC:22.9
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is an String, that both operands are coerced to
+   *                 type String and the correct boolean value is returned.
+   * 
+   *                 Equations tested: String "==" & "eq" String
+   */
+  @Test
+  public void elStringEqualToTest() throws Exception {
+
+    // Value A is equal to value B. (true)
+    this.testOperatorBoolean("Beta", DT, true, "==");
+
+    // Value A is smaller than value B. (false)
+    this.testOperatorBoolean("Alpha", DT, false, "eq");
+
+  }
+
+  /**
+   * @testName: elStringNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.9
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is an String, that both operands are coerced to
+   *                 type String and the correct boolean value is returned.
+   * 
+   *                 Equations tested: String "!=" & "ne" String
+   */
+  @Test
+  public void elStringNotEqualToTest() throws Exception {
+
+    // Value A is not equal to value B. (true)
+    this.testOperatorBoolean("Alpha", DT, true, "!=");
+
+    // Value A is not equal to value B. (false)
+    this.testOperatorBoolean("Beta", DT, false, "ne");
+
+  }
+
+  /**
+   * @testName: elOtherLessThanTest
+   * @assertion_ids: EL:SPEC:21.8.2
+   * @test_Strategy: Validate that if operand A in an EL "<" or "lt" operation
+   *                 is comparable, the result A.compareTo(B) is returned.
+   * 
+   *                 Equation example: DougType "<" & "lt" NickType
+   */
+  @Test
+  public void elOtherLessThanTest() throws Exception {
+
+    // Value A is less than value B. (true)
+    this.testOperatorBoolean(DT, NT, true, "<");
+
+    // Value A is less than value B. (false)
+    this.testOperatorBoolean(DT, DT, false, "lt");
+
+    // Value A is less than value B. (false)
+    this.testOperatorBoolean(NT, DT, false, "lt");
+
+  }
+
+  /**
+   * @testName: elOtherLessThanEqualTest
+   * @assertion_ids: EL:SPEC:21.8.2
+   * @test_Strategy: Validate that if operand A in an EL "<=" or "le" operation
+   *                 is comparable, the result A.compareTo(B) is returned.
+   * 
+   *                 Equation example: DougType "<=" & "le" NickType
+   */
+  @Test
+  public void elOtherLessThanEqualTest() throws Exception {
+
+    // Value A is less than or equal to value B. (false)
+    this.testOperatorBoolean(NT, DT, false, "<=");
+
+    // Value A is less than or equal to value B. (true)
+    this.testOperatorBoolean(DT, DT, true, "le");
+
+    // Value A is less than or equal to value B. (true)
+    this.testOperatorBoolean(DT, NT, true, "<=");
+  }
+
+  /**
+   * @testName: elOtherGreaterThanTest
+   * @assertion_ids: EL:SPEC:21.8.2
+   * @test_Strategy: Validate that if operand A in an EL ">" or "gt" operation
+   *                 is comparable, the result A.compareTo(B) is returned.
+   * 
+   *                 Equation example: DougType "<" & "gt" NickType
+   */
+  @Test
+  public void elOtherGreaterThanTest() throws Exception {
+
+    // Value A is greater than value B. (true)
+    this.testOperatorBoolean(NT, DT, true, ">");
+
+    // Value A greater than value B. (false)
+    this.testOperatorBoolean(DT, DT, false, "gt");
+
+    // Value A is greater than value B. (false)
+    this.testOperatorBoolean(DT, NT, false, "gt");
+
+  }
+
+  /**
+   * @testName: elOtherGreaterThanEqualTest
+   * @assertion_ids: EL:SPEC:21.8.2
+   * @test_Strategy: Validate that if operand A in an EL ">=" or "ge" operation
+   *                 is comparable, the result A.compareTo(B) is returned.
+   * 
+   *                 Equations tested: DougType ">=" & "ge" NickType
+   */
+  @Test
+  public void elOtherGreaterThanEqualTest() throws Exception {
+
+    // Value A is greater than or equal to value B. (true)
+    this.testOperatorBoolean(NT, DT, true, ">=");
+
+    // Value A is greater than or equal to value B. (true)
+    this.testOperatorBoolean(DT, DT, true, "ge");
+
+    // Value A is greater than or equal to value B. (false)
+    this.testOperatorBoolean(DT, NT, false, "ge");
+
+  }
+
+  /**
+   * @testName: elOtherEqualToTest
+   * @assertion_ids: EL:SPEC:22.11
+   * @test_Strategy: Validate that if operand A in an EL "==" or "eq" operation
+   *                 is comparable, the result A.equals(B) is returned.
+   * 
+   *                 Equations Example: DougType "==" & "eq" NickType
+   */
+  @Test
+  public void elOtherEqualToTest() throws Exception {
+
+    // Value A is equal to value B. (true)
+    this.testOperatorBoolean(DT, DT, true, "==");
+
+    // Value A is smaller than value B. (false)
+    this.testOperatorBoolean(DT, NT, false, "eq");
+
+  }
+
+  /**
+   * @testName: elOtherNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.11
+   * @test_Strategy: Validate that if operand A in an EL "!=" or "ne" operation
+   *                 is comparable, the result A.equals(B) is returned.
+   * 
+   *                 Equation Example: DougType "!=" & "ne" NickType
+   */
+  @Test
+  public void elOtherNotEqualToTest() throws Exception {
+
+    // Value A is not equal to value B. (true)
+    this.testOperatorBoolean(DT, NT, true, "!=");
+
+    // Value A is not equal to value B. (false)
+    this.testOperatorBoolean(DT, DT, false, "ne");
+
+  }
+
+  /**
+   * @testName: elBooleanEqualToTest
+   * @assertion_ids: EL:SPEC:22.7
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is an Boolean, that both operands are coerced to
+   *                 type Boolean and the correct boolean value is returned.
+   * 
+   *                 Equations tested: Boolean "==" & "eq" String
+   */
+  @Test
+  public void elBooleanEqualToTest() throws Exception {
+
+    // Value A is equal to value B. (true)
+    this.testOperatorBoolean("true", true, true, "==");
+
+    // Value A is smaller than value B. (false)
+    this.testOperatorBoolean("false", true, false, "eq");
+
+  }
+
+  /**
+   * @testName: elBooleanNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.7
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is an Boolean, that both operands are coerced to
+   *                 type Boolean and the correct boolean value is returned.
+   * 
+   *                 Equations tested: String "!=" & "ne" String
+   */
+  @Test
+  public void elBooleanNotEqualToTest() throws Exception {
+
+    // Value A is not equal to value B. (true)
+    this.testOperatorBoolean("false", true, true, "!=");
+
+    // Value A is not equal to value B. (false)
+    this.testOperatorBoolean("false", false, false, "ne");
+
+  }
+
+  /**
+   * @testName: elEnumEqualToTest
+   * @assertion_ids: EL:SPEC:22.8
+   * @test_Strategy: Validate that if one of the operands in an EL "==" or "eq"
+   *                 operation is an Enum, that both operands are coerced to
+   *                 type Enum and the correct boolean value is returned.
+   * 
+   *                 Example Equation: Enum "==" String or Integer
+   */
+  @Test
+  public void elEnumEqualToTest() throws Exception {
+
+    // Value A is equal to value B. (true)
+    this.testOperatorBoolean(TestEnum.APPLE, "APPLE", true, "==");
+    this.testOperatorBoolean(TestEnum.PEAR, "PEAR", true, "eq");
+
+    // Value A is not equal to value B. (false)
+    this.testOperatorBoolean(TestEnum.PEAR, "APPLE", false, "==");
+    this.testOperatorBoolean(TestEnum.APPLE, "PEAR", false, "eq");
+  }
+
+  /**
+   * @testName: elEnumNotEqualToTest
+   * @assertion_ids: EL:SPEC:22.8
+   * @test_Strategy: Validate that if one of the operands in an EL "!=" or "ne"
+   *                 operation is an Enum, that both operands are coerced to
+   *                 type String and the correct boolean value is returned.
+   * 
+   *                 Example Equation: Enum "!=" & "ne" Enum
+   */
+  @Test
+  public void elEnumNotEqualToTest() throws Exception {
+
+    // Value A is not equal to value B. (true)
+    this.testOperatorBoolean(TestEnum.APPLE, "PEAR", true, "!=");
+    this.testOperatorBoolean(TestEnum.PEAR, "APPLE", true, "ne");
+
+    // Value A is not equal to value B. (false)
+    this.testOperatorBoolean(TestEnum.APPLE, "APPLE", false, "!=");
+    this.testOperatorBoolean(TestEnum.PEAR, "PEAR", false, "ne");
+  }
+
+  // ---------------------------------------------------------- private
+  // methods
+
+  /**
+   * This method is used to validate an expression that has at least one
+   * BigDecimal in it. We pass in one of the operands(testVal), the other
+   * operand is automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. ">, >=,
+   *          <, <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(BigDecimal testVal, Boolean expectedVal,
+      String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    for (int i = 0; numberList.size() > i; i++) {
+      logger.log(Logger.Level.TRACE, 
+          "*** Start " + "\"" + "BigDecimal" + "\"" + " Test Sequence ***");
+
+      Object testNum = numberList.get(i);
+
+      // We don't test numeric strings
+      if (!(testNum instanceof Number))
+        continue;
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(false, booleanOperator);
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.TRACE, "types are " + "BigDecimal" + " and "
+            + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && (((Boolean) result).equals(expectedVal)));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.TRACE, 
+            "*** End " + "\"" + "BigDecimal" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one
+   * BigInteger in it. We pass in one of the operands(testVal), the other
+   * operand is automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. >, >=, <,
+   *          <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(BigInteger testVal, Boolean expectedVal,
+      String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    for (int i = 0; numberList.size() > i; i++) {
+      logger.log(Logger.Level.TRACE, 
+          "*** Start " + "\"" + "BigInteger" + "\"" + " Test Sequence ***");
+
+      Object testNum = numberList.get(i);
+
+      // We don't test numeric strings
+      if (!(testNum instanceof Number))
+        continue;
+
+      if ((testNum instanceof BigDecimal) || (testNum instanceof Float)
+          || (testNum instanceof Double)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.TRACE, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(false, booleanOperator);
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.TRACE, "types are " + "BigInteger" + " and "
+            + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && (((Boolean) result).equals(expectedVal)));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.TRACE, 
+            "*** End " + "\"" + "BigInteger" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one Float
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. ">, >=,
+   *          <, <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(Float testVal, Boolean expectedVal,
+      String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    for (int i = 0; numberList.size() > i; i++) {
+      logger.log(Logger.Level.TRACE, 
+          "*** Start " + "\"" + "Float" + "\"" + " Test Sequence ***");
+
+      Object testNum = numberList.get(i);
+
+      // We don't test numeric strings
+      if (!(testNum instanceof Number))
+        continue;
+
+      if ((testNum instanceof BigDecimal)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.TRACE, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(false, booleanOperator);
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.TRACE, 
+            "types are " + "Float" + " and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && (((Boolean) result).equals(expectedVal)));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.TRACE, 
+            "*** End " + "\"" + "Float" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one Double
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. ">, >=,
+   *          <, <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(Double testVal, Boolean expectedVal,
+      String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    for (int i = 0; numberList.size() > i; i++) {
+      logger.log(Logger.Level.TRACE, 
+          "*** Start " + "\"" + "Double" + "\"" + " Test Sequence ***");
+
+      Object testNum = numberList.get(i);
+
+      // We don't test numeric strings
+      if (!(testNum instanceof Number))
+        continue;
+
+      if ((testNum instanceof BigDecimal || testNum instanceof Float)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.TRACE, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(false, booleanOperator);
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.TRACE, 
+            "types are " + "Double" + " and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && (((Boolean) result).equals(expectedVal)));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.TRACE, 
+            "*** End " + "\"" + "Double" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one Long in
+   * it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. ">, >=,
+   *          <, <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(Long testVal, Boolean expectedVal,
+      String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    for (int i = 0; numberList.size() > i; i++) {
+      logger.log(Logger.Level.TRACE, "*** Start " + "\"" + "Long" + "\"" + " Test Sequence ***");
+
+      Object testNum = numberList.get(i);
+
+      // We don't test numeric strings
+      if (!(testNum instanceof Number))
+        continue;
+
+      if ((testNum instanceof BigDecimal || testNum instanceof Float
+          || testNum instanceof BigInteger || testNum instanceof Double)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.TRACE, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(false, booleanOperator);
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.TRACE, 
+            "types are " + "Long" + " and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && (((Boolean) result).equals(expectedVal)));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.TRACE, "*** End " + "\"" + "Long" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one Integer
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. ">, >=,
+   *          <, <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(Integer testVal, Boolean expectedVal,
+      String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    for (int i = 0; numberList.size() > i; i++) {
+      logger.log(Logger.Level.TRACE, 
+          "*** Start " + "\"" + "Integer" + "\"" + " Test Sequence ***");
+
+      Object testNum = numberList.get(i);
+
+      // We don't test numeric strings
+      if (!(testNum instanceof Number))
+        continue;
+
+      if ((testNum instanceof BigDecimal || testNum instanceof Float
+          || testNum instanceof BigInteger || testNum instanceof Long
+          || testNum instanceof Double)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.TRACE, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(false, booleanOperator);
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.TRACE, 
+            "types are " + "Integer" + " and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && (((Boolean) result).equals(expectedVal)));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.TRACE, 
+            "*** End " + "\"" + "Integer" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one Short
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. ">, >=,
+   *          <, <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(Short testVal, Boolean expectedVal,
+      String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    for (int i = 0; numberList.size() > i; i++) {
+      logger.log(Logger.Level.TRACE, 
+          "*** Start " + "\"" + "Short" + "\"" + " Test Sequence ***");
+
+      Object testNum = numberList.get(i);
+
+      if (!(testNum instanceof Short || testNum instanceof Byte)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.TRACE, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(false, booleanOperator);
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.TRACE, 
+            "types are " + "Short" + " and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && (((Boolean) result).equals(expectedVal)));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.TRACE, 
+            "*** End " + "\"" + "Short" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one Byte in
+   * it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. >, >=, <,
+   *          <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(Byte testVal, Boolean expectedVal,
+      String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    for (int i = 0; numberList.size() > i; i++) {
+      logger.log(Logger.Level.TRACE, "*** Start " + "\"" + "Byte" + "\"" + " Test Sequence ***");
+
+      Object testNum = numberList.get(i);
+
+      if (!(testNum instanceof Byte)) {
+        String skipType = testNum.getClass().getSimpleName();
+        logger.log(Logger.Level.TRACE, "Skip " + skipType + " Data type already "
+            + "tested for this in the " + skipType + " tests.");
+        continue;
+      }
+
+      NameValuePair values[] = NameValuePair.buildNameValuePair(testVal,
+          testNum);
+
+      try {
+        String expr = ExprEval.buildElExpr(false, booleanOperator);
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+        logger.log(Logger.Level.TRACE, 
+            "types are " + "Byte" + " and " + testNum.getClass().getName());
+
+        Object result = ExprEval.evaluateValueExpression(expr, values,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+        pass = (ExprEval.compareClass(result, Boolean.class)
+            && (((Boolean) result).equals(expectedVal)));
+
+      } catch (Exception e) {
+        throw new Exception(e);
+
+      } finally {
+        ExprEval.cleanup();
+        logger.log(Logger.Level.TRACE, "*** End " + "\"" + "Byte" + "\"" + " Test Sequence ***");
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    }
+  }
+
+  /**
+   * This method is used to validate an expression that has at least one String
+   * in it. We pass in one of the operands(testVal), the other operand is
+   * automatically picked up from the numberList.
+   * 
+   * @param testVal
+   *          - One of the operands used in the expression.
+   * @param expectedVal
+   *          - expected result.
+   * @param booleanOperator
+   *          - The operator in which the operands are compared. (i.e. ">, >=,
+   *          <, <=, gt, ge, lt, le, ==, !=, eq, ne)
+   */
+  private void testOperatorBoolean(Object testValOne, Object testValTwo,
+      Boolean expectedVal, String booleanOperator) throws Exception {
+
+    boolean pass;
+
+    NameValuePair values[] = NameValuePair.buildNameValuePair(testValOne,
+        testValTwo);
+
+    try {
+      logger.log(Logger.Level.TRACE, 
+          "*** Start " + "\"" + "String" + "\"" + " Test Sequence ***");
+
+      String expr = ExprEval.buildElExpr(false, booleanOperator);
+      logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+      logger.log(Logger.Level.TRACE, "types are " + "String and String");
+
+      Object result = ExprEval.evaluateValueExpression(expr, values,
+          Object.class);
+
+      logger.log(Logger.Level.TRACE, "result is " + result.toString());
+
+      pass = (ExprEval.compareClass(result, Boolean.class)
+          && (((Boolean) result).equals(expectedVal)));
+
+    } catch (Exception e) {
+      throw new Exception(e);
+
+    } finally {
+      ExprEval.cleanup();
+      logger.log(Logger.Level.TRACE, "*** End " + "\"" + "String" + "\"" + " Test Sequence ***");
+    }
+
+    if (!pass)
+      throw new Exception("TEST FAILED: pass = false");
+
+  }
+
+  // ---------------------------------------------------- Inner Classes
+
+  private static class DougType implements Comparable {
+
+    @Override
+    public String toString() {
+
+      return "Beta";
+    }
+
+    public int compareTo(Object o) {
+
+      if (o == null)
+        return -1;
+      return this.toString().compareTo(o.toString());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+
+      // test for null.
+      if (o == null)
+        return false;
+
+      /*
+       * Since all DougType are staticly set to "Beta" All DougTypes are
+       * considered equal, and any other object is not.
+       */
+      return (o instanceof DougType);
+
+    }
+
+    @Override
+    public int hashCode() {
+      return 42;
+    }
+
+  }
+
+  private static class NickType implements Comparable {
+
+    @Override
+    public String toString() {
+      return "Gamma";
+    }
+
+    public int compareTo(Object o) {
+
+      if (o == null)
+        return -1;
+      return this.toString().compareTo(o.toString());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+
+      // test for null.
+      if (o == null)
+        return false;
+
+      /*
+       * Since all NickType are statically set to "Gamma" All NickTypes are
+       * considered equal, and any other object is not.
+       */
+      return (o instanceof NickType);
+
+    }
+
+    @Override
+    public int hashCode() {
+      return 42;
+    }
+
+  }
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/semicolonoperator/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/semicolonoperator/ELClientIT.java
new file mode 100644
index 0000000..1f33b49
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/semicolonoperator/ELClientIT.java
@@ -0,0 +1,871 @@
+/*
+ * Copyright (c) 2012, 2020 Oracle and/or its affiliates and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.semicolonoperator;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.TypesBean;
+import com.sun.ts.tests.el.common.util.Validator;
+
+import jakarta.el.ELProcessor;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+ 
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /**
+   * @testName: elSemiColonOperatorBigDecimalTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: To evaluate A;B, A is first evaluated, and its value is
+   *                 discarded. B is then evaluated and its value is returned.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = types.tckBigDecimal; a [operator] b"
+   * 
+   *                 Variable A - BigDecimal
+   * 
+   *                 Variable B - Rotating through the following types:
+   *                 BigDecimal, BigInteger, Integer, Float, Long, Short,
+   *                 Double, Byte
+   * 
+   *                 Excluded: none
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorBigDecimalTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "BigDecimal";
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+      elp.eval(bValue);
+
+      // (+ operator)
+      Validator.testExpression(elp, "a = types.tckBigDecimal; a + b",
+          BigDecimal.valueOf(2), comparitorA + " + " + bName);
+
+      // (* operator)
+      Validator.testExpression(elp, "a = types.tckBigDecimal; a * b",
+          BigDecimal.valueOf(1), comparitorA + " * " + bName);
+
+      // (- operator)
+      Validator.testExpression(elp, "a = types.tckBigDecimal; a - b",
+          BigDecimal.valueOf(0), comparitorA + " - " + bName);
+
+      // (/ operator)
+      Validator.testExpression(elp, "a = types.tckBigDecimal; a / b",
+          BigDecimal.valueOf(1), comparitorA + " / " + bName);
+
+      // (div operator)
+      Validator.testExpression(elp, "a = types.tckBigDecimal; a div b",
+          BigDecimal.valueOf(1), comparitorA + " div " + bName);
+
+      // (% operator)
+      Validator.testExpression(elp, "a = types.tckBigDecimal; a % b",
+          Double.valueOf(0), comparitorA + " % " + bName);
+
+      // (mod operator)
+      Validator.testExpression(elp, "a = types.tckBigDecimal; a mod b",
+          Double.valueOf(0), comparitorA + " mod " + bName);
+
+      // Clean variables...
+      elp.eval("a = null");
+      elp.eval("b = null");
+    }
+
+  } // End elSemiColonOperatorBigDecimalTest
+
+  /**
+   * @testName: elSemiColonOperatorFloatTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = types.tckFloat; a [operator] b"
+   * 
+   *                 Variable A - Float
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorFloatTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Float";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if (excludeList.contains(bName)) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        elp.eval(bValue);
+
+        if ("BigInteger".equals(bName)) {
+          // (+ operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a + b",
+              BigDecimal.valueOf(2), comparitorA + " + " + bName);
+
+          // (* operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a * b",
+              BigDecimal.valueOf(1), comparitorA + " * " + bName);
+
+          // (- operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a - b",
+              BigDecimal.valueOf(0), comparitorA + " - " + bName);
+
+          // (/ operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a / b",
+              BigDecimal.valueOf(1), comparitorA + " / " + bName);
+
+          // (div operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a div b",
+              BigDecimal.valueOf(1), comparitorA + " div " + bName);
+
+        } else {
+          // (+ operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a + b",
+              Double.valueOf(2), comparitorA + " + " + bName);
+
+          // (* operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a * b",
+              Double.valueOf(1), comparitorA + " * " + bName);
+
+          // (- operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a - b",
+              Double.valueOf(0), comparitorA + " - " + bName);
+
+          // (/ operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a / b",
+              Double.valueOf(1), comparitorA + " / " + bName);
+
+          // (div operator)
+          Validator.testExpression(elp, "a = types.tckFloat; a div b",
+              Double.valueOf(1), comparitorA + " div " + bName);
+
+        }
+
+        // The same for all other tested data types.
+
+        // (% operator)
+        Validator.testExpression(elp, "a = types.tckFloat; a % b",
+            Double.valueOf(0), comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a = types.tckFloat; a mod b",
+            Double.valueOf(0), comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elSemiColonOperatorFloatTest
+
+  /**
+   * @testName: elSemiColonOperatorDoubleTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = types.tckDouble; a [operator] b"
+   * 
+   *                 Variable A - Double
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, Float
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorDoubleTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Double";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if (excludeList.contains(bName)) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        elp.eval(bValue);
+
+        if ("BigInteger".equals(bName)) {
+          // (+ operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a + b",
+              BigDecimal.valueOf(2), comparitorA + " + " + bName);
+
+          // (* operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a * b",
+              BigDecimal.valueOf(1), comparitorA + " * " + bName);
+
+          // (- operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a - b",
+              BigDecimal.valueOf(0), comparitorA + " - " + bName);
+
+          // (/ operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a / b",
+              BigDecimal.valueOf(1), comparitorA + " / " + bName);
+
+          // (div operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a div b",
+              BigDecimal.valueOf(1), comparitorA + " div " + bName);
+
+        } else {
+          // (+ operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a + b",
+              Double.valueOf(2), comparitorA + " + " + bName);
+
+          // (* operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a * b",
+              Double.valueOf(1), comparitorA + " * " + bName);
+
+          // (- operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a - b",
+              Double.valueOf(0), comparitorA + " - " + bName);
+
+          // (/ operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a / b",
+              Double.valueOf(1), comparitorA + " / " + bName);
+
+          // (div operator)
+          Validator.testExpression(elp, "a = types.tckDouble; a div b",
+              Double.valueOf(1), comparitorA + " div " + bName);
+
+        }
+
+        // The same for all other tested data types.
+
+        // (% operator)
+        Validator.testExpression(elp, "a = types.tckDouble; a % b",
+            Double.valueOf(0), comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a = types.tckDouble; a mod b",
+            Double.valueOf(0), comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elSemiColonOperatorDoubleTest
+
+  /**
+   * @testName: elSemiColonOperatorBigIntegerTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = types.tckBigInteger; a [operator] b"
+   * 
+   *                 Variable A - BigInteger
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, Float, Double
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorBigIntegerTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "BigInteger";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a = types.tckBigInteger; a + b",
+            BigInteger.valueOf(2), comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a = types.tckBigInteger; a * b",
+            BigInteger.valueOf(1), comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a = types.tckBigInteger; a - b",
+            BigInteger.valueOf(0), comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a = types.tckBigInteger; a / b",
+            BigDecimal.valueOf(1), comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a = types.tckBigInteger; a div b",
+            BigDecimal.valueOf(1), comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a = types.tckBigInteger; a % b",
+            BigInteger.valueOf(0), comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a = types.tckBigInteger; a mod b",
+            BigInteger.valueOf(0), comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elSemiColonOperatorBigIntegerTest
+
+  /**
+   * @testName: elSemiColonOperatorIntegerTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = types.tckInteger; a [operator] b"
+   * 
+   *                 Variable A - Integer
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorIntegerTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Integer";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a = types.tckInteger; a + b",
+            Long.valueOf(2), comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a = types.tckInteger; a * b",
+            Long.valueOf(1), comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a = types.tckInteger; a - b",
+            Long.valueOf(0), comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a = types.tckInteger; a / b",
+            Double.valueOf(1), comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a = types.tckInteger; a div b",
+            Double.valueOf(1), comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a = types.tckInteger; a % b",
+            Long.valueOf(0), comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a = types.tckInteger; a mod b",
+            Long.valueOf(0), comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elSemiColonOperatorIntegerTest
+
+  /**
+   * @testName: elSemiColonOperatorLongTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = types.tckLong; a [operator] b"
+   * 
+   *                 Variable A - Long
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorLongTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Long";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a = types.tckLong; a + b",
+            Long.valueOf(2), comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a = types.tckLong; a * b",
+            Long.valueOf(1), comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a = types.tckLong; a - b",
+            Long.valueOf(0), comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a = types.tckLong; a / b",
+            Double.valueOf(1), comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a = types.tckLong; a div b",
+            Double.valueOf(1), comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a = types.tckLong; a % b",
+            Long.valueOf(0), comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a = types.tckLong; a mod b",
+            Long.valueOf(0), comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elSemiColonOperatorLongTest
+
+  /**
+   * @testName: elSemiColonOperatorShortTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = types.tckShort; a [operator] b"
+   * 
+   *                 Variable A - Short
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer,
+   *                 Long
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorShortTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Short";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+    excludeList.add("Long");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a = types.tckShort; a + b",
+            Long.valueOf(2), comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a = types.tckShort; a * b",
+            Long.valueOf(1), comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a = types.tckShort; a - b",
+            Long.valueOf(0), comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a = types.tckShort; a / b",
+            Double.valueOf(1), comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a = types.tckShort; a div b",
+            Double.valueOf(1), comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a = types.tckShort; a % b",
+            Long.valueOf(0), comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a mod b", Long.valueOf(0),
+            comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elSemiColonOperatorShortTest
+
+  /**
+   * @testName: elSemiColonOperatorByteTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = types.tckByte; a [operator] b"
+   * 
+   *                 Variable A - Byte
+   * 
+   *                 Variable B - Rotating through the following types: Integer,
+   *                 Float, Long, Short, Double, Byte
+   * 
+   *                 Exclude: BigDecimal, BigInteger, Float, Double, Integer,
+   *                 Long, Short
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorByteTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    String comparitorA = "Byte";
+
+    // excluded data types.
+    List<String> excludeList = new ArrayList<String>();
+    excludeList.add("BigDecimal");
+    excludeList.add("BigInteger");
+    excludeList.add("Integer");
+    excludeList.add("Double");
+    excludeList.add("Float");
+    excludeList.add("Long");
+    excludeList.add("Short");
+
+    Iterator<Class<?>> iter;
+
+    elp.defineBean("types", new TypesBean());
+
+    iter = TypesBean.getNumberMap().keySet().iterator();
+    while (iter.hasNext()) {
+      Class<?> bType = iter.next();
+      String bValue = TypesBean.getNumberMap().get(bType);
+      String bName = bType.getSimpleName();
+
+      if ((excludeList.contains(bName))) {
+        logger.log(Logger.Level.TRACE, "*** Skipping " + comparitorA + " with " + bName
+            + ", Already Tested in " + bName + " Test Sequence ***");
+
+      } else {
+        elp.eval(bValue);
+
+        // (+ operator)
+        Validator.testExpression(elp, "a = types.tckByte; a + b",
+            Long.valueOf(2), comparitorA + " + " + bName);
+
+        // (* operator)
+        Validator.testExpression(elp, "a = types.tckByte; a * b",
+            Long.valueOf(1), comparitorA + " * " + bName);
+
+        // (- operator)
+        Validator.testExpression(elp, "a = types.tckByte; a - b",
+            Long.valueOf(0), comparitorA + " - " + bName);
+
+        // (/ operator)
+        Validator.testExpression(elp, "a = types.tckByte; a / b",
+            Double.valueOf(1), comparitorA + " / " + bName);
+
+        // (div operator)
+        Validator.testExpression(elp, "a = types.tckByte; a div b",
+            Double.valueOf(1), comparitorA + " div " + bName);
+
+        // (% operator)
+        Validator.testExpression(elp, "a = types.tckByte; a % b",
+            Long.valueOf(0), comparitorA + " % " + bName);
+
+        // (mod operator)
+        Validator.testExpression(elp, "a = types.tckByte; a mod b",
+            Long.valueOf(0), comparitorA + " mod " + bName);
+
+        // Clean variables...
+        elp.eval("a = null");
+        elp.eval("b = null");
+      }
+    }
+
+  } // End elSemiColonOperatorByteTest
+
+  /**
+   * @testName: elSemiColonOperatorNullTest
+   * 
+   * @assertion_ids: EL:SPEC:49.1
+   * 
+   * @test_Strategy: Validate that when we have variable A set to a specific
+   *                 data type that we coerce and receive back the correct value
+   *                 and Class type.
+   * 
+   *                 Operators: +, -, *, /, div, %, mod
+   * 
+   *                 Expression: "a = null; a [operator] b"
+   * 
+   *                 Variable A - null
+   * 
+   *                 Variable B - null
+   * 
+   * @since: 3.0
+   * 
+   */
+  @Test
+  public void elSemiColonOperatorNullTest() throws Exception {
+
+    ELProcessor elp = new ELProcessor();
+    elp.defineBean("types", new TypesBean());
+
+    Long expected = Long.valueOf(0);
+    String bValue = "b = types.tckNull";
+
+    elp.eval(bValue);
+
+    // (+ operator)
+    Validator.testExpression(elp, "a = null; a + b", expected, "null + null");
+
+    // (- operator)
+    Validator.testExpression(elp, "a = null; a - b", expected, "null - null");
+
+    // (* operator)
+    Validator.testExpression(elp, "a = null; a * b", expected, "null * null");
+
+    // (/ operator)
+    Validator.testExpression(elp, "a = null; a / b", expected, "null / null");
+
+    // (div operator)
+    Validator.testExpression(elp, "a = null; a div b", expected,
+        "null div null");
+
+    // (% operator)
+    Validator.testExpression(elp, "a = null; a % b", expected, "null % null");
+
+    // (mod operator)
+    Validator.testExpression(elp, "a = null; a mod b", expected,
+        "null mod null");
+
+  } // End elSemiColonOperatorNullTest
+
+}
diff --git a/tck/src/main/java/com/sun/ts/tests/el/spec/unaryoperator/ELClientIT.java b/tck/src/main/java/com/sun/ts/tests/el/spec/unaryoperator/ELClientIT.java
new file mode 100644
index 0000000..75c0dd9
--- /dev/null
+++ b/tck/src/main/java/com/sun/ts/tests/el/spec/unaryoperator/ELClientIT.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package com.sun.ts.tests.el.spec.unaryoperator;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Properties;
+
+
+import com.sun.ts.tests.el.common.util.ExprEval;
+import com.sun.ts.tests.el.common.util.NameValuePair;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.lang.System.Logger;
+
+public class ELClientIT {
+
+  private static final Logger logger = System.getLogger(ELClientIT.class.getName());
+
+  private final boolean[] deferred = { true, false };
+
+  @AfterEach
+  public void cleanup() throws Exception {
+    logger.log(Logger.Level.INFO, "Cleanup method called");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    logger.log(Logger.Level.INFO, "FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /*
+   * @testName: elNullUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.1
+   * 
+   * @test_Strategy: Validate that if null is passed with the unary minus
+   * operator, the result is (Long) 0. Test both ${-null} & #{-null}
+   */
+  @Test
+  public void elNullUnaryTest() throws Exception {
+
+    boolean pass = false;
+    String[] symbols = { "$", "#" };
+
+    Long expectedResult = Long.valueOf("0");
+
+    try {
+      for (String prefix : symbols) {
+        String expr = prefix + "{-null}";
+        logger.log(Logger.Level.TRACE, "expression to be evaluated is " + expr);
+
+        Object result = ExprEval.evaluateValueExpression(expr, null,
+            Object.class);
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Long.class)
+            && ExprEval.compareValue((Long) result, expectedResult, 0));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elBigDecimalUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.2
+   * 
+   * @test_Strategy: Validate that if a BigDecimal A is passed with the unary
+   * minus operator (-), the result is A.negate(). Test both ${- value} & #{-
+   * value}
+   */
+  @Test
+  public void elBigDecimalUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    BigDecimal bd = BigDecimal.valueOf(10.0);
+    BigDecimal expectedResult = BigDecimal.valueOf(-10.0);
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(bd);
+
+    try {
+      for (boolean tf : deferred) {
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, BigDecimal.class)
+            && ExprEval.compareValue((BigDecimal) result, expectedResult, 0));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elBigIntegerUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.2
+   * 
+   * @test_Strategy: Validate that if a BigInteger A is passed with the unary
+   * minus operator (-), the result is A.negate(). Test both ${- value} & #{-
+   * value}
+   */
+  @Test
+  public void elBigIntegerUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    BigInteger bi = BigInteger.valueOf(100);
+    BigInteger expectedResult = BigInteger.valueOf(-100);
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(bi);
+
+    try {
+      for (boolean tf : deferred) {
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, BigInteger.class)
+            && ExprEval.compareValue((BigInteger) result, expectedResult, 0));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elDoubleStringUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.3.1
+   * 
+   * @test_Strategy: Validate that if a String is passed with the unary minus
+   * operator (-), the result is as follows: - If the String contains ".", "e",
+   * or "E" coerce to Double, apply operator.
+   *
+   * Test both ${- value} & #{- value}
+   */
+  @Test
+  public void elDoubleStringUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    String[] values = { "10.0", "10E0", "10e0" };
+
+    Double expectedResult = Double.valueOf("-10");
+
+    try {
+      for (boolean tf : deferred) {
+        for (String val : values) {
+          NameValuePair value[] = NameValuePair.buildUnaryNameValue(val);
+
+          String expr = ExprEval.buildElExpr(tf, "unary_minus");
+          Object result = ExprEval.evaluateValueExpression(expr, value,
+              Object.class);
+
+          logger.log(Logger.Level.TRACE, "result is " + result.toString());
+          pass = (ExprEval.compareClass(result, Double.class)
+              && ExprEval.compareValue((Double) result, expectedResult));
+        }
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elLongStringUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.3.2
+   * 
+   * @test_Strategy: Validate that if a String is passed with the unary minus
+   * operator (-), the result is as follows: - If the String does not contain
+   * ".", "e", or "E" coerce to Long, apply operator.
+   *
+   * Test both ${- value} & #{- value}
+   */
+  @Test
+  public void elLongStringUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    String val = "100";
+
+    Long expectedResult = Long.valueOf("-100");
+
+    try {
+      for (boolean tf : deferred) {
+        NameValuePair value[] = NameValuePair.buildUnaryNameValue(val);
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Long.class)
+            && ExprEval.compareValue((Long) result, expectedResult));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elByteUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.4.1
+   * 
+   * @test_Strategy: Validate that if a Byte is passed with the unary minus
+   * operator (-), the type is retained and the operator is applied.
+   *
+   * Test both ${- value} & #{- value}
+   */
+  @Test
+  public void elByteUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    byte num = 1;
+    byte expectedResult = -1;
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(num);
+
+    try {
+      for (boolean tf : deferred) {
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Byte.class)
+            && ExprEval.compareValue((Byte) result, expectedResult));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elShortUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.4.1
+   * 
+   * @test_Strategy: Validate that if a Short is passed with the unary minus
+   * operator (-), the type is retained and the operator is applied.
+   *
+   * Test both ${- value} & #{- value}
+   */
+  @Test
+  public void elShortUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    short num = 1;
+    short expectedResult = -1;
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(num);
+
+    try {
+      for (boolean tf : deferred) {
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Short.class)
+            && ExprEval.compareValue((Short) result, expectedResult));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elIntegerUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.4.1
+   * 
+   * @test_Strategy: Validate that if an Integer is passed with the unary minus
+   * operator (-), the type is retained and the operator is applied.
+   *
+   * Test both ${- value} & #{- value}
+   */
+  @Test
+  public void elIntegerUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    int num = 1;
+    int expectedResult = -1;
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(num);
+
+    try {
+      for (boolean tf : deferred) {
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Integer.class)
+            && ExprEval.compareValue((Integer) result, expectedResult));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elLongUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.4.1
+   * 
+   * @test_Strategy: Validate that if a Long is passed with the unary minus
+   * operator (-), the type is retained and the operator is applied.
+   *
+   * Test both ${- value} & #{- value}
+   */
+  @Test
+  public void elLongUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    long num = 10000;
+    long expectedResult = -10000;
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(num);
+
+    try {
+      for (boolean tf : deferred) {
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Long.class)
+            && ExprEval.compareValue((Long) result, expectedResult));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elFloatUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.4.1
+   * 
+   * @test_Strategy: Validate that if a Float is passed with the unary minus
+   * operator (-), the type is retained and the operator is applied.
+   *
+   * Test both ${- value} & #{- value}
+   */
+  @Test
+  public void elFloatUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    float num = 10000f;
+    float expectedResult = -10000f;
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(num);
+
+    try {
+      for (boolean tf : deferred) {
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Float.class)
+            && ExprEval.compareValue((Float) result, expectedResult, 0));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elDoubleUnaryTest
+   * 
+   * @assertion_ids: EL:SPEC:20.4.1
+   * 
+   * @test_Strategy: Validate that if a Double is passed with the unary minus
+   * operator (-), the type is retained and the operator is applied.
+   *
+   * Test both ${- value} & #{- value}
+   */
+  @Test
+  public void elDoubleUnaryTest() throws Exception {
+
+    boolean pass = false;
+
+    double num = 10000.0;
+    double expectedResult = -10000.0;
+
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(num);
+
+    try {
+      for (boolean tf : deferred) {
+
+        String expr = ExprEval.buildElExpr(tf, "unary_minus");
+        Object result = ExprEval.evaluateValueExpression(expr, value,
+            Object.class);
+
+        logger.log(Logger.Level.TRACE, "result is " + result.toString());
+        pass = (ExprEval.compareClass(result, Double.class)
+            && ExprEval.compareValue((Double) result, expectedResult));
+      }
+
+      if (!pass)
+        throw new Exception("TEST FAILED: pass = false");
+
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+
+  /*
+   * @testName: elBooleanUnaryFalseTest
+   * 
+   * @assertion_ids: EL:SPEC:24.1.1
+   * 
+   * @test_Strategy: Validate that if a String("false") is passed with the unary
+   * "not" operator, the type is coerced to Boolean and the operator is applied.
+   *
+   * Equations Tested: ${not value} & #{not value} ${! value} & #{! value}
+   */
+  @Test
+  public void elBooleanUnaryFalseTest() throws Exception {
+
+    this.testUnary("false", true);
+
+  }
+
+  /*
+   * @testName: elBooleanUnaryTrueTest
+   * 
+   * @assertion_ids: EL:SPEC:24.1.1
+   * 
+   * @test_Strategy: Validate that if a String("true") is passed with the unary
+   * "not" operator, the type is coerced to Boolean and the operator is applied.
+   *
+   * Equations Tested: ${not value} & #{not value} ${! value} & #{! value}
+   */
+  @Test
+  public void elBooleanUnaryTrueTest() throws Exception {
+
+    this.testUnary("true", false);
+
+  }
+
+  // ---------------------------------------------------------- private methods
+
+  private void testUnary(String testVal, boolean expectedResult) throws Exception {
+
+    boolean pass = false;
+
+    String[] operator = { "unary_not", "unary_bang" };
+    NameValuePair value[] = NameValuePair.buildUnaryNameValue(testVal);
+
+    try {
+      for (boolean tf : deferred) {
+        for (String op : operator) {
+          String expr = ExprEval.buildElExpr(tf, op);
+          Object result = ExprEval.evaluateValueExpression(expr, value,
+              Object.class);
+
+          logger.log(Logger.Level.TRACE, "result is " + result.toString());
+          pass = (ExprEval.compareClass(result, Boolean.class)
+              && ExprEval.compareValue((Boolean) result, expectedResult));
+
+          if (!pass)
+            throw new Exception("TEST FAILED: pass = false");
+        }
+      }
+    } catch (Exception e) {
+      throw new Exception(e);
+    }
+  }
+}
diff --git a/tck/src/main/resources/LICENSE_EFTL.md b/tck/src/main/resources/LICENSE_EFTL.md
new file mode 100644
index 0000000..a210682
--- /dev/null
+++ b/tck/src/main/resources/LICENSE_EFTL.md
@@ -0,0 +1,83 @@
+# Eclipse Foundation Technology Compatibility Kit License - v 1.0
+
+Copyright (c) 2018, Eclipse Foundation, Inc. and its licensors.
+
+Redistribution and use in binary form is permitted provided that the
+following conditions are met:
+
+1.  Use of the Technology Compatibility Kit accompanying this license
+    (the "TCK") and its documentation is permitted solely for the
+    purpose of testing compatibility of an implementation (the
+    "Product") of a specification (the "Specification") made available
+    by the Eclipse Foundation, Inc. ("Eclipse").
+
+2.  Only those modifications expressly permitted by the TCK and its
+    documentation are permitted. Except in these limited circumstances,
+    no modifications to the TCK are permitted under this license.
+
+3.  A Product will be deemed to be "compatible" with the Specification
+    if it fully and completely meets and satisfies all requirements of
+    the TCK.
+
+4.  Before any claim of compatibility (or any similar claim suggesting
+    compatibility) is made based on the TCK, the testing party must:
+
+    a.  use the TCK to demonstrate that the Product fully and
+	completely meets and satisfies all requirements of the TCK;
+
+    b.  make TCK test results showing full and complete satisfaction of
+	all requirements of the TCK publicly available on the testing
+	party's website and send a link to such test results to Eclipse
+	at [tck@eclipse.org](mailto:tck@eclipse.org); and
+
+    c.  comply with any requirements stated in the Specification with
+	regard to subsetting, supersetting, modifying or extending the
+	Specification in any Product claimed to be compatible with the
+	Specification.
+
+5.  The test results must be continuously available and the link must
+    be live for at least as long as the Product is available in the
+    marketplace.
+
+6.  The TCK may not be used as a basis for any statements of partial
+    compatibility. The TCK may only be used as a basis for true,
+    factual statements of full compatibility of Products that fully
+    meet and satisfy all requirements of the TCK.
+
+7.  A determination that a Product is compatible with the TCK does not,
+    in itself, give rise to the right to use any name, mark, logo
+    associated with the TCK, Eclipse, or Eclipse's contributors or
+    licensors.
+
+8.  Upon the request of Eclipse, a tester will retract any statements
+    of compatibility (or any similar claim suggesting compatibility)
+    which Eclipse reasonably determines to be false or misleading or in
+    violation of the terms of this license.
+
+9.  Redistribution of the TCK must be under this Eclipse Foundation
+    Technology Compatibility Kit License and 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.
+
+10. Neither the name, trademarks or logos of Eclipse, nor the names,
+    trademarks or logos of its contributors or licensors may be used to
+    endorse or promote products tested with this software without
+    specific prior written permission.
+
+11. The source code for the TCK accompanying this license is available
+    from Eclipse.
+
+TO THE EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED ON
+AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
+EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
+CONDITIONS OF TITLE, NON- INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR
+A PARTICULAR PURPOSE. TO THE EXTENT PERMITTED BY APPLICABLE LAW,
+NEITHER THE COPYRIGHT OWNER OR ANY CONTRIBUTORS SHALL HAVE ANY
+LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS),
+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 OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/tck/src/main/resources/LICENSE_EPL.md b/tck/src/main/resources/LICENSE_EPL.md
new file mode 100644
index 0000000..1d428ed
--- /dev/null
+++ b/tck/src/main/resources/LICENSE_EPL.md
@@ -0,0 +1,637 @@
+# Eclipse Public License - v 2.0
+
+        THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+        PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
+        OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+    1. DEFINITIONS
+
+    "Contribution" means:
+
+      a) in the case of the initial Contributor, the initial content
+         Distributed under this Agreement, and
+
+      b) in the case of each subsequent Contributor: 
+         i) changes to the Program, and 
+         ii) additions to the Program;
+      where such changes and/or additions to the Program originate from
+      and are Distributed by that particular Contributor. A Contribution
+      "originates" from a Contributor if it was added to the Program by
+      such Contributor itself or anyone acting on such Contributor's behalf.
+      Contributions do not include changes or additions to the Program that
+      are not Modified Works.
+
+    "Contributor" means any person or entity that Distributes the Program.
+
+    "Licensed Patents" mean patent claims licensable by a Contributor which
+    are necessarily infringed by the use or sale of its Contribution alone
+    or when combined with the Program.
+
+    "Program" means the Contributions Distributed in accordance with this
+    Agreement.
+
+    "Recipient" means anyone who receives the Program under this Agreement
+    or any Secondary License (as applicable), including Contributors.
+
+    "Derivative Works" shall mean any work, whether in Source Code or other
+    form, that is based on (or derived from) the Program and for which the
+    editorial revisions, annotations, elaborations, or other modifications
+    represent, as a whole, an original work of authorship.
+
+    "Modified Works" shall mean any work in Source Code or other form that
+    results from an addition to, deletion from, or modification of the
+    contents of the Program, including, for purposes of clarity any new file
+    in Source Code form that contains any contents of the Program. Modified
+    Works shall not include works that contain only declarations,
+    interfaces, types, classes, structures, or files of the Program solely
+    in each case in order to link to, bind by name, or subclass the Program
+    or Modified Works thereof.
+
+    "Distribute" means the acts of a) distributing or b) making available
+    in any manner that enables the transfer of a copy.
+
+    "Source Code" means the form of a Program preferred for making
+    modifications, including but not limited to software source code,
+    documentation source, and configuration files.
+
+    "Secondary License" means either the GNU General Public License,
+    Version 2.0, or any later versions of that license, including any
+    exceptions or additional permissions as identified by the initial
+    Contributor.
+
+    2. GRANT OF RIGHTS
+
+      a) Subject to the terms of this Agreement, each Contributor hereby
+      grants Recipient a non-exclusive, worldwide, royalty-free copyright
+      license to reproduce, prepare Derivative Works of, publicly display,
+      publicly perform, Distribute and sublicense the Contribution of such
+      Contributor, if any, and such Derivative Works.
+
+      b) Subject to the terms of this Agreement, each Contributor hereby
+      grants Recipient a non-exclusive, worldwide, royalty-free patent
+      license under Licensed Patents to make, use, sell, offer to sell,
+      import and otherwise transfer the Contribution of such Contributor,
+      if any, in Source Code or other form. This patent license shall
+      apply to the combination of the Contribution and the Program if, at
+      the time the Contribution is added by the Contributor, such addition
+      of the Contribution causes such combination to be covered by the
+      Licensed Patents. The patent license shall not apply to any other
+      combinations which include the Contribution. No hardware per se is
+      licensed hereunder.
+
+      c) Recipient understands that although each Contributor grants the
+      licenses to its Contributions set forth herein, no assurances are
+      provided by any Contributor that the Program does not infringe the
+      patent or other intellectual property rights of any other entity.
+      Each Contributor disclaims any liability to Recipient for claims
+      brought by any other entity based on infringement of intellectual
+      property rights or otherwise. As a condition to exercising the
+      rights and licenses granted hereunder, each Recipient hereby
+      assumes sole responsibility to secure any other intellectual
+      property rights needed, if any. For example, if a third party
+      patent license is required to allow Recipient to Distribute the
+      Program, it is Recipient's responsibility to acquire that license
+      before distributing the Program.
+
+      d) Each Contributor represents that to its knowledge it has
+      sufficient copyright rights in its Contribution, if any, to grant
+      the copyright license set forth in this Agreement.
+
+      e) Notwithstanding the terms of any Secondary License, no
+      Contributor makes additional grants to any Recipient (other than
+      those set forth in this Agreement) as a result of such Recipient's
+      receipt of the Program under the terms of a Secondary License
+      (if permitted under the terms of Section 3).
+
+    3. REQUIREMENTS
+
+    3.1 If a Contributor Distributes the Program in any form, then:
+
+      a) the Program must also be made available as Source Code, in
+      accordance with section 3.2, and the Contributor must accompany
+      the Program with a statement that the Source Code for the Program
+      is available under this Agreement, and informs Recipients how to
+      obtain it in a reasonable manner on or through a medium customarily
+      used for software exchange; and
+
+      b) the Contributor may Distribute the Program under a license
+      different than this Agreement, provided that such license:
+         i) effectively disclaims on behalf of all other Contributors all
+         warranties and conditions, express and implied, including
+         warranties or conditions of title and non-infringement, and
+         implied warranties or conditions of merchantability and fitness
+         for a particular purpose;
+
+         ii) effectively excludes on behalf of all other Contributors all
+         liability for damages, including direct, indirect, special,
+         incidental and consequential damages, such as lost profits;
+
+         iii) does not attempt to limit or alter the recipients' rights
+         in the Source Code under section 3.2; and
+
+         iv) requires any subsequent distribution of the Program by any
+         party to be under a license that satisfies the requirements
+         of this section 3.
+
+    3.2 When the Program is Distributed as Source Code:
+
+      a) it must be made available under this Agreement, or if the
+      Program (i) is combined with other material in a separate file or
+      files made available under a Secondary License, and (ii) the initial
+      Contributor attached to the Source Code the notice described in
+      Exhibit A of this Agreement, then the Program may be made available
+      under the terms of such Secondary Licenses, and
+
+      b) a copy of this Agreement must be included with each copy of
+      the Program.
+
+    3.3 Contributors may not remove or alter any copyright, patent,
+    trademark, attribution notices, disclaimers of warranty, or limitations
+    of liability ("notices") contained within the Program from any copy of
+    the Program which they Distribute, provided that Contributors may add
+    their own appropriate notices.
+
+    4. COMMERCIAL DISTRIBUTION
+
+    Commercial distributors of software may accept certain responsibilities
+    with respect to end users, business partners and the like. While this
+    license is intended to facilitate the commercial use of the Program,
+    the Contributor who includes the Program in a commercial product
+    offering should do so in a manner which does not create potential
+    liability for other Contributors. Therefore, if a Contributor includes
+    the Program in a commercial product offering, such Contributor
+    ("Commercial Contributor") hereby agrees to defend and indemnify every
+    other Contributor ("Indemnified Contributor") against any losses,
+    damages and costs (collectively "Losses") arising from claims, lawsuits
+    and other legal actions brought by a third party against the Indemnified
+    Contributor to the extent caused by the acts or omissions of such
+    Commercial Contributor in connection with its distribution of the Program
+    in a commercial product offering. The obligations in this section do not
+    apply to any claims or Losses relating to any actual or alleged
+    intellectual property infringement. In order to qualify, an Indemnified
+    Contributor must: a) promptly notify the Commercial Contributor in
+    writing of such claim, and b) allow the Commercial Contributor to control,
+    and cooperate with the Commercial Contributor in, the defense and any
+    related settlement negotiations. The Indemnified Contributor may
+    participate in any such claim at its own expense.
+
+    For example, a Contributor might include the Program in a commercial
+    product offering, Product X. That Contributor is then a Commercial
+    Contributor. If that Commercial Contributor then makes performance
+    claims, or offers warranties related to Product X, those performance
+    claims and warranties are such Commercial Contributor's responsibility
+    alone. Under this section, the Commercial Contributor would have to
+    defend claims against the other Contributors related to those performance
+    claims and warranties, and if a court requires any other Contributor to
+    pay any damages as a result, the Commercial Contributor must pay
+    those damages.
+
+    5. NO WARRANTY
+
+    EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+    PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
+    BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+    IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
+    TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+    PURPOSE. Each Recipient is solely responsible for determining the
+    appropriateness of using and distributing the Program and assumes all
+    risks associated with its exercise of rights under this Agreement,
+    including but not limited to the risks and costs of program errors,
+    compliance with applicable laws, damage to or loss of data, programs
+    or equipment, and unavailability or interruption of operations.
+
+    6. DISCLAIMER OF LIABILITY
+
+    EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+    PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
+    SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+    PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE
+    EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGES.
+
+    7. GENERAL
+
+    If any provision of this Agreement is invalid or unenforceable under
+    applicable law, it shall not affect the validity or enforceability of
+    the remainder of the terms of this Agreement, and without further
+    action by the parties hereto, such provision shall be reformed to the
+    minimum extent necessary to make such provision valid and enforceable.
+
+    If Recipient institutes patent litigation against any entity
+    (including a cross-claim or counterclaim in a lawsuit) alleging that the
+    Program itself (excluding combinations of the Program with other software
+    or hardware) infringes such Recipient's patent(s), then such Recipient's
+    rights granted under Section 2(b) shall terminate as of the date such
+    litigation is filed.
+
+    All Recipient's rights under this Agreement shall terminate if it
+    fails to comply with any of the material terms or conditions of this
+    Agreement and does not cure such failure in a reasonable period of
+    time after becoming aware of such noncompliance. If all Recipient's
+    rights under this Agreement terminate, Recipient agrees to cease use
+    and distribution of the Program as soon as reasonably practicable.
+    However, Recipient's obligations under this Agreement and any licenses
+    granted by Recipient relating to the Program shall continue and survive.
+
+    Everyone is permitted to copy and distribute copies of this Agreement,
+    but in order to avoid inconsistency the Agreement is copyrighted and
+    may only be modified in the following manner. The Agreement Steward
+    reserves the right to publish new versions (including revisions) of
+    this Agreement from time to time. No one other than the Agreement
+    Steward has the right to modify this Agreement. The Eclipse Foundation
+    is the initial Agreement Steward. The Eclipse Foundation may assign the
+    responsibility to serve as the Agreement Steward to a suitable separate
+    entity. Each new version of the Agreement will be given a distinguishing
+    version number. The Program (including Contributions) may always be
+    Distributed subject to the version of the Agreement under which it was
+    received. In addition, after a new version of the Agreement is published,
+    Contributor may elect to Distribute the Program (including its
+    Contributions) under the new version.
+
+    Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
+    receives no rights or licenses to the intellectual property of any
+    Contributor under this Agreement, whether expressly, by implication,
+    estoppel or otherwise. All rights in the Program not expressly granted
+    under this Agreement are reserved. Nothing in this Agreement is intended
+    to be enforceable by any entity that is not a Contributor or Recipient.
+    No third-party beneficiary rights are created under this Agreement.
+
+    Exhibit A - Form of Secondary Licenses Notice
+
+    "This Source Code may also be made available under the following 
+    Secondary Licenses when the conditions for such availability set forth 
+    in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
+    version(s), and exceptions or additional permissions here}."
+
+      Simply including a copy of this Agreement, including this Exhibit A
+      is not sufficient to license the Source Code under Secondary Licenses.
+
+      If it is not possible or desirable to put the notice in a particular
+      file, then You may include the notice in a location (such as a LICENSE
+      file in a relevant directory) where a recipient would be likely to
+      look for such a notice.
+
+      You may add additional accurate notices of copyright ownership.
+
+---
+
+##    The GNU General Public License (GPL) Version 2, June 1991
+
+    Copyright (C) 1989, 2022 Free Software Foundation, Inc.
+    51 Franklin Street, Fifth Floor
+    Boston, MA 02110-1335
+    USA
+
+    Everyone is permitted to copy and distribute verbatim copies
+    of this license document, but changing it is not allowed.
+
+    Preamble
+
+    The licenses for most software are designed to take away your freedom to
+    share and change it. By contrast, the GNU General Public License is
+    intended to guarantee your freedom to share and change free software--to
+    make sure the software is free for all its users. This General Public
+    License applies to most of the Free Software Foundation's software and
+    to any other program whose authors commit to using it. (Some other Free
+    Software Foundation software is covered by the GNU Library General
+    Public License instead.) You can apply it to your programs, too.
+
+    When we speak of free software, we are referring to freedom, not price.
+    Our General Public Licenses are designed to make sure that you have the
+    freedom to distribute copies of free software (and charge for this
+    service if you wish), that you receive source code or can get it if you
+    want it, that you can change the software or use pieces of it in new
+    free programs; and that you know you can do these things.
+
+    To protect your rights, we need to make restrictions that forbid anyone
+    to deny you these rights or to ask you to surrender the rights. These
+    restrictions translate to certain responsibilities for you if you
+    distribute copies of the software, or if you modify it.
+
+    For example, if you distribute copies of such a program, whether gratis
+    or for a fee, you must give the recipients all the rights that you have.
+    You must make sure that they, too, receive or can get the source code.
+    And you must show them these terms so they know their rights.
+
+    We protect your rights with two steps: (1) copyright the software, and
+    (2) offer you this license which gives you legal permission to copy,
+    distribute and/or modify the software.
+
+    Also, for each author's protection and ours, we want to make certain
+    that everyone understands that there is no warranty for this free
+    software. If the software is modified by someone else and passed on, we
+    want its recipients to know that what they have is not the original, so
+    that any problems introduced by others will not reflect on the original
+    authors' reputations.
+
+    Finally, any free program is threatened constantly by software patents.
+    We wish to avoid the danger that redistributors of a free program will
+    individually obtain patent licenses, in effect making the program
+    proprietary. To prevent this, we have made it clear that any patent must
+    be licensed for everyone's free use or not licensed at all.
+
+    The precise terms and conditions for copying, distribution and
+    modification follow.
+
+    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+    0. This License applies to any program or other work which contains a
+    notice placed by the copyright holder saying it may be distributed under
+    the terms of this General Public License. The "Program", below, refers
+    to any such program or work, and a "work based on the Program" means
+    either the Program or any derivative work under copyright law: that is
+    to say, a work containing the Program or a portion of it, either
+    verbatim or with modifications and/or translated into another language.
+    (Hereinafter, translation is included without limitation in the term
+    "modification".) Each licensee is addressed as "you".
+
+    Activities other than copying, distribution and modification are not
+    covered by this License; they are outside its scope. The act of running
+    the Program is not restricted, and the output from the Program is
+    covered only if its contents constitute a work based on the Program
+    (independent of having been made by running the Program). Whether that
+    is true depends on what the Program does.
+
+    1. You may copy and distribute verbatim copies of the Program's source
+    code as you receive it, in any medium, provided that you conspicuously
+    and appropriately publish on each copy an appropriate copyright notice
+    and disclaimer of warranty; keep intact all the notices that refer to
+    this License and to the absence of any warranty; and give any other
+    recipients of the Program a copy of this License along with the Program.
+
+    You may charge a fee for the physical act of transferring a copy, and
+    you may at your option offer warranty protection in exchange for a fee.
+
+    2. You may modify your copy or copies of the Program or any portion of
+    it, thus forming a work based on the Program, and copy and distribute
+    such modifications or work under the terms of Section 1 above, provided
+    that you also meet all of these conditions:
+
+        a) You must cause the modified files to carry prominent notices
+        stating that you changed the files and the date of any change.
+
+        b) You must cause any work that you distribute or publish, that in
+        whole or in part contains or is derived from the Program or any part
+        thereof, to be licensed as a whole at no charge to all third parties
+        under the terms of this License.
+
+        c) If the modified program normally reads commands interactively
+        when run, you must cause it, when started running for such
+        interactive use in the most ordinary way, to print or display an
+        announcement including an appropriate copyright notice and a notice
+        that there is no warranty (or else, saying that you provide a
+        warranty) and that users may redistribute the program under these
+        conditions, and telling the user how to view a copy of this License.
+        (Exception: if the Program itself is interactive but does not
+        normally print such an announcement, your work based on the Program
+        is not required to print an announcement.)
+
+    These requirements apply to the modified work as a whole. If
+    identifiable sections of that work are not derived from the Program, and
+    can be reasonably considered independent and separate works in
+    themselves, then this License, and its terms, do not apply to those
+    sections when you distribute them as separate works. But when you
+    distribute the same sections as part of a whole which is a work based on
+    the Program, the distribution of the whole must be on the terms of this
+    License, whose permissions for other licensees extend to the entire
+    whole, and thus to each and every part regardless of who wrote it.
+
+    Thus, it is not the intent of this section to claim rights or contest
+    your rights to work written entirely by you; rather, the intent is to
+    exercise the right to control the distribution of derivative or
+    collective works based on the Program.
+
+    In addition, mere aggregation of another work not based on the Program
+    with the Program (or with a work based on the Program) on a volume of a
+    storage or distribution medium does not bring the other work under the
+    scope of this License.
+
+    3. You may copy and distribute the Program (or a work based on it,
+    under Section 2) in object code or executable form under the terms of
+    Sections 1 and 2 above provided that you also do one of the following:
+
+        a) Accompany it with the complete corresponding machine-readable
+        source code, which must be distributed under the terms of Sections 1
+        and 2 above on a medium customarily used for software interchange; or,
+
+        b) Accompany it with a written offer, valid for at least three
+        years, to give any third party, for a charge no more than your cost
+        of physically performing source distribution, a complete
+        machine-readable copy of the corresponding source code, to be
+        distributed under the terms of Sections 1 and 2 above on a medium
+        customarily used for software interchange; or,
+
+        c) Accompany it with the information you received as to the offer to
+        distribute corresponding source code. (This alternative is allowed
+        only for noncommercial distribution and only if you received the
+        program in object code or executable form with such an offer, in
+        accord with Subsection b above.)
+
+    The source code for a work means the preferred form of the work for
+    making modifications to it. For an executable work, complete source code
+    means all the source code for all modules it contains, plus any
+    associated interface definition files, plus the scripts used to control
+    compilation and installation of the executable. However, as a special
+    exception, the source code distributed need not include anything that is
+    normally distributed (in either source or binary form) with the major
+    components (compiler, kernel, and so on) of the operating system on
+    which the executable runs, unless that component itself accompanies the
+    executable.
+
+    If distribution of executable or object code is made by offering access
+    to copy from a designated place, then offering equivalent access to copy
+    the source code from the same place counts as distribution of the source
+    code, even though third parties are not compelled to copy the source
+    along with the object code.
+
+    4. You may not copy, modify, sublicense, or distribute the Program
+    except as expressly provided under this License. Any attempt otherwise
+    to copy, modify, sublicense or distribute the Program is void, and will
+    automatically terminate your rights under this License. However, parties
+    who have received copies, or rights, from you under this License will
+    not have their licenses terminated so long as such parties remain in
+    full compliance.
+
+    5. You are not required to accept this License, since you have not
+    signed it. However, nothing else grants you permission to modify or
+    distribute the Program or its derivative works. These actions are
+    prohibited by law if you do not accept this License. Therefore, by
+    modifying or distributing the Program (or any work based on the
+    Program), you indicate your acceptance of this License to do so, and all
+    its terms and conditions for copying, distributing or modifying the
+    Program or works based on it.
+
+    6. Each time you redistribute the Program (or any work based on the
+    Program), the recipient automatically receives a license from the
+    original licensor to copy, distribute or modify the Program subject to
+    these terms and conditions. You may not impose any further restrictions
+    on the recipients' exercise of the rights granted herein. You are not
+    responsible for enforcing compliance by third parties to this License.
+
+    7. If, as a consequence of a court judgment or allegation of patent
+    infringement or for any other reason (not limited to patent issues),
+    conditions are imposed on you (whether by court order, agreement or
+    otherwise) that contradict the conditions of this License, they do not
+    excuse you from the conditions of this License. If you cannot distribute
+    so as to satisfy simultaneously your obligations under this License and
+    any other pertinent obligations, then as a consequence you may not
+    distribute the Program at all. For example, if a patent license would
+    not permit royalty-free redistribution of the Program by all those who
+    receive copies directly or indirectly through you, then the only way you
+    could satisfy both it and this License would be to refrain entirely from
+    distribution of the Program.
+
+    If any portion of this section is held invalid or unenforceable under
+    any particular circumstance, the balance of the section is intended to
+    apply and the section as a whole is intended to apply in other
+    circumstances.
+
+    It is not the purpose of this section to induce you to infringe any
+    patents or other property right claims or to contest validity of any
+    such claims; this section has the sole purpose of protecting the
+    integrity of the free software distribution system, which is implemented
+    by public license practices. Many people have made generous
+    contributions to the wide range of software distributed through that
+    system in reliance on consistent application of that system; it is up to
+    the author/donor to decide if he or she is willing to distribute
+    software through any other system and a licensee cannot impose that choice.
+
+    This section is intended to make thoroughly clear what is believed to be
+    a consequence of the rest of this License.
+
+    8. If the distribution and/or use of the Program is restricted in
+    certain countries either by patents or by copyrighted interfaces, the
+    original copyright holder who places the Program under this License may
+    add an explicit geographical distribution limitation excluding those
+    countries, so that distribution is permitted only in or among countries
+    not thus excluded. In such case, this License incorporates the
+    limitation as if written in the body of this License.
+
+    9. The Free Software Foundation may publish revised and/or new
+    versions of the General Public License from time to time. Such new
+    versions will be similar in spirit to the present version, but may
+    differ in detail to address new problems or concerns.
+
+    Each version is given a distinguishing version number. If the Program
+    specifies a version number of this License which applies to it and "any
+    later version", you have the option of following the terms and
+    conditions either of that version or of any later version published by
+    the Free Software Foundation. If the Program does not specify a version
+    number of this License, you may choose any version ever published by the
+    Free Software Foundation.
+
+    10. If you wish to incorporate parts of the Program into other free
+    programs whose distribution conditions are different, write to the
+    author to ask for permission. For software which is copyrighted by the
+    Free Software Foundation, write to the Free Software Foundation; we
+    sometimes make exceptions for this. Our decision will be guided by the
+    two goals of preserving the free status of all derivatives of our free
+    software and of promoting the sharing and reuse of software generally.
+
+    NO WARRANTY
+
+    11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+    WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+    EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+    OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
+    EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+    ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+    YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+    NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+    12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+    WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+    AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
+    DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
+    DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
+    (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+    INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
+    THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
+    OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+    END OF TERMS AND CONDITIONS
+
+    How to Apply These Terms to Your New Programs
+
+    If you develop a new program, and you want it to be of the greatest
+    possible use to the public, the best way to achieve this is to make it
+    free software which everyone can redistribute and change under these terms.
+
+    To do so, attach the following notices to the program. It is safest to
+    attach them to the start of each source file to most effectively convey
+    the exclusion of warranty; and each file should have at least the
+    "copyright" line and a pointer to where the full notice is found.
+
+        One line to give the program's name and a brief idea of what it does.
+        Copyright (C) <year> <name of author>
+
+        This program is free software; you can redistribute it and/or modify
+        it under the terms of the GNU General Public License as published by
+        the Free Software Foundation; either version 2 of the License, or
+        (at your option) any later version.
+
+        This program is distributed in the hope that it will be useful, but
+        WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+        General Public License for more details.
+
+        You should have received a copy of the GNU General Public License
+        along with this program; if not, write to the Free Software
+        Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+
+    Also add information on how to contact you by electronic and paper mail.
+
+    If the program is interactive, make it output a short notice like this
+    when it starts in an interactive mode:
+
+        Gnomovision version 69, Copyright (C) year name of author
+        Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type
+        `show w'. This is free software, and you are welcome to redistribute
+        it under certain conditions; type `show c' for details.
+
+    The hypothetical commands `show w' and `show c' should show the
+    appropriate parts of the General Public License. Of course, the commands
+    you use may be called something other than `show w' and `show c'; they
+    could even be mouse-clicks or menu items--whatever suits your program.
+
+    You should also get your employer (if you work as a programmer) or your
+    school, if any, to sign a "copyright disclaimer" for the program, if
+    necessary. Here is a sample; alter the names:
+
+        Yoyodyne, Inc., hereby disclaims all copyright interest in the
+        program `Gnomovision' (which makes passes at compilers) written by
+        James Hacker.
+
+        signature of Ty Coon, 1 April 1989
+        Ty Coon, President of Vice
+
+    This General Public License does not permit incorporating your program
+    into proprietary programs. If your program is a subroutine library, you
+    may consider it more useful to permit linking proprietary applications
+    with the library. If this is what you want to do, use the GNU Library
+    General Public License instead of this License.
+
+---
+
+## CLASSPATH EXCEPTION
+
+    Linking this library statically or dynamically with other modules is
+    making a combined work based on this library.  Thus, the terms and
+    conditions of the GNU General Public License version 2 cover the whole
+    combination.
+
+    As a special exception, the copyright holders of this library give you
+    permission to link this library with independent modules to produce an
+    executable, regardless of the license terms of these independent
+    modules, and to copy and distribute the resulting executable under
+    terms of your choice, provided that you also meet, for each linked
+    independent module, the terms and conditions of the license of that
+    module.  An independent module is a module which is not derived from or
+    based on this library.  If you modify this library, you may extend this
+    exception to your version of the library, but you are not obligated to
+    do so.  If you do not wish to do so, delete this exception statement
+    from your version.
diff --git a/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/jakarta.el.sig_5.0 b/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/jakarta.el.sig_5.0
new file mode 100644
index 0000000..dcbc9a3
--- /dev/null
+++ b/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/jakarta.el.sig_5.0
@@ -0,0 +1,434 @@
+#Signature file v4.1
+#Version 5.0
+
+CLSS public jakarta.el.ArrayELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly
+
+CLSS public jakarta.el.BeanELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,properties
+hcls BPSoftReference,BeanProperties,BeanProperty,SoftConcurrentHashMap
+
+CLSS public jakarta.el.BeanNameELResolver
+cons public init(jakarta.el.BeanNameResolver)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds beanNameResolver
+
+CLSS public abstract jakarta.el.BeanNameResolver
+cons public init()
+meth public boolean canCreateBean(java.lang.String)
+meth public boolean isNameResolved(java.lang.String)
+meth public boolean isReadOnly(java.lang.String)
+meth public java.lang.Object getBean(java.lang.String)
+meth public void setBeanValue(java.lang.String,java.lang.Object)
+supr java.lang.Object
+
+CLSS public jakarta.el.CompositeELResolver
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void add(jakarta.el.ELResolver)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds elResolvers,size
+hcls CompositeIterator
+
+CLSS public jakarta.el.ELClass
+cons public init(java.lang.Class<?>)
+meth public java.lang.Class<?> getKlass()
+supr java.lang.Object
+hfds klass
+
+CLSS public abstract jakarta.el.ELContext
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract jakarta.el.ELResolver getELResolver()
+meth public abstract jakarta.el.FunctionMapper getFunctionMapper()
+meth public abstract jakarta.el.VariableMapper getVariableMapper()
+meth public boolean isLambdaArgument(java.lang.String)
+meth public boolean isPropertyResolved()
+meth public jakarta.el.ImportHandler getImportHandler()
+meth public java.lang.Object getContext(java.lang.Class<?>)
+meth public java.lang.Object getLambdaArgument(java.lang.String)
+meth public java.util.List<jakarta.el.EvaluationListener> getEvaluationListeners()
+meth public java.util.Locale getLocale()
+meth public void addEvaluationListener(jakarta.el.EvaluationListener)
+meth public void enterLambdaScope(java.util.Map<java.lang.String,java.lang.Object>)
+meth public void exitLambdaScope()
+meth public void notifyAfterEvaluation(java.lang.String)
+meth public void notifyBeforeEvaluation(java.lang.String)
+meth public void notifyPropertyResolved(java.lang.Object,java.lang.Object)
+meth public void putContext(java.lang.Class<?>,java.lang.Object)
+meth public void setLocale(java.util.Locale)
+meth public void setPropertyResolved(boolean)
+meth public void setPropertyResolved(java.lang.Object,java.lang.Object)
+supr java.lang.Object
+hfds importHandler,lambdaArgs,listeners,locale,map,resolved
+
+CLSS public jakarta.el.ELContextEvent
+cons public init(jakarta.el.ELContext)
+meth public jakarta.el.ELContext getELContext()
+supr java.util.EventObject
+hfds serialVersionUID
+
+CLSS public abstract interface jakarta.el.ELContextListener
+intf java.util.EventListener
+meth public abstract void contextCreated(jakarta.el.ELContextEvent)
+
+CLSS public jakarta.el.ELException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public jakarta.el.ELManager
+cons public init()
+meth public jakarta.el.ELContext setELContext(jakarta.el.ELContext)
+meth public jakarta.el.StandardELContext getELContext()
+meth public java.lang.Object defineBean(java.lang.String,java.lang.Object)
+meth public static jakarta.el.ExpressionFactory getExpressionFactory()
+meth public void addBeanNameResolver(jakarta.el.BeanNameResolver)
+meth public void addELResolver(jakarta.el.ELResolver)
+meth public void addEvaluationListener(jakarta.el.EvaluationListener)
+meth public void importClass(java.lang.String)
+meth public void importPackage(java.lang.String)
+meth public void importStatic(java.lang.String)
+meth public void mapFunction(java.lang.String,java.lang.String,java.lang.reflect.Method)
+meth public void setVariable(java.lang.String,jakarta.el.ValueExpression)
+supr java.lang.Object
+hfds elContext
+
+CLSS public jakarta.el.ELProcessor
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} eval(java.lang.String)
+meth public <%0 extends java.lang.Object> {%%0} getValue(java.lang.String,java.lang.Class<{%%0}>)
+meth public jakarta.el.ELManager getELManager()
+meth public void defineBean(java.lang.String,java.lang.Object)
+meth public void defineFunction(java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.ClassNotFoundException,java.lang.NoSuchMethodException
+meth public void defineFunction(java.lang.String,java.lang.String,java.lang.reflect.Method) throws java.lang.NoSuchMethodException
+meth public void setValue(java.lang.String,java.lang.Object)
+meth public void setVariable(java.lang.String,java.lang.String)
+supr java.lang.Object
+hfds elManager,factory
+
+CLSS public abstract jakarta.el.ELResolver
+cons public init()
+fld public final static java.lang.String RESOLVABLE_AT_DESIGN_TIME = "resolvableAtDesignTime"
+fld public final static java.lang.String TYPE = "type"
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public abstract java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.EvaluationListener
+cons public init()
+meth public void afterEvaluation(jakarta.el.ELContext,java.lang.String)
+meth public void beforeEvaluation(jakarta.el.ELContext,java.lang.String)
+meth public void propertyResolved(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.Expression
+cons public init()
+intf java.io.Serializable
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract boolean isLiteralText()
+meth public abstract int hashCode()
+meth public abstract java.lang.String getExpressionString()
+supr java.lang.Object
+hfds serialVersionUID
+
+CLSS public abstract jakarta.el.ExpressionFactory
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} coerceToType(java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract jakarta.el.MethodExpression createMethodExpression(jakarta.el.ELContext,java.lang.String,java.lang.Class<?>,java.lang.Class<?>[])
+meth public abstract jakarta.el.ValueExpression createValueExpression(jakarta.el.ELContext,java.lang.String,java.lang.Class<?>)
+meth public abstract jakarta.el.ValueExpression createValueExpression(java.lang.Object,java.lang.Class<?>)
+meth public jakarta.el.ELResolver getStreamELResolver()
+meth public java.util.Map<java.lang.String,java.lang.reflect.Method> getInitFunctionMap()
+meth public static jakarta.el.ExpressionFactory newInstance()
+meth public static jakarta.el.ExpressionFactory newInstance(java.util.Properties)
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.FunctionMapper
+cons public init()
+meth public abstract java.lang.reflect.Method resolveFunction(java.lang.String,java.lang.String)
+meth public void mapFunction(java.lang.String,java.lang.String,java.lang.reflect.Method)
+supr java.lang.Object
+
+CLSS public jakarta.el.ImportHandler
+cons public init()
+meth public java.lang.Class<?> resolveClass(java.lang.String)
+meth public java.lang.Class<?> resolveStatic(java.lang.String)
+meth public void importClass(java.lang.String)
+meth public void importPackage(java.lang.String)
+meth public void importStatic(java.lang.String)
+supr java.lang.Object
+hfds classMap,classNameMap,notAClass,packages,staticNameMap
+
+CLSS public jakarta.el.LambdaExpression
+cons public init(java.util.List<java.lang.String>,jakarta.el.ValueExpression)
+meth public !varargs java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object[])
+meth public !varargs java.lang.Object invoke(java.lang.Object[])
+meth public void setELContext(jakarta.el.ELContext)
+supr java.lang.Object
+hfds context,envirArgs,expression,formalParameters
+
+CLSS public jakarta.el.ListELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,theUnmodifiableListClass
+
+CLSS public jakarta.el.MapELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,theUnmodifiableMapClass
+
+CLSS public abstract jakarta.el.MethodExpression
+cons public init()
+meth public abstract jakarta.el.MethodInfo getMethodInfo(jakarta.el.ELContext)
+meth public abstract java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object[])
+meth public boolean isParametersProvided()
+meth public jakarta.el.MethodReference getMethodReference(jakarta.el.ELContext)
+supr jakarta.el.Expression
+hfds serialVersionUID
+
+CLSS public jakarta.el.MethodInfo
+cons public init(java.lang.String,java.lang.Class<?>,java.lang.Class<?>[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.Class<?> getReturnType()
+meth public java.lang.Class<?>[] getParamTypes()
+meth public java.lang.String getName()
+supr java.lang.Object
+hfds name,paramTypes,returnType
+
+CLSS public jakarta.el.MethodNotFoundException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.MethodReference
+cons public init(java.lang.Object,jakarta.el.MethodInfo,java.lang.annotation.Annotation[],java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public jakarta.el.MethodInfo getMethodInfo()
+meth public java.lang.Object getBase()
+meth public java.lang.Object[] getEvaluatedParameters()
+meth public java.lang.annotation.Annotation[] getAnnotations()
+supr java.lang.Object
+hfds annotations,base,evaluatedParameters,methodInfo
+
+CLSS public jakarta.el.PropertyNotFoundException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.PropertyNotWritableException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.ResourceBundleELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public jakarta.el.StandardELContext
+cons public init(jakarta.el.ELContext)
+cons public init(jakarta.el.ExpressionFactory)
+meth public jakarta.el.ELResolver getELResolver()
+meth public jakarta.el.FunctionMapper getFunctionMapper()
+meth public jakarta.el.VariableMapper getVariableMapper()
+meth public java.lang.Object getContext(java.lang.Class<?>)
+meth public void addELResolver(jakarta.el.ELResolver)
+meth public void putContext(java.lang.Class<?>,java.lang.Object)
+supr jakarta.el.ELContext
+hfds beans,customResolvers,delegate,elResolver,functionMapper,initFunctionMap,streamELResolver,variableMapper
+hcls DefaultFunctionMapper,DefaultVariableMapper,LocalBeanNameResolver
+
+CLSS public jakarta.el.StaticFieldELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public abstract jakarta.el.TypeConverter
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public abstract jakarta.el.ValueExpression
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} getValue(jakarta.el.ELContext)
+meth public abstract boolean isReadOnly(jakarta.el.ELContext)
+meth public abstract java.lang.Class<?> getExpectedType()
+meth public abstract java.lang.Class<?> getType(jakarta.el.ELContext)
+meth public abstract void setValue(jakarta.el.ELContext,java.lang.Object)
+meth public jakarta.el.ValueReference getValueReference(jakarta.el.ELContext)
+supr jakarta.el.Expression
+hfds serialVersionUID
+
+CLSS public jakarta.el.ValueReference
+cons public init(java.lang.Object,java.lang.Object)
+intf java.io.Serializable
+meth public java.lang.Object getBase()
+meth public java.lang.Object getProperty()
+supr java.lang.Object
+hfds base,property,serialVersionUID
+
+CLSS public abstract jakarta.el.VariableMapper
+cons public init()
+meth public abstract jakarta.el.ValueExpression resolveVariable(java.lang.String)
+meth public abstract jakarta.el.ValueExpression setVariable(java.lang.String,jakarta.el.ValueExpression)
+supr java.lang.Object
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+ anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="9")
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+
+CLSS public abstract interface java.util.EventListener
+
+CLSS public java.util.EventObject
+cons public init(java.lang.Object)
+fld protected java.lang.Object source
+intf java.io.Serializable
+meth public java.lang.Object getSource()
+meth public java.lang.String toString()
+supr java.lang.Object
+
diff --git a/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/jakarta.el.sig_6.0 b/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/jakarta.el.sig_6.0
new file mode 100644
index 0000000..7f9a81b
--- /dev/null
+++ b/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/jakarta.el.sig_6.0
@@ -0,0 +1,435 @@
+#Signature file v4.1
+#Version 6.0.0
+
+CLSS public jakarta.el.ArrayELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds LENGTH_PROPERTY_NAME,isReadOnly
+
+CLSS public jakarta.el.BeanELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,properties
+hcls BPSoftReference,BeanProperties,BeanProperty,SoftConcurrentHashMap
+
+CLSS public jakarta.el.BeanNameELResolver
+cons public init(jakarta.el.BeanNameResolver)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds beanNameResolver
+
+CLSS public abstract jakarta.el.BeanNameResolver
+cons public init()
+meth public boolean canCreateBean(java.lang.String)
+meth public boolean isNameResolved(java.lang.String)
+meth public boolean isReadOnly(java.lang.String)
+meth public java.lang.Object getBean(java.lang.String)
+meth public void setBeanValue(java.lang.String,java.lang.Object)
+supr java.lang.Object
+
+CLSS public jakarta.el.CompositeELResolver
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public void add(jakarta.el.ELResolver)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds elResolvers,size
+
+CLSS public jakarta.el.ELClass
+cons public init(java.lang.Class<?>)
+meth public java.lang.Class<?> getKlass()
+supr java.lang.Object
+hfds klass
+
+CLSS public abstract jakarta.el.ELContext
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract jakarta.el.ELResolver getELResolver()
+meth public abstract jakarta.el.FunctionMapper getFunctionMapper()
+meth public abstract jakarta.el.VariableMapper getVariableMapper()
+meth public boolean isLambdaArgument(java.lang.String)
+meth public boolean isPropertyResolved()
+meth public jakarta.el.ImportHandler getImportHandler()
+meth public java.lang.Object getContext(java.lang.Class<?>)
+meth public java.lang.Object getLambdaArgument(java.lang.String)
+meth public java.util.List<jakarta.el.EvaluationListener> getEvaluationListeners()
+meth public java.util.Locale getLocale()
+meth public void addEvaluationListener(jakarta.el.EvaluationListener)
+meth public void enterLambdaScope(java.util.Map<java.lang.String,java.lang.Object>)
+meth public void exitLambdaScope()
+meth public void notifyAfterEvaluation(java.lang.String)
+meth public void notifyBeforeEvaluation(java.lang.String)
+meth public void notifyPropertyResolved(java.lang.Object,java.lang.Object)
+meth public void putContext(java.lang.Class<?>,java.lang.Object)
+meth public void setLocale(java.util.Locale)
+meth public void setPropertyResolved(boolean)
+meth public void setPropertyResolved(java.lang.Object,java.lang.Object)
+supr java.lang.Object
+hfds importHandler,lambdaArgs,listeners,locale,map,resolved
+
+CLSS public jakarta.el.ELContextEvent
+cons public init(jakarta.el.ELContext)
+meth public jakarta.el.ELContext getELContext()
+supr java.util.EventObject
+hfds serialVersionUID
+
+CLSS public abstract interface jakarta.el.ELContextListener
+intf java.util.EventListener
+meth public abstract void contextCreated(jakarta.el.ELContextEvent)
+
+CLSS public jakarta.el.ELException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public jakarta.el.ELManager
+cons public init()
+meth public jakarta.el.ELContext setELContext(jakarta.el.ELContext)
+meth public jakarta.el.StandardELContext getELContext()
+meth public java.lang.Object defineBean(java.lang.String,java.lang.Object)
+meth public static jakarta.el.ExpressionFactory getExpressionFactory()
+meth public void addBeanNameResolver(jakarta.el.BeanNameResolver)
+meth public void addELResolver(jakarta.el.ELResolver)
+meth public void addEvaluationListener(jakarta.el.EvaluationListener)
+meth public void importClass(java.lang.String)
+meth public void importPackage(java.lang.String)
+meth public void importStatic(java.lang.String)
+meth public void mapFunction(java.lang.String,java.lang.String,java.lang.reflect.Method)
+meth public void setVariable(java.lang.String,jakarta.el.ValueExpression)
+supr java.lang.Object
+hfds elContext,exprFactory
+
+CLSS public jakarta.el.ELProcessor
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} eval(java.lang.String)
+meth public <%0 extends java.lang.Object> {%%0} getValue(java.lang.String,java.lang.Class<{%%0}>)
+meth public jakarta.el.ELManager getELManager()
+meth public void defineBean(java.lang.String,java.lang.Object)
+meth public void defineFunction(java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.ClassNotFoundException,java.lang.NoSuchMethodException
+meth public void defineFunction(java.lang.String,java.lang.String,java.lang.reflect.Method) throws java.lang.NoSuchMethodException
+meth public void setValue(java.lang.String,java.lang.Object)
+meth public void setVariable(java.lang.String,java.lang.String)
+supr java.lang.Object
+hfds elManager,factory
+
+CLSS public abstract jakarta.el.ELResolver
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public abstract java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.EvaluationListener
+cons public init()
+meth public void afterEvaluation(jakarta.el.ELContext,java.lang.String)
+meth public void beforeEvaluation(jakarta.el.ELContext,java.lang.String)
+meth public void propertyResolved(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.Expression
+cons public init()
+intf java.io.Serializable
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract boolean isLiteralText()
+meth public abstract int hashCode()
+meth public abstract java.lang.String getExpressionString()
+supr java.lang.Object
+hfds serialVersionUID
+
+CLSS public abstract jakarta.el.ExpressionFactory
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} coerceToType(java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract jakarta.el.MethodExpression createMethodExpression(jakarta.el.ELContext,java.lang.String,java.lang.Class<?>,java.lang.Class<?>[])
+meth public abstract jakarta.el.ValueExpression createValueExpression(jakarta.el.ELContext,java.lang.String,java.lang.Class<?>)
+meth public abstract jakarta.el.ValueExpression createValueExpression(java.lang.Object,java.lang.Class<?>)
+meth public jakarta.el.ELResolver getStreamELResolver()
+meth public java.util.Map<java.lang.String,java.lang.reflect.Method> getInitFunctionMap()
+meth public static jakarta.el.ExpressionFactory newInstance()
+meth public static jakarta.el.ExpressionFactory newInstance(java.util.Properties)
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.FunctionMapper
+cons public init()
+meth public abstract java.lang.reflect.Method resolveFunction(java.lang.String,java.lang.String)
+meth public void mapFunction(java.lang.String,java.lang.String,java.lang.reflect.Method)
+supr java.lang.Object
+
+CLSS public jakarta.el.ImportHandler
+cons public init()
+meth public java.lang.Class<?> resolveClass(java.lang.String)
+meth public java.lang.Class<?> resolveStatic(java.lang.String)
+meth public void importClass(java.lang.String)
+meth public void importPackage(java.lang.String)
+meth public void importStatic(java.lang.String)
+supr java.lang.Object
+hfds classMap,classNameMap,notAClass,packages,staticNameMap
+
+CLSS public jakarta.el.LambdaExpression
+cons public init(java.util.List<java.lang.String>,jakarta.el.ValueExpression)
+meth public !varargs java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object[])
+meth public !varargs java.lang.Object invoke(java.lang.Object[])
+meth public void setELContext(jakarta.el.ELContext)
+supr java.lang.Object
+hfds context,envirArgs,expression,formalParameters
+
+CLSS public jakarta.el.ListELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,theUnmodifiableListClass
+
+CLSS public jakarta.el.MapELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,theUnmodifiableMapClass
+
+CLSS public abstract jakarta.el.MethodExpression
+cons public init()
+meth public abstract jakarta.el.MethodInfo getMethodInfo(jakarta.el.ELContext)
+meth public abstract java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object[])
+meth public boolean isParametersProvided()
+meth public jakarta.el.MethodReference getMethodReference(jakarta.el.ELContext)
+supr jakarta.el.Expression
+hfds serialVersionUID
+
+CLSS public jakarta.el.MethodInfo
+cons public init(java.lang.String,java.lang.Class<?>,java.lang.Class<?>[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.Class<?> getReturnType()
+meth public java.lang.Class<?>[] getParamTypes()
+meth public java.lang.String getName()
+supr java.lang.Object
+hfds name,paramTypes,returnType
+
+CLSS public jakarta.el.MethodNotFoundException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.MethodReference
+cons public init(java.lang.Object,jakarta.el.MethodInfo,java.lang.annotation.Annotation[],java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public jakarta.el.MethodInfo getMethodInfo()
+meth public java.lang.Object getBase()
+meth public java.lang.Object[] getEvaluatedParameters()
+meth public java.lang.annotation.Annotation[] getAnnotations()
+supr java.lang.Object
+hfds annotations,base,evaluatedParameters,methodInfo
+
+CLSS public jakarta.el.OptionalELResolver
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public jakarta.el.PropertyNotFoundException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.PropertyNotWritableException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.RecordELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public jakarta.el.ResourceBundleELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public jakarta.el.StandardELContext
+cons public init(jakarta.el.ELContext)
+cons public init(jakarta.el.ExpressionFactory)
+meth public jakarta.el.ELResolver getELResolver()
+meth public jakarta.el.FunctionMapper getFunctionMapper()
+meth public jakarta.el.VariableMapper getVariableMapper()
+meth public java.lang.Object getContext(java.lang.Class<?>)
+meth public void addELResolver(jakarta.el.ELResolver)
+meth public void putContext(java.lang.Class<?>,java.lang.Object)
+supr jakarta.el.ELContext
+hfds beans,customResolvers,delegate,elResolver,functionMapper,initFunctionMap,streamELResolver,variableMapper
+hcls DefaultFunctionMapper,DefaultVariableMapper,LocalBeanNameResolver
+
+CLSS public jakarta.el.StaticFieldELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public abstract jakarta.el.TypeConverter
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public abstract jakarta.el.ValueExpression
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} getValue(jakarta.el.ELContext)
+meth public abstract boolean isReadOnly(jakarta.el.ELContext)
+meth public abstract java.lang.Class<?> getExpectedType()
+meth public abstract java.lang.Class<?> getType(jakarta.el.ELContext)
+meth public abstract void setValue(jakarta.el.ELContext,java.lang.Object)
+meth public jakarta.el.ValueReference getValueReference(jakarta.el.ELContext)
+supr jakarta.el.Expression
+hfds serialVersionUID
+
+CLSS public jakarta.el.ValueReference
+cons public init(java.lang.Object,java.lang.Object)
+intf java.io.Serializable
+meth public java.lang.Object getBase()
+meth public java.lang.Object getProperty()
+supr java.lang.Object
+hfds base,property,serialVersionUID
+
+CLSS public abstract jakarta.el.VariableMapper
+cons public init()
+meth public abstract jakarta.el.ValueExpression resolveVariable(java.lang.String)
+meth public abstract jakarta.el.ValueExpression setVariable(java.lang.String,jakarta.el.ValueExpression)
+supr java.lang.Object
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+ anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="9")
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,depth,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface java.util.EventListener
+
+CLSS public java.util.EventObject
+cons public init(java.lang.Object)
+fld protected java.lang.Object source
+intf java.io.Serializable
+meth public java.lang.Object getSource()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds serialVersionUID
+
diff --git a/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/sig-test-pkg-list.txt b/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/sig-test-pkg-list.txt
new file mode 100644
index 0000000..89236c8
--- /dev/null
+++ b/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/sig-test-pkg-list.txt
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2018, 2020 Oracle and/or its affiliates and others.
+# All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+##
+# This file contains a list of all the packages
+# contained in the signature files for this
+# deliverable.  This file is used to exclude valid
+# sub-packages from being verified when their
+# parent package's signature is checked.
+##
+
+jakarta.el
diff --git a/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/sig-test.map b/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/sig-test.map
new file mode 100644
index 0000000..a74a497
--- /dev/null
+++ b/tck/src/main/resources/com/sun/ts/tests/signaturetest/el/sig-test.map
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2018, 2021 Oracle and/or its affiliates and others.
+# All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+###############################################################
+# The signature test mapping file for the JSF TCK.  This file
+# should be formatted as a standard java properties file.  The
+# name is the package name and the value is the version of the
+# package that should be tested by the signature tests.
+###############################################################
+
+jakarta.el=6.0
diff --git a/tck/src/main/resources/jakarta.el.sig_5.0 b/tck/src/main/resources/jakarta.el.sig_5.0
new file mode 100644
index 0000000..dcbc9a3
--- /dev/null
+++ b/tck/src/main/resources/jakarta.el.sig_5.0
@@ -0,0 +1,434 @@
+#Signature file v4.1
+#Version 5.0
+
+CLSS public jakarta.el.ArrayELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly
+
+CLSS public jakarta.el.BeanELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,properties
+hcls BPSoftReference,BeanProperties,BeanProperty,SoftConcurrentHashMap
+
+CLSS public jakarta.el.BeanNameELResolver
+cons public init(jakarta.el.BeanNameResolver)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds beanNameResolver
+
+CLSS public abstract jakarta.el.BeanNameResolver
+cons public init()
+meth public boolean canCreateBean(java.lang.String)
+meth public boolean isNameResolved(java.lang.String)
+meth public boolean isReadOnly(java.lang.String)
+meth public java.lang.Object getBean(java.lang.String)
+meth public void setBeanValue(java.lang.String,java.lang.Object)
+supr java.lang.Object
+
+CLSS public jakarta.el.CompositeELResolver
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void add(jakarta.el.ELResolver)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds elResolvers,size
+hcls CompositeIterator
+
+CLSS public jakarta.el.ELClass
+cons public init(java.lang.Class<?>)
+meth public java.lang.Class<?> getKlass()
+supr java.lang.Object
+hfds klass
+
+CLSS public abstract jakarta.el.ELContext
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract jakarta.el.ELResolver getELResolver()
+meth public abstract jakarta.el.FunctionMapper getFunctionMapper()
+meth public abstract jakarta.el.VariableMapper getVariableMapper()
+meth public boolean isLambdaArgument(java.lang.String)
+meth public boolean isPropertyResolved()
+meth public jakarta.el.ImportHandler getImportHandler()
+meth public java.lang.Object getContext(java.lang.Class<?>)
+meth public java.lang.Object getLambdaArgument(java.lang.String)
+meth public java.util.List<jakarta.el.EvaluationListener> getEvaluationListeners()
+meth public java.util.Locale getLocale()
+meth public void addEvaluationListener(jakarta.el.EvaluationListener)
+meth public void enterLambdaScope(java.util.Map<java.lang.String,java.lang.Object>)
+meth public void exitLambdaScope()
+meth public void notifyAfterEvaluation(java.lang.String)
+meth public void notifyBeforeEvaluation(java.lang.String)
+meth public void notifyPropertyResolved(java.lang.Object,java.lang.Object)
+meth public void putContext(java.lang.Class<?>,java.lang.Object)
+meth public void setLocale(java.util.Locale)
+meth public void setPropertyResolved(boolean)
+meth public void setPropertyResolved(java.lang.Object,java.lang.Object)
+supr java.lang.Object
+hfds importHandler,lambdaArgs,listeners,locale,map,resolved
+
+CLSS public jakarta.el.ELContextEvent
+cons public init(jakarta.el.ELContext)
+meth public jakarta.el.ELContext getELContext()
+supr java.util.EventObject
+hfds serialVersionUID
+
+CLSS public abstract interface jakarta.el.ELContextListener
+intf java.util.EventListener
+meth public abstract void contextCreated(jakarta.el.ELContextEvent)
+
+CLSS public jakarta.el.ELException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public jakarta.el.ELManager
+cons public init()
+meth public jakarta.el.ELContext setELContext(jakarta.el.ELContext)
+meth public jakarta.el.StandardELContext getELContext()
+meth public java.lang.Object defineBean(java.lang.String,java.lang.Object)
+meth public static jakarta.el.ExpressionFactory getExpressionFactory()
+meth public void addBeanNameResolver(jakarta.el.BeanNameResolver)
+meth public void addELResolver(jakarta.el.ELResolver)
+meth public void addEvaluationListener(jakarta.el.EvaluationListener)
+meth public void importClass(java.lang.String)
+meth public void importPackage(java.lang.String)
+meth public void importStatic(java.lang.String)
+meth public void mapFunction(java.lang.String,java.lang.String,java.lang.reflect.Method)
+meth public void setVariable(java.lang.String,jakarta.el.ValueExpression)
+supr java.lang.Object
+hfds elContext
+
+CLSS public jakarta.el.ELProcessor
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} eval(java.lang.String)
+meth public <%0 extends java.lang.Object> {%%0} getValue(java.lang.String,java.lang.Class<{%%0}>)
+meth public jakarta.el.ELManager getELManager()
+meth public void defineBean(java.lang.String,java.lang.Object)
+meth public void defineFunction(java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.ClassNotFoundException,java.lang.NoSuchMethodException
+meth public void defineFunction(java.lang.String,java.lang.String,java.lang.reflect.Method) throws java.lang.NoSuchMethodException
+meth public void setValue(java.lang.String,java.lang.Object)
+meth public void setVariable(java.lang.String,java.lang.String)
+supr java.lang.Object
+hfds elManager,factory
+
+CLSS public abstract jakarta.el.ELResolver
+cons public init()
+fld public final static java.lang.String RESOLVABLE_AT_DESIGN_TIME = "resolvableAtDesignTime"
+fld public final static java.lang.String TYPE = "type"
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public abstract java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.EvaluationListener
+cons public init()
+meth public void afterEvaluation(jakarta.el.ELContext,java.lang.String)
+meth public void beforeEvaluation(jakarta.el.ELContext,java.lang.String)
+meth public void propertyResolved(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.Expression
+cons public init()
+intf java.io.Serializable
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract boolean isLiteralText()
+meth public abstract int hashCode()
+meth public abstract java.lang.String getExpressionString()
+supr java.lang.Object
+hfds serialVersionUID
+
+CLSS public abstract jakarta.el.ExpressionFactory
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} coerceToType(java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract jakarta.el.MethodExpression createMethodExpression(jakarta.el.ELContext,java.lang.String,java.lang.Class<?>,java.lang.Class<?>[])
+meth public abstract jakarta.el.ValueExpression createValueExpression(jakarta.el.ELContext,java.lang.String,java.lang.Class<?>)
+meth public abstract jakarta.el.ValueExpression createValueExpression(java.lang.Object,java.lang.Class<?>)
+meth public jakarta.el.ELResolver getStreamELResolver()
+meth public java.util.Map<java.lang.String,java.lang.reflect.Method> getInitFunctionMap()
+meth public static jakarta.el.ExpressionFactory newInstance()
+meth public static jakarta.el.ExpressionFactory newInstance(java.util.Properties)
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.FunctionMapper
+cons public init()
+meth public abstract java.lang.reflect.Method resolveFunction(java.lang.String,java.lang.String)
+meth public void mapFunction(java.lang.String,java.lang.String,java.lang.reflect.Method)
+supr java.lang.Object
+
+CLSS public jakarta.el.ImportHandler
+cons public init()
+meth public java.lang.Class<?> resolveClass(java.lang.String)
+meth public java.lang.Class<?> resolveStatic(java.lang.String)
+meth public void importClass(java.lang.String)
+meth public void importPackage(java.lang.String)
+meth public void importStatic(java.lang.String)
+supr java.lang.Object
+hfds classMap,classNameMap,notAClass,packages,staticNameMap
+
+CLSS public jakarta.el.LambdaExpression
+cons public init(java.util.List<java.lang.String>,jakarta.el.ValueExpression)
+meth public !varargs java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object[])
+meth public !varargs java.lang.Object invoke(java.lang.Object[])
+meth public void setELContext(jakarta.el.ELContext)
+supr java.lang.Object
+hfds context,envirArgs,expression,formalParameters
+
+CLSS public jakarta.el.ListELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,theUnmodifiableListClass
+
+CLSS public jakarta.el.MapELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,theUnmodifiableMapClass
+
+CLSS public abstract jakarta.el.MethodExpression
+cons public init()
+meth public abstract jakarta.el.MethodInfo getMethodInfo(jakarta.el.ELContext)
+meth public abstract java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object[])
+meth public boolean isParametersProvided()
+meth public jakarta.el.MethodReference getMethodReference(jakarta.el.ELContext)
+supr jakarta.el.Expression
+hfds serialVersionUID
+
+CLSS public jakarta.el.MethodInfo
+cons public init(java.lang.String,java.lang.Class<?>,java.lang.Class<?>[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.Class<?> getReturnType()
+meth public java.lang.Class<?>[] getParamTypes()
+meth public java.lang.String getName()
+supr java.lang.Object
+hfds name,paramTypes,returnType
+
+CLSS public jakarta.el.MethodNotFoundException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.MethodReference
+cons public init(java.lang.Object,jakarta.el.MethodInfo,java.lang.annotation.Annotation[],java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public jakarta.el.MethodInfo getMethodInfo()
+meth public java.lang.Object getBase()
+meth public java.lang.Object[] getEvaluatedParameters()
+meth public java.lang.annotation.Annotation[] getAnnotations()
+supr java.lang.Object
+hfds annotations,base,evaluatedParameters,methodInfo
+
+CLSS public jakarta.el.PropertyNotFoundException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.PropertyNotWritableException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.ResourceBundleELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public jakarta.el.StandardELContext
+cons public init(jakarta.el.ELContext)
+cons public init(jakarta.el.ExpressionFactory)
+meth public jakarta.el.ELResolver getELResolver()
+meth public jakarta.el.FunctionMapper getFunctionMapper()
+meth public jakarta.el.VariableMapper getVariableMapper()
+meth public java.lang.Object getContext(java.lang.Class<?>)
+meth public void addELResolver(jakarta.el.ELResolver)
+meth public void putContext(java.lang.Class<?>,java.lang.Object)
+supr jakarta.el.ELContext
+hfds beans,customResolvers,delegate,elResolver,functionMapper,initFunctionMap,streamELResolver,variableMapper
+hcls DefaultFunctionMapper,DefaultVariableMapper,LocalBeanNameResolver
+
+CLSS public jakarta.el.StaticFieldELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public abstract jakarta.el.TypeConverter
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.util.Iterator<java.beans.FeatureDescriptor> getFeatureDescriptors(jakarta.el.ELContext,java.lang.Object)
+ anno 0 java.lang.Deprecated(boolean forRemoval=true, java.lang.String since="5.0")
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public abstract jakarta.el.ValueExpression
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} getValue(jakarta.el.ELContext)
+meth public abstract boolean isReadOnly(jakarta.el.ELContext)
+meth public abstract java.lang.Class<?> getExpectedType()
+meth public abstract java.lang.Class<?> getType(jakarta.el.ELContext)
+meth public abstract void setValue(jakarta.el.ELContext,java.lang.Object)
+meth public jakarta.el.ValueReference getValueReference(jakarta.el.ELContext)
+supr jakarta.el.Expression
+hfds serialVersionUID
+
+CLSS public jakarta.el.ValueReference
+cons public init(java.lang.Object,java.lang.Object)
+intf java.io.Serializable
+meth public java.lang.Object getBase()
+meth public java.lang.Object getProperty()
+supr java.lang.Object
+hfds base,property,serialVersionUID
+
+CLSS public abstract jakarta.el.VariableMapper
+cons public init()
+meth public abstract jakarta.el.ValueExpression resolveVariable(java.lang.String)
+meth public abstract jakarta.el.ValueExpression setVariable(java.lang.String,jakarta.el.ValueExpression)
+supr java.lang.Object
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+ anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="9")
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+
+CLSS public abstract interface java.util.EventListener
+
+CLSS public java.util.EventObject
+cons public init(java.lang.Object)
+fld protected java.lang.Object source
+intf java.io.Serializable
+meth public java.lang.Object getSource()
+meth public java.lang.String toString()
+supr java.lang.Object
+
diff --git a/tck/src/main/resources/jakarta.el.sig_6.0 b/tck/src/main/resources/jakarta.el.sig_6.0
new file mode 100644
index 0000000..89efd20
--- /dev/null
+++ b/tck/src/main/resources/jakarta.el.sig_6.0
@@ -0,0 +1,436 @@
+#Signature file v4.1
+#Version 6.0.0
+
+CLSS public jakarta.el.ArrayELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds LENGTH_PROPERTY_NAME,isReadOnly
+
+CLSS public jakarta.el.BeanELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,properties
+hcls BPSoftReference,BeanProperties,BeanProperty,SoftConcurrentHashMap
+
+CLSS public jakarta.el.BeanNameELResolver
+cons public init(jakarta.el.BeanNameResolver)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds beanNameResolver
+
+CLSS public abstract jakarta.el.BeanNameResolver
+cons public init()
+meth public boolean canCreateBean(java.lang.String)
+meth public boolean isNameResolved(java.lang.String)
+meth public boolean isReadOnly(java.lang.String)
+meth public java.lang.Object getBean(java.lang.String)
+meth public void setBeanValue(java.lang.String,java.lang.Object)
+supr java.lang.Object
+
+CLSS public jakarta.el.CompositeELResolver
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public void add(jakarta.el.ELResolver)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds elResolvers,size
+
+CLSS public jakarta.el.ELClass
+cons public init(java.lang.Class<?>)
+meth public java.lang.Class<?> getKlass()
+supr java.lang.Object
+hfds klass
+
+CLSS public abstract jakarta.el.ELContext
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract jakarta.el.ELResolver getELResolver()
+meth public abstract jakarta.el.FunctionMapper getFunctionMapper()
+meth public abstract jakarta.el.VariableMapper getVariableMapper()
+meth public boolean isLambdaArgument(java.lang.String)
+meth public boolean isPropertyResolved()
+meth public jakarta.el.ImportHandler getImportHandler()
+meth public java.lang.Object getContext(java.lang.Class<?>)
+meth public java.lang.Object getLambdaArgument(java.lang.String)
+meth public java.util.List<jakarta.el.EvaluationListener> getEvaluationListeners()
+meth public java.util.Locale getLocale()
+meth public void addEvaluationListener(jakarta.el.EvaluationListener)
+meth public void enterLambdaScope(java.util.Map<java.lang.String,java.lang.Object>)
+meth public void exitLambdaScope()
+meth public void notifyAfterEvaluation(java.lang.String)
+meth public void notifyBeforeEvaluation(java.lang.String)
+meth public void notifyPropertyResolved(java.lang.Object,java.lang.Object)
+meth public void putContext(java.lang.Class<?>,java.lang.Object)
+meth public void setLocale(java.util.Locale)
+meth public void setPropertyResolved(boolean)
+meth public void setPropertyResolved(java.lang.Object,java.lang.Object)
+supr java.lang.Object
+hfds importHandler,lambdaArgs,listeners,locale,map,resolved
+
+CLSS public jakarta.el.ELContextEvent
+cons public init(jakarta.el.ELContext)
+meth public jakarta.el.ELContext getELContext()
+supr java.util.EventObject
+hfds serialVersionUID
+
+CLSS public abstract interface jakarta.el.ELContextListener
+intf java.util.EventListener
+meth public abstract void contextCreated(jakarta.el.ELContextEvent)
+
+CLSS public jakarta.el.ELException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.RuntimeException
+hfds serialVersionUID
+
+CLSS public jakarta.el.ELManager
+cons public init()
+meth public jakarta.el.ELContext setELContext(jakarta.el.ELContext)
+meth public jakarta.el.StandardELContext getELContext()
+meth public java.lang.Object defineBean(java.lang.String,java.lang.Object)
+meth public static jakarta.el.ExpressionFactory getExpressionFactory()
+meth public void addBeanNameResolver(jakarta.el.BeanNameResolver)
+meth public void addELResolver(jakarta.el.ELResolver)
+meth public void addEvaluationListener(jakarta.el.EvaluationListener)
+meth public void importClass(java.lang.String)
+meth public void importPackage(java.lang.String)
+meth public void importStatic(java.lang.String)
+meth public void mapFunction(java.lang.String,java.lang.String,java.lang.reflect.Method)
+meth public void setVariable(java.lang.String,jakarta.el.ValueExpression)
+supr java.lang.Object
+hfds elContext,exprFactory
+
+CLSS public jakarta.el.ELProcessor
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} eval(java.lang.String)
+meth public <%0 extends java.lang.Object> {%%0} getValue(java.lang.String,java.lang.Class<{%%0}>)
+meth public jakarta.el.ELManager getELManager()
+meth public void defineBean(java.lang.String,java.lang.Object)
+meth public void defineFunction(java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.ClassNotFoundException,java.lang.NoSuchMethodException
+meth public void defineFunction(java.lang.String,java.lang.String,java.lang.reflect.Method) throws java.lang.NoSuchMethodException
+meth public void setValue(java.lang.String,java.lang.Object)
+meth public void setVariable(java.lang.String,java.lang.String)
+supr java.lang.Object
+hfds elManager,factory
+
+CLSS public abstract jakarta.el.ELResolver
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public abstract java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public abstract void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.EvaluationListener
+cons public init()
+meth public void afterEvaluation(jakarta.el.ELContext,java.lang.String)
+meth public void beforeEvaluation(jakarta.el.ELContext,java.lang.String)
+meth public void propertyResolved(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.Expression
+cons public init()
+intf java.io.Serializable
+meth public abstract boolean equals(java.lang.Object)
+meth public abstract boolean isLiteralText()
+meth public abstract int hashCode()
+meth public abstract java.lang.String getExpressionString()
+supr java.lang.Object
+hfds serialVersionUID
+
+CLSS public abstract jakarta.el.ExpressionFactory
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} coerceToType(java.lang.Object,java.lang.Class<{%%0}>)
+meth public abstract jakarta.el.MethodExpression createMethodExpression(jakarta.el.ELContext,java.lang.String,java.lang.Class<?>,java.lang.Class<?>[])
+meth public abstract jakarta.el.ValueExpression createValueExpression(jakarta.el.ELContext,java.lang.String,java.lang.Class<?>)
+meth public abstract jakarta.el.ValueExpression createValueExpression(java.lang.Object,java.lang.Class<?>)
+meth public jakarta.el.ELResolver getStreamELResolver()
+meth public java.util.Map<java.lang.String,java.lang.reflect.Method> getInitFunctionMap()
+meth public static jakarta.el.ExpressionFactory newInstance()
+meth public static jakarta.el.ExpressionFactory newInstance(java.util.Properties)
+supr java.lang.Object
+
+CLSS public abstract jakarta.el.FunctionMapper
+cons public init()
+meth public abstract java.lang.reflect.Method resolveFunction(java.lang.String,java.lang.String)
+meth public void mapFunction(java.lang.String,java.lang.String,java.lang.reflect.Method)
+supr java.lang.Object
+
+CLSS public jakarta.el.ImportHandler
+cons public init()
+meth public java.lang.Class<?> resolveClass(java.lang.String)
+meth public java.lang.Class<?> resolveStatic(java.lang.String)
+meth public void importClass(java.lang.String)
+meth public void importPackage(java.lang.String)
+meth public void importStatic(java.lang.String)
+supr java.lang.Object
+hfds classMap,classNameMap,notAClass,packages,staticNameMap
+
+CLSS public jakarta.el.LambdaExpression
+cons public init(java.util.List<java.lang.String>,jakarta.el.ValueExpression)
+meth public !varargs java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object[])
+meth public !varargs java.lang.Object invoke(java.lang.Object[])
+meth public void setELContext(jakarta.el.ELContext)
+supr java.lang.Object
+hfds context,envirArgs,expression,formalParameters
+
+CLSS public jakarta.el.ListELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,theUnmodifiableListClass
+
+CLSS public jakarta.el.MapELResolver
+cons public init()
+cons public init(boolean)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+hfds isReadOnly,theUnmodifiableMapClass
+
+CLSS public abstract jakarta.el.MethodExpression
+cons public init()
+meth public abstract jakarta.el.MethodInfo getMethodInfo(jakarta.el.ELContext)
+meth public abstract java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object[])
+meth public boolean isParametersProvided()
+meth public jakarta.el.MethodReference getMethodReference(jakarta.el.ELContext)
+supr jakarta.el.Expression
+hfds serialVersionUID
+
+CLSS public jakarta.el.MethodInfo
+cons public init(java.lang.String,java.lang.Class<?>,java.lang.Class<?>[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public java.lang.Class<?> getReturnType()
+meth public java.lang.Class<?>[] getParamTypes()
+meth public java.lang.String getName()
+supr java.lang.Object
+hfds name,paramTypes,returnType
+
+CLSS public jakarta.el.MethodNotFoundException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.MethodReference
+cons public init(java.lang.Object,jakarta.el.MethodInfo,java.lang.annotation.Annotation[],java.lang.Object[])
+meth public boolean equals(java.lang.Object)
+meth public int hashCode()
+meth public jakarta.el.MethodInfo getMethodInfo()
+meth public java.lang.Object getBase()
+meth public java.lang.Object[] getEvaluatedParameters()
+meth public java.lang.annotation.Annotation[] getAnnotations()
+supr java.lang.Object
+hfds annotations,base,evaluatedParameters,methodInfo
+
+CLSS public jakarta.el.OptionalELResolver
+cons public init()
+meth public <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public jakarta.el.PropertyNotFoundException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.PropertyNotWritableException
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr jakarta.el.ELException
+hfds serialVersionUID
+
+CLSS public jakarta.el.RecordELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public jakarta.el.ResourceBundleELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public jakarta.el.StandardELContext
+cons public init(jakarta.el.ELContext)
+cons public init(jakarta.el.ExpressionFactory)
+meth public jakarta.el.ELResolver getELResolver()
+meth public jakarta.el.FunctionMapper getFunctionMapper()
+meth public jakarta.el.VariableMapper getVariableMapper()
+meth public java.lang.Object getContext(java.lang.Class<?>)
+meth public void addELResolver(jakarta.el.ELResolver)
+meth public void putContext(java.lang.Class<?>,java.lang.Object)
+supr jakarta.el.ELContext
+hfds beans,customResolvers,delegate,elResolver,functionMapper,initFunctionMap,streamELResolver,variableMapper
+hcls DefaultFunctionMapper,DefaultVariableMapper,LocalBeanNameResolver
+
+CLSS public jakarta.el.StaticFieldELResolver
+cons public init()
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object invoke(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Class<?>[],java.lang.Object[])
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public abstract jakarta.el.TypeConverter
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} convertToType(jakarta.el.ELContext,java.lang.Object,java.lang.Class<{%%0}>)
+meth public boolean isReadOnly(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Class<?> getCommonPropertyType(jakarta.el.ELContext,java.lang.Object)
+meth public java.lang.Class<?> getType(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public java.lang.Object getValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object)
+meth public void setValue(jakarta.el.ELContext,java.lang.Object,java.lang.Object,java.lang.Object)
+supr jakarta.el.ELResolver
+
+CLSS public abstract jakarta.el.ValueExpression
+cons public init()
+meth public abstract <%0 extends java.lang.Object> {%%0} getValue(jakarta.el.ELContext)
+meth public abstract boolean isReadOnly(jakarta.el.ELContext)
+meth public abstract java.lang.Class<?> getExpectedType()
+meth public abstract java.lang.Class<?> getType(jakarta.el.ELContext)
+meth public abstract void setValue(jakarta.el.ELContext,java.lang.Object)
+meth public jakarta.el.ValueReference getValueReference(jakarta.el.ELContext)
+supr jakarta.el.Expression
+hfds serialVersionUID
+
+CLSS public jakarta.el.ValueReference
+cons public init(java.lang.Object,java.lang.Object)
+intf java.io.Serializable
+meth public java.lang.Object getBase()
+meth public java.lang.Object getProperty()
+supr java.lang.Object
+hfds base,property,serialVersionUID
+
+CLSS public abstract jakarta.el.VariableMapper
+cons public init()
+meth public abstract jakarta.el.ValueExpression resolveVariable(java.lang.String)
+meth public abstract jakarta.el.ValueExpression setVariable(java.lang.String,jakarta.el.ValueExpression)
+supr java.lang.Object
+
+CLSS public abstract interface java.io.Serializable
+
+CLSS public java.lang.Exception
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Throwable
+hfds serialVersionUID
+
+CLSS public java.lang.Object
+cons public init()
+meth protected java.lang.Object clone() throws java.lang.CloneNotSupportedException
+meth protected void finalize() throws java.lang.Throwable
+ anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="9")
+meth public boolean equals(java.lang.Object)
+meth public final java.lang.Class<?> getClass()
+meth public final void notify()
+meth public final void notifyAll()
+meth public final void wait() throws java.lang.InterruptedException
+meth public final void wait(long) throws java.lang.InterruptedException
+meth public final void wait(long,int) throws java.lang.InterruptedException
+meth public int hashCode()
+meth public java.lang.String toString()
+
+CLSS public java.lang.RuntimeException
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+supr java.lang.Exception
+hfds serialVersionUID
+
+CLSS public java.lang.Throwable
+cons protected init(java.lang.String,java.lang.Throwable,boolean,boolean)
+cons public init()
+cons public init(java.lang.String)
+cons public init(java.lang.String,java.lang.Throwable)
+cons public init(java.lang.Throwable)
+intf java.io.Serializable
+meth public final java.lang.Throwable[] getSuppressed()
+meth public final void addSuppressed(java.lang.Throwable)
+meth public java.lang.StackTraceElement[] getStackTrace()
+meth public java.lang.String getLocalizedMessage()
+meth public java.lang.String getMessage()
+meth public java.lang.String toString()
+meth public java.lang.Throwable fillInStackTrace()
+meth public java.lang.Throwable getCause()
+meth public java.lang.Throwable initCause(java.lang.Throwable)
+meth public void printStackTrace()
+meth public void printStackTrace(java.io.PrintStream)
+meth public void printStackTrace(java.io.PrintWriter)
+meth public void setStackTrace(java.lang.StackTraceElement[])
+supr java.lang.Object
+hfds CAUSE_CAPTION,EMPTY_THROWABLE_ARRAY,NULL_CAUSE_MESSAGE,SELF_SUPPRESSION_MESSAGE,SUPPRESSED_CAPTION,SUPPRESSED_SENTINEL,UNASSIGNED_STACK,backtrace,cause,depth,detailMessage,serialVersionUID,stackTrace,suppressedExceptions
+hcls PrintStreamOrWriter,SentinelHolder,WrappedPrintStream,WrappedPrintWriter
+
+CLSS public abstract interface java.util.EventListener
+
+CLSS public java.util.EventObject
+cons public init(java.lang.Object)
+fld protected java.lang.Object source
+intf java.io.Serializable
+meth public java.lang.Object getSource()
+meth public java.lang.String toString()
+supr java.lang.Object
+hfds serialVersionUID
+