diff --git a/api/pom.xml b/api/pom.xml
deleted file mode 100644
index 4b69e29..0000000
--- a/api/pom.xml
+++ /dev/null
@@ -1,253 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 1997, 2018 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>
-        <relativePath/>
-    </parent>
-    
-    <groupId>jakarta.el</groupId>
-    <artifactId>jakarta.el-api</artifactId>
-    <version>3.0.3-SNAPSHOT</version>
-    
-    <name>Jakarta Expression Language 3.0 API</name>
-    <description>
-        Jakarta Expression Language defines an expression language for Java applications
-    </description>
-    <url>https://projects.eclipse.org/projects/ee4j.el</url>
-
-    <properties>
-        <!-- Make sure the two versions are in sync with the maven version -->
-        <spec.version>3.0</spec.version>
-        <bundle.version>3.0.3</bundle.version>
-        <extensionName>javax.el</extensionName>
-        <bundle.symbolicName>javax.el-api</bundle.symbolicName>
-        <vendorName>Oracle Corporation</vendorName>
-        <findbugs.version>2.4.0</findbugs.version>
-        <findbugs.exclude />
-        <findbugs.threshold>High</findbugs.threshold>
-    </properties>
-
-    <licenses>
-        <license>
-            <name>EPL 2.0</name>
-            <url>http://www.eclipse.org/legal/epl-2.0</url>
-            <distribution>repo</distribution>
-        </license>
-        <license>
-            <name>GPL2 w/ CPE</name>
-            <url>https://www.gnu.org/software/classpath/license.html</url>
-            <distribution>repo</distribution>
-        </license>
-    </licenses>
-    
-    <issueManagement>
-        <system>github</system>
-        <url>https://github.com/eclipse-ee4j/el-ri/issues</url>
-    </issueManagement>
-    
-    <mailingLists>
-        <mailingList>
-            <name>Jakarta Expression Language mailing list</name>
-            <post>el-dev@eclipse.org</post>
-            <subscribe>https://dev.eclipse.org/mailman/listinfo/el-dev</subscribe>
-            <unsubscribe>https://dev.eclipse.org/mailman/listinfo/el-dev</unsubscribe>
-            <archive>https://dev.eclipse.org/mhonarc/lists/el-dev</archive>
-        </mailingList>
-    </mailingLists>
-    
-    <scm>
-        <connection>scm:git:https://github.com/eclipse-ee4j/el-ri.git</connection>
-        <developerConnection>scm:git:git@github.com:eclipse-ee4j/el-ri.git</developerConnection>
-        <url>https://github.com/eclipse-ee4j/el-ri</url>
-        <tag>HEAD</tag>
-    </scm>
-
-    <developers>
-        <developer>
-            <id>yaminikb</id>
-            <name>Yamini K B</name>
-            <organization>Oracle Corporation</organization>
-            <organizationUrl>http://www.oracle.com/</organizationUrl>
-        </developer>
-    </developers>
-
-    <contributors>
-        <contributor>
-            <name>Kin-man Chung</name>
-        </contributor>
-    </contributors>
-
-    <build>
-        <resources>
-            <resource>
-                <directory>src/main/java</directory>
-                <includes>
-                    <include>**/*.properties</include>
-                </includes>
-            </resource>
-            <resource>
-                <directory>${project.basedir}/..</directory>
-                <includes>
-                    <include>LICENSE.md</include>
-                    <include>NOTICE.md</include>
-                </includes>
-                <targetPath>META-INF</targetPath>
-            </resource>
-        </resources>
-    
-        <plugins>
-             <!-- Restricts the Java version to 1.7 -->
-             <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <version>3.0</version>
-                <configuration>
-                    <source>1.7</source>
-                    <target>1.7</target>
-                    <compilerArgument>-Xlint:unchecked</compilerArgument>
-                </configuration>
-            </plugin>
-        
-        
-            <!-- Creates the OSGi MANIFEST.MF file -->        
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <version>1.4.3</version>
-                <configuration>
-                    <supportedProjectTypes>
-                        <supportedProjectType>jar</supportedProjectType>
-                    </supportedProjectTypes>
-                    <instructions>
-                        <Bundle-Description>Jakarta Expression Language ${spec.version}</Bundle-Description>
-                        <Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName>
-                        <Bundle-Version>${bundle.version}</Bundle-Version>
-                        <Extension-Name>${extensionName}</Extension-Name>
-                        <Specification-Version>${spec.version}</Specification-Version>
-                        <Specification-Vendor>${vendorName}</Specification-Vendor>
-                        <Implementation-Version>${project.version}</Implementation-Version>
-                        <Implementation-Vendor>${vendorName}</Implementation-Vendor>
-                        <Export-Package>javax.el</Export-Package>
-                    </instructions>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>bundle-manifest</id>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>manifest</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            
-            <!-- Adds the manifest file created by the org.apache.felix:maven-bundle-plugin -->
-            <plugin>
-                <artifactId>maven-jar-plugin</artifactId>
-                <version>2.4</version>
-                <configuration>
-                    <archive>
-                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
-                    </archive>
-                    <excludes>
-                        <exclude>**/*.java</exclude>
-                    </excludes>
-                </configuration>
-            </plugin>
-            
-            <!-- Creates the source jar -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-source-plugin</artifactId>
-                <version>3.0.1</version>
-                <configuration>
-                    <includePom>true</includePom>
-                </configuration>
-                <executions>
-                    <execution>
-                       <id>attach-sources</id>
-                       <goals>
-                           <goal>jar-no-fork</goal> 
-                       </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <version>3.0.1</version>
-            </plugin>
-            
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>findbugs-maven-plugin</artifactId>
-                <version>${findbugs.version}</version>
-                <configuration>
-                    <threshold>${findbugs.threshold}</threshold>
-                    <excludeFilterFile>${findbugs.exclude}</excludeFilterFile>
-                    <findbugsXmlOutput>true</findbugsXmlOutput>
-                    <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-release-plugin</artifactId>
-                <configuration>
-                    <mavenExecutorId>forked-path</mavenExecutorId>
-                    <useReleaseProfile>false</useReleaseProfile>
-                    <arguments>${release.arguments}</arguments>
-                </configuration>
-            </plugin>
-            
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-enforcer-plugin</artifactId>
-                <version>3.0.0-M2</version>
-            </plugin>               
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-gpg-plugin</artifactId>
-                <version>1.6</version>          
-            </plugin>
-        </plugins>
-    </build>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>findbugs-maven-plugin</artifactId>
-                <version>${findbugs.version}</version>
-                <configuration>
-                    <threshold>${findbugs.threshold}</threshold>
-                    <excludeFilterFile>${findbugs.exclude}</excludeFilterFile>
-                </configuration>
-            </plugin>
-        </plugins>
-    </reporting>
-</project>
diff --git a/api/src/main/java/javax/el/ArrayELResolver.java b/api/src/main/java/javax/el/ArrayELResolver.java
deleted file mode 100644
index aa088f5..0000000
--- a/api/src/main/java/javax/el/ArrayELResolver.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.beans.FeatureDescriptor;
-import java.lang.reflect.Array;
-import java.util.Iterator;
-
-/**
- * Defines property resolution behavior on arrays.
- *
- * <p>
- * This resolver handles base objects that are Java language arrays. It accepts any object as a property and coerces
- * that object into an integer index into the array. The resulting value is the value in the array at that index.
- * </p>
- *
- * <p>
- * This resolver can be constructed in read-only mode, which means that {@link #isReadOnly} will always return
- * <code>true</code> and {@link #setValue} will always throw <code>PropertyNotWritableException</code>.
- * </p>
- *
- * <p>
- * <code>ELResolver</code>s are combined together using {@link CompositeELResolver}s, to define rich semantics for
- * evaluating an expression. See the javadocs for {@link ELResolver} for details.
- * </p>
- *
- * @see CompositeELResolver
- * @see ELResolver
- * 
- * @since Jakarta Server Pages 2.1
- */
-public class ArrayELResolver extends ELResolver {
-
-    /**
-     * Creates a new read/write <code>ArrayELResolver</code>.
-     */
-    public ArrayELResolver() {
-        this.isReadOnly = false;
-    }
-
-    /**
-     * Creates a new <code>ArrayELResolver</code> whose read-only status is determined by the given parameter.
-     *
-     * @param isReadOnly <code>true</code> if this resolver cannot modify arrays; <code>false</code> otherwise.
-     */
-    public ArrayELResolver(boolean isReadOnly) {
-        this.isReadOnly = isReadOnly;
-    }
-
-    /**
-     * If the base object is an array, returns the most general acceptable type for a value in this array.
-     *
-     * <p>
-     * If the base is a <code>array</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * Assuming the base is an <code>array</code>, this method will always return
-     * <code>base.getClass().getComponentType()</code>, which is the most general type of component that can be stored at
-     * any given index in the array.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The array to analyze. Only bases that are Java language arrays are handled by this resolver.
-     * @param property The index of the element in the array to return the acceptable type for. Will be coerced into an
-     * integer, but otherwise ignored by this resolver.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the most general acceptable type; otherwise undefined.
-     * @throws PropertyNotFoundException if the given index is out of bounds for this array.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws ELException 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.
-     */
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base.getClass().isArray()) {
-            context.setPropertyResolved(true);
-            int index = toInteger(property);
-            if (index < 0 || index >= Array.getLength(base)) {
-                throw new PropertyNotFoundException();
-            }
-            return base.getClass().getComponentType();
-        }
-        return null;
-    }
-
-    /**
-     * If the base object is a Java language array, returns the value at the given index. The index is specified by the
-     * <code>property</code> argument, and coerced into an integer. If the coercion could not be performed, an
-     * <code>IllegalArgumentException</code> is thrown. If the index is out of bounds, <code>null</code> is returned.
-     *
-     * <p>
-     * If the base is a Java language array, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The array to analyze. Only bases that are Java language arrays are handled by this resolver.
-     * @param property The index of the value to be returned. Will be coerced into an integer.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the value at the given index or <code>null</code> if the index was out of bounds. Otherwise, undefined.
-     * @throws IllegalArgumentException if the property could not be coerced into an integer.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws ELException 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.
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base.getClass().isArray()) {
-            context.setPropertyResolved(base, property);
-            int index = toInteger(property);
-            if (index >= 0 && index < Array.getLength(base)) {
-                return Array.get(base, index);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * 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 <code>property</code> argument, and coerced into an integer. If the coercion could not be
-     * performed, an <code>IllegalArgumentException</code> is thrown. If the index is out of bounds, a
-     * <code>PropertyNotFoundException</code> is thrown.
-     *
-     * <p>
-     * If the base is a Java language array, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller can safely assume no value was set.
-     * </p>
-     *
-     * <p>
-     * If this resolver was constructed in read-only mode, this method will always throw
-     * <code>PropertyNotWritableException</code>.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The array to be modified. Only bases that are Java language arrays are handled by this resolver.
-     * @param property The index of the value to be set. Will be coerced into an integer.
-     * @param val The value to be set at the given index.
-     * @throws ClassCastException if the class of the specified element prevents it from being added to this array.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws IllegalArgumentException 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.
-     * @throws PropertyNotWritableException if this resolver was constructed in read-only mode.
-     * @throws PropertyNotFoundException if the given index is out of bounds for this array.
-     * @throws ELException 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.
-     */
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object val) {
-
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base.getClass().isArray()) {
-            context.setPropertyResolved(base, property);
-            if (isReadOnly) {
-                throw new PropertyNotWritableException();
-            }
-            Class<?> type = base.getClass().getComponentType();
-            if (val != null && !type.isAssignableFrom(val.getClass())) {
-                throw new ClassCastException();
-            }
-            int index = toInteger(property);
-            if (index < 0 || index >= Array.getLength(base)) {
-                throw new PropertyNotFoundException();
-            }
-            Array.set(base, index, val);
-        }
-    }
-
-    /**
-     * If the base object is a Java language array, returns whether a call to {@link #setValue} will always fail.
-     *
-     * <p>
-     * If the base is a Java language array, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * If this resolver was constructed in read-only mode, this method will always return <code>true</code>. Otherwise, it
-     * returns <code>false</code>.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The array to analyze. Only bases that are a Java language array are handled by this resolver.
-     * @param property The index of the element in the array to return the acceptable type for. Will be coerced into an
-     * integer, but otherwise ignored by this resolver.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>true</code> if calling the <code>setValue</code> method will always fail or <code>false</code> if it is
-     * possible that such a call may succeed; otherwise undefined.
-     * @throws PropertyNotFoundException if the given index is out of bounds for this array.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws ELException 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.
-     */
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base.getClass().isArray()) {
-            context.setPropertyResolved(true);
-            int index = toInteger(property);
-            if (index < 0 || index >= Array.getLength(base)) {
-                throw new PropertyNotFoundException();
-            }
-        }
-        return isReadOnly;
-    }
-
-    /**
-     * Always returns <code>null</code>, since there is no reason to iterate through set set of all integers.
-     *
-     * <p>
-     * The {@link #getCommonPropertyType} method returns sufficient information about what properties this resolver accepts.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The array to analyze. Only bases that are a Java language array are handled by this resolver.
-     * @return <code>null</code>.
-     */
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        return null;
-    }
-
-    /**
-     * If the base object is a Java language array, returns the most general type that this resolver accepts for the
-     * <code>property</code> argument. Otherwise, returns <code>null</code>.
-     *
-     * <p>
-     * Assuming the base is an array, this method will always return <code>Integer.class</code>. This is because arrays
-     * accept integers for their index.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The array to analyze. Only bases that are a Java language array are handled by this resolver.
-     * @return <code>null</code> if base is not a Java language array; otherwise <code>Integer.class</code>.
-     */
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-
-        if (base != null && base.getClass().isArray()) {
-            return Integer.class;
-        }
-        return null;
-    }
-
-    private int toInteger(Object p) {
-
-        if (p instanceof Integer) {
-            return ((Integer) p).intValue();
-        }
-        if (p instanceof Character) {
-            return ((Character) p).charValue();
-        }
-        if (p instanceof Boolean) {
-            return ((Boolean) p).booleanValue() ? 1 : 0;
-        }
-        if (p instanceof Number) {
-            return ((Number) p).intValue();
-        }
-        if (p instanceof String) {
-            return Integer.parseInt((String) p);
-        }
-        throw new IllegalArgumentException();
-    }
-
-    private boolean isReadOnly;
-}
diff --git a/api/src/main/java/javax/el/BeanELResolver.java b/api/src/main/java/javax/el/BeanELResolver.java
deleted file mode 100644
index 2ffd50d..0000000
--- a/api/src/main/java/javax/el/BeanELResolver.java
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import static java.lang.Boolean.TRUE;
-import static javax.el.ELUtil.getExceptionMessageString;
-
-import java.beans.BeanInfo;
-import java.beans.FeatureDescriptor;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Defines property resolution behavior on objects using the JavaBeans component architecture.
- *
- * <p>
- * This resolver handles base objects of any type, as long as the base is not <code>null</code>. It accepts any object
- * as a property or method, and coerces it to a string.
- *
- * <p>
- * For property resolution, the property string is used to find a JavaBeans compliant property on the base object. The
- * value is accessed using JavaBeans getters and setters.
- * </p>
- *
- * <p>
- * For method resolution, the method string is the name of the method in the bean. The parameter types can be optionally
- * specified to identify the method. If the parameter types are not specified, the parameter objects are used in the
- * method resolution.
- * </p>
- *
- * <p>
- * This resolver can be constructed in read-only mode, which means that {@link #isReadOnly} will always return
- * <code>true</code> and {@link #setValue} will always throw <code>PropertyNotWritableException</code>.
- * </p>
- *
- * <p>
- * <code>ELResolver</code>s are combined together using {@link CompositeELResolver}s, to define rich semantics for
- * evaluating an expression. See the javadocs for {@link ELResolver} for details.
- * </p>
- *
- * <p>
- * Because this resolver handles base objects of any type, it should be placed near the end of a composite resolver.
- * Otherwise, it will claim to have resolved a property before any resolvers that come after it get a chance to test if
- * they can do so as well.
- * </p>
- *
- * @see CompositeELResolver
- * @see ELResolver
- * 
- * @since Jakarta Server Pages 2.1
- */
-public class BeanELResolver extends ELResolver {
-
-    static private class BPSoftReference extends SoftReference<BeanProperties> {
-        final Class<?> key;
-
-        BPSoftReference(Class<?> key, BeanProperties beanProperties, ReferenceQueue<BeanProperties> refQ) {
-            super(beanProperties, refQ);
-            this.key = key;
-        }
-    }
-
-    static private class SoftConcurrentHashMap extends ConcurrentHashMap<Class<?>, BeanProperties> {
-
-        private static final long serialVersionUID = -178867497897782229L;
-        private static final int CACHE_INIT_SIZE = 1024;
-        private ConcurrentHashMap<Class<?>, BPSoftReference> map = new ConcurrentHashMap<>(CACHE_INIT_SIZE);
-        private ReferenceQueue<BeanProperties> refQ = new ReferenceQueue<>();
-
-        // Remove map entries that have been placed on the queue by GC.
-        private void cleanup() {
-            BPSoftReference BPRef = null;
-            while ((BPRef = (BPSoftReference) refQ.poll()) != null) {
-                map.remove(BPRef.key);
-            }
-        }
-
-        @Override
-        public BeanProperties put(Class<?> key, BeanProperties value) {
-            cleanup();
-            BPSoftReference prev = map.put(key, new BPSoftReference(key, value, refQ));
-            return prev == null ? null : prev.get();
-        }
-
-        @Override
-        public BeanProperties putIfAbsent(Class<?> key, BeanProperties value) {
-            cleanup();
-            BPSoftReference prev = map.putIfAbsent(key, new BPSoftReference(key, value, refQ));
-            return prev == null ? null : prev.get();
-        }
-
-        @Override
-        public BeanProperties get(Object key) {
-            cleanup();
-            BPSoftReference BPRef = map.get(key);
-            if (BPRef == null) {
-                return null;
-            }
-            if (BPRef.get() == null) {
-                // value has been garbage collected, remove entry in map
-                map.remove(key);
-                return null;
-            }
-            return BPRef.get();
-        }
-    }
-
-    private boolean isReadOnly;
-
-    private static final SoftConcurrentHashMap properties = new SoftConcurrentHashMap();
-
-    /*
-     * Defines a property for a bean.
-     */
-    final static class BeanProperty {
-
-        private Method readMethod;
-        private Method writeMethod;
-        private PropertyDescriptor descriptor;
-
-        public BeanProperty(Class<?> baseClass, PropertyDescriptor descriptor) {
-            this.descriptor = descriptor;
-            readMethod = ELUtil.getMethod(baseClass, descriptor.getReadMethod());
-            writeMethod = ELUtil.getMethod(baseClass, descriptor.getWriteMethod());
-        }
-
-        public Class<?> getPropertyType() {
-            return descriptor.getPropertyType();
-        }
-
-        public boolean isReadOnly() {
-            return getWriteMethod() == null;
-        }
-
-        public Method getReadMethod() {
-            return readMethod;
-        }
-
-        public Method getWriteMethod() {
-            return writeMethod;
-        }
-    }
-
-    /*
-     * Defines the properties for a bean.
-     */
-    final static class BeanProperties {
-
-        private final Map<String, BeanProperty> propertyMap = new HashMap<>();
-
-        public BeanProperties(Class<?> baseClass) {
-            PropertyDescriptor[] descriptors;
-            try {
-                BeanInfo info = Introspector.getBeanInfo(baseClass);
-                descriptors = info.getPropertyDescriptors();
-            } catch (IntrospectionException ie) {
-                throw new ELException(ie);
-            }
-
-            for (PropertyDescriptor descriptor : descriptors) {
-                propertyMap.put(descriptor.getName(), new BeanProperty(baseClass, descriptor));
-            }
-        }
-
-        public BeanProperty getBeanProperty(String property) {
-            return propertyMap.get(property);
-        }
-    }
-
-    /**
-     * Creates a new read/write <code>BeanELResolver</code>.
-     */
-    public BeanELResolver() {
-        this.isReadOnly = false;
-    }
-
-    /**
-     * Creates a new <code>BeanELResolver</code> whose read-only status is determined by the given parameter.
-     *
-     * @param isReadOnly <code>true</code> if this resolver cannot modify beans; <code>false</code> otherwise.
-     */
-    public BeanELResolver(boolean isReadOnly) {
-        this.isReadOnly = isReadOnly;
-    }
-
-    /**
-     * If the base object is not <code>null</code>, returns the most general acceptable type that can be set on this bean
-     * property.
-     *
-     * <p>
-     * If the base is not <code>null</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * The provided property will first be coerced to a <code>String</code>. If there is a <code>BeanInfoProperty</code> for
-     * this property and there were no errors retrieving it, the <code>propertyType</code> of the
-     * <code>propertyDescriptor</code> is returned. Otherwise, a <code>PropertyNotFoundException</code> is thrown.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean to analyze.
-     * @param property The name of the property to analyze. Will be coerced to a <code>String</code>.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the most general acceptable type; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if <code>base</code> is not <code>null</code> and the specified property does not
-     * exist or is not readable.
-     * @throws ELException 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.
-     */
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base == null || property == null) {
-            return null;
-        }
-
-        BeanProperty beanProperty = getBeanProperty(context, base, property);
-        context.setPropertyResolved(true);
-        return beanProperty.getPropertyType();
-    }
-
-    /**
-     * If the base object is not <code>null</code>, returns the current value of the given property on this bean.
-     *
-     * <p>
-     * If the base is not <code>null</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * The provided property name will first be coerced to a <code>String</code>. 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
-     * <code>PropertyNotFoundException</code> is thrown.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean on which to get the property.
-     * @param property The name of the property to get. Will be coerced to a <code>String</code>.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the value of the given property. Otherwise, undefined.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotFoundException if <code>base</code> is not <code>null</code> and the specified property does not
-     * exist or is not readable.
-     * @throws ELException 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.
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base == null || property == null) {
-            return null;
-        }
-
-        Method method = getBeanProperty(context, base, property).getReadMethod();
-        if (method == null) {
-            throw new PropertyNotFoundException(
-                    getExceptionMessageString(context, "propertyNotReadable", new Object[] { base.getClass().getName(), property.toString() }));
-        }
-
-        Object value;
-        try {
-            value = method.invoke(base, new Object[0]);
-            context.setPropertyResolved(base, property);
-        } catch (ELException ex) {
-            throw ex;
-        } catch (InvocationTargetException ite) {
-            throw new ELException(ite.getCause());
-        } catch (Exception ex) {
-            throw new ELException(ex);
-        }
-
-        return value;
-    }
-
-    /**
-     * If the base object is not <code>null</code>, attempts to set the value of the given property on this bean.
-     *
-     * <p>
-     * If the base is not <code>null</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller can safely assume no value was set.
-     * </p>
-     *
-     * <p>
-     * If this resolver was constructed in read-only mode, this method will always throw
-     * <code>PropertyNotWritableException</code>.
-     * </p>
-     *
-     * <p>
-     * The provided property name will first be coerced to a <code>String</code>. If property is a writable property of
-     * <code>base</code> (as per the JavaBeans Specification), the setter method is called (passing <code>value</code>). If
-     * the property exists but does not have a setter, then a <code>PropertyNotFoundException</code> is thrown. If the
-     * property does not exist, a <code>PropertyNotFoundException</code> is thrown.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean on which to set the property.
-     * @param property The name of the property to set. Will be coerced to a <code>String</code>.
-     * @param val The value to be associated with the specified key.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotFoundException if <code>base</code> is not <code>null</code> and the specified property does not
-     * exist.
-     * @throws PropertyNotWritableException if this resolver was constructed in read-only mode, or if there is no setter for
-     * the property.
-     * @throws ELException 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.
-     */
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object val) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base == null || property == null) {
-            return;
-        }
-
-        if (isReadOnly) {
-            throw new PropertyNotWritableException(getExceptionMessageString(context, "resolverNotwritable", new Object[] { base.getClass().getName() }));
-        }
-
-        Method method = getBeanProperty(context, base, property).getWriteMethod();
-        if (method == null) {
-            throw new PropertyNotWritableException(
-                    getExceptionMessageString(context, "propertyNotWritable", new Object[] { base.getClass().getName(), property.toString() }));
-        }
-
-        try {
-            method.invoke(base, new Object[] { val });
-            context.setPropertyResolved(base, property);
-        } catch (ELException ex) {
-            throw ex;
-        } catch (InvocationTargetException ite) {
-            throw new ELException(ite.getCause());
-        } catch (Exception ex) {
-            if (null == val) {
-                val = "null";
-            }
-            String message = getExceptionMessageString(context, "setPropertyFailed", new Object[] { property.toString(), base.getClass().getName(), val });
-            throw new ELException(message, ex);
-        }
-    }
-
-    /**
-     * If the base object is not <code>null</code>, invoke the method, with the given parameters on this bean. The return
-     * value from the method is returned.
-     *
-     * <p>
-     * If the base is not <code>null</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * The provided method object will first be coerced to a <code>String</code>. 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
-     * <code>MethodNotFoundException</code> is thrown.
-     *
-     * If the given paramTypes is not <code>null</code>, 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 corresponding parameter types of the method, and the method is then
-     * invoked.
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean on which to invoke the method
-     * @param methodName The simple name of the method to invoke. Will be coerced to a <code>String</code>. If method is
-     * "&lt;init&gt;"or "&lt;clinit&gt;" a MethodNotFoundException is thrown.
-     * @param paramTypes An array of Class objects identifying the method's formal parameter types, in declared order. Use
-     * an empty array if the method has no parameters. Can be <code>null</code>, in which case the method's formal parameter
-     * types are assumed to be unknown.
-     * @param params The parameters to pass to the method, or <code>null</code> if no parameters.
-     * @return The result of the method invocation (<code>null</code> if the method has a <code>void</code> return type).
-     * @throws MethodNotFoundException if no suitable method can be found.
-     * @throws ELException 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
-     * <code>InvocationTargetException</code>, extract its <code>cause</code> and pass it to the <code>ELException</code>
-     * constructor.
-     * @since Jakarta Expression Language 2.2
-     */
-    @Override
-    public Object invoke(ELContext context, Object base, Object methodName, Class<?>[] paramTypes, Object[] params) {
-        if (base == null || methodName == null) {
-            return null;
-        }
-
-        Method method = ELUtil.findMethod(base.getClass(), methodName.toString(), paramTypes, params, false);
-
-        for (Object param : params) {
-            // If the parameters is a LambdaExpression, set the ELContext
-            // for its evaluation
-            if (param instanceof LambdaExpression) {
-                ((LambdaExpression) param).setELContext(context);
-            }
-        }
-
-        Object ret = ELUtil.invokeMethod(context, method, base, params);
-        context.setPropertyResolved(base, methodName);
-        return ret;
-    }
-
-    /**
-     * If the base object is not <code>null</code>, returns whether a call to {@link #setValue} will always fail.
-     *
-     * <p>
-     * If the base is not <code>null</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller can safely assume no value was set.
-     * </p>
-     *
-     * <p>
-     * If this resolver was constructed in read-only mode, this method will always return <code>true</code>.
-     * </p>
-     *
-     * <p>
-     * The provided property name will first be coerced to a <code>String</code>. If property is a writable property of
-     * <code>base</code>, <code>false</code> is returned. If the property is found but is not writable, <code>true</code> is
-     * returned. If the property is not found, a <code>PropertyNotFoundException</code> is thrown.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean to analyze.
-     * @param property The name of the property to analyzed. Will be coerced to a <code>String</code>.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>true</code> if calling the <code>setValue</code> method will always fail or <code>false</code> if it is
-     * possible that such a call may succeed; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if <code>base</code> is not <code>null</code> and the specified property does not
-     * exist.
-     * @throws ELException 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.
-     */
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base == null || property == null) {
-            return false;
-        }
-
-        context.setPropertyResolved(true);
-        if (isReadOnly) {
-            return true;
-        }
-
-        return getBeanProperty(context, base, property).isReadOnly();
-    }
-
-    /**
-     * If the base object is not <code>null</code>, returns an <code>Iterator</code> containing the set of JavaBeans
-     * properties available on the given object. Otherwise, returns <code>null</code>.
-     *
-     * <p>
-     * The <code>Iterator</code> returned must contain zero or more instances of {@link java.beans.FeatureDescriptor}. Each
-     * info object contains information about a property in the bean, as obtained by calling the
-     * <code>BeanInfo.getPropertyDescriptors</code> method. The <code>FeatureDescriptor</code> is initialized using the same
-     * fields as are present in the <code>PropertyDescriptor</code>, with the additional required named attributes
-     * "<code>type</code>" and "<code>resolvableAtDesignTime</code>" set as follows:
-     * <ul>
-     * <li>{@link ELResolver#TYPE} - The runtime type of the property, from
-     * <code>PropertyDescriptor.getPropertyType()</code>.</li>
-     * <li>{@link ELResolver#RESOLVABLE_AT_DESIGN_TIME} - <code>true</code>.</li>
-     * </ul>
-     *
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean to analyze.
-     * @return An <code>Iterator</code> containing zero or more <code>FeatureDescriptor</code> objects, each representing a
-     * property on this bean, or <code>null</code> if the <code>base</code> object is <code>null</code>.
-     */
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        if (base == null) {
-            return null;
-        }
-
-        BeanInfo info = null;
-        try {
-            info = Introspector.getBeanInfo(base.getClass());
-        } catch (Exception ex) {
-        }
-
-        if (info == null) {
-            return null;
-        }
-
-        ArrayList<FeatureDescriptor> featureDescriptors = new ArrayList<>(info.getPropertyDescriptors().length);
-        for (PropertyDescriptor propertyDescriptor : info.getPropertyDescriptors()) {
-            propertyDescriptor.setValue("type", propertyDescriptor.getPropertyType());
-            propertyDescriptor.setValue("resolvableAtDesignTime", TRUE);
-            featureDescriptors.add(propertyDescriptor);
-        }
-
-        return featureDescriptors.iterator();
-    }
-
-    /**
-     * If the base object is not <code>null</code>, returns the most general type that this resolver accepts for the
-     * <code>property</code> argument. Otherwise, returns <code>null</code>.
-     *
-     * <p>
-     * Assuming the base is not <code>null</code>, this method will always return <code>Object.class</code>. This is because
-     * any object is accepted as a key and is coerced into a string.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean to analyze.
-     * @return <code>null</code> if base is <code>null</code>; otherwise <code>Object.class</code>.
-     */
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        if (base == null) {
-            return null;
-        }
-
-        return Object.class;
-    }
-
-    private BeanProperty getBeanProperty(ELContext context, Object base, Object prop) {
-        String property = prop.toString();
-        Class<?> baseClass = base.getClass();
-
-        BeanProperties beanProperties = properties.get(baseClass);
-        if (beanProperties == null) {
-            beanProperties = new BeanProperties(baseClass);
-            properties.put(baseClass, beanProperties);
-        }
-
-        BeanProperty beanProperty = beanProperties.getBeanProperty(property);
-        if (beanProperty == null) {
-            throw new PropertyNotFoundException(getExceptionMessageString(context, "propertyNotFound", new Object[] { baseClass.getName(), property }));
-        }
-
-        return beanProperty;
-    }
-}
diff --git a/api/src/main/java/javax/el/BeanNameELResolver.java b/api/src/main/java/javax/el/BeanNameELResolver.java
deleted file mode 100644
index 9c147f1..0000000
--- a/api/src/main/java/javax/el/BeanNameELResolver.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-import java.beans.FeatureDescriptor;
-import java.util.Iterator;
-
-/**
- * <p>
- * An <code>ELResolver</code> for resolving user or container managed beans.
- * </p>
- * <p>
- * A {@link BeanNameResolver} is required for its proper operation. The following example creates an
- * <code>ELResolver</code> that resolves the name "bean" to an instance of MyBean.
- *
- * <pre>
- * <code>
- * ELResovler elr = new BeanNameELResolver(new BeanNameResolver {
- *    public boolean isNameResolved(String beanName) {
- *       return "bean".equals(beanName);
- *    }
- *    public Object getBean(String beanName) {
- *       return "bean".equals(beanName)? new MyBean(): null;
- *    }
- * });
- * </code>
- * </pre>
- *
- * @since Jakarta Expression Language 3.0
- */
-public class BeanNameELResolver extends ELResolver {
-
-    private BeanNameResolver beanNameResolver;
-
-    /**
-     * Constructor
-     *
-     * @param beanNameResolver The {@link BeanNameResolver} that resolves a bean name.
-     */
-    public BeanNameELResolver(BeanNameResolver beanNameResolver) {
-        this.beanNameResolver = beanNameResolver;
-    }
-
-    /**
-     * If the base object is <code>null</code> and the property is a name that is resolvable by the BeanNameResolver,
-     * returns the value resolved by the BeanNameResolver.
-     *
-     * <p>
-     * If name is resolved by the BeanNameResolver, the <code>propertyResolved</code> property of the <code>ELContext</code>
-     * object must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code>
-     * after this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base <code>null</code>
-     * @param property The name of the bean.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the value of the bean with the given name. Otherwise, undefined.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws ELException 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.
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base == null && property instanceof String) {
-            if (beanNameResolver.isNameResolved((String) property)) {
-                context.setPropertyResolved(base, property);
-                return beanNameResolver.getBean((String) property);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * 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.
-     *
-     * <p>
-     * If the name is resolvable by the BeanNameResolver, or if the BeanNameResolver allows creating a new bean, the
-     * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by the
-     * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller can
-     * safely assume no value has been set.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base <code>null</code>
-     * @param property The name of the bean
-     * @param value The value to set the bean with the given name to.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotWritableException if the BeanNameResolver does not allow the bean to be modified.
-     * @throws ELException 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.
-     */
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object value) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base == null && property instanceof String) {
-            String beanName = (String) property;
-            if (beanNameResolver.isNameResolved(beanName) || beanNameResolver.canCreateBean(beanName)) {
-                beanNameResolver.setBeanValue(beanName, value);
-                context.setPropertyResolved(base, property);
-            }
-        }
-    }
-
-    /**
-     * If the base is null and the property is a name resolvable by the BeanNameResolver, return the type of the bean.
-     *
-     * <p>
-     * If the name is resolvable by the BeanNameResolver, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller can safely assume no value has been set.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base <code>null</code>
-     * @param property The name of the bean.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the type of the bean with the given name. Otherwise, undefined.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws ELException 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.
-     */
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base == null && property instanceof String) {
-            if (beanNameResolver.isNameResolved((String) property)) {
-                context.setPropertyResolved(true);
-                return beanNameResolver.getBean((String) property).getClass();
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * If the base is null and the property is a name resolvable by the BeanNameResolver, attempts to determine if the bean
-     * is writable.
-     *
-     * <p>
-     * If the name is resolvable by the BeanNameResolver, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller can safely assume no value has been set.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base <code>null</code>
-     * @param property The name of the bean.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>true</code> if the property is read-only or <code>false</code> if not; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws ELException 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.
-     */
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base == null && property instanceof String) {
-            if (beanNameResolver.isNameResolved((String) property)) {
-                context.setPropertyResolved(true);
-                return beanNameResolver.isReadOnly((String) property);
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Always returns <code>null</code>, since there is no reason to iterate through a list of one element: bean name.
-     *
-     * @param context The context of this evaluation.
-     * @param base <code>null</code>.
-     * @return <code>null</code>.
-     */
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        return null;
-    }
-
-    /**
-     * Always returns <code>String.class</code>, since a bean name is a String.
-     *
-     * @param context The context of this evaluation.
-     * @param base <code>null</code>.
-     * @return <code>String.class</code>.
-     */
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        return String.class;
-    }
-}
diff --git a/api/src/main/java/javax/el/BeanNameResolver.java b/api/src/main/java/javax/el/BeanNameResolver.java
deleted file mode 100644
index d173174..0000000
--- a/api/src/main/java/javax/el/BeanNameResolver.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-/**
- * Resolves a bean by its known name. This class can be extended to return a bean object given its name, to set a value
- * to an existing bean, or to create a bean with the value.
- *
- * @see BeanNameELResolver
- *
- * @since Jakarta Expression Language 3.0
- */
-public abstract class BeanNameResolver {
-
-    /**
-     * Returns whether the given name is resolved by the BeanNameResolver
-     *
-     * @param beanName The name of the bean.
-     * @return true if the name is resolved by this BeanNameResolver; false otherwise.
-     */
-    public boolean isNameResolved(String beanName) {
-        return false;
-    }
-
-    /**
-     * Returns the bean known by its name.
-     *
-     * @param beanName The name of the bean.
-     * @return The bean with the given name. Can be <code>null</code>.
-     *
-     */
-    public Object getBean(String beanName) {
-        return null;
-    }
-
-    /**
-     * Sets a value to a bean of the given name. If the bean of the given name does not exist and if {@link #canCreateBean}
-     * is <code>true</code>, one is created with the given value.
-     *
-     * @param beanName The name of the bean
-     * @param value The value to set the bean to. Can be <code>null</code>.
-     * @throws PropertyNotWritableException if the bean cannot be modified or created.
-     */
-    public void setBeanValue(String beanName, Object value) throws PropertyNotWritableException {
-        throw new PropertyNotWritableException();
-    }
-
-    /**
-     * Indicates if the bean of the given name is read-only or writable
-     *
-     * @param beanName The name of the bean
-     * @return <code>true</code> if the bean can be set to a new value. <code>false</code> otherwise.
-     */
-    public boolean isReadOnly(String beanName) {
-        return true;
-    }
-
-    /**
-     * Allow creating a bean of the given name if it does not exist.
-     *
-     * @param beanName The name of the bean
-     * @return <code>true</code> if bean creation is supported <code>false</code> otherwise.
-     */
-    public boolean canCreateBean(String beanName) {
-        return false;
-    }
-}
diff --git a/api/src/main/java/javax/el/CompositeELResolver.java b/api/src/main/java/javax/el/CompositeELResolver.java
deleted file mode 100644
index 1e0e9e1..0000000
--- a/api/src/main/java/javax/el/CompositeELResolver.java
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.beans.FeatureDescriptor;
-import java.util.Iterator;
-
-/**
- * Maintains an ordered composite list of child <code>ELResolver</code>s.
- *
- * <p>
- * Though only a single <code>ELResolver</code> is associated with an <code>ELContext</code>, there are usually multiple
- * resolvers considered for any given variable or property resolution. <code>ELResolver</code>s are combined together
- * using a <code>CompositeELResolver</code>, to define rich semantics for evaluating an expression.
- * </p>
- *
- * <p>
- * For the {@link #getValue}, {@link #getType}, {@link #setValue} and {@link #isReadOnly} methods, an
- * <code>ELResolver</code> is not responsible for resolving all possible (base, property) pairs. In fact, most resolvers
- * will only handle a <code>base</code> of a single type. To indicate that a resolver has successfully resolved a
- * particular (base, property) pair, it must set the <code>propertyResolved</code> property of the
- * <code>ELContext</code> to <code>true</code>. If it could not handle the given pair, it must leave this property
- * alone. The caller must ignore the return value of the method if <code>propertyResolved</code> is <code>false</code>.
- * </p>
- *
- * <p>
- * The <code>CompositeELResolver</code> initializes the <code>ELContext.propertyResolved</code> flag to
- * <code>false</code>, and uses it as a stop condition for iterating through its component resolvers.
- * </p>
- *
- * <p>
- * The <code>ELContext.propertyResolved</code> flag is not used for the design-time methods
- * {@link #getFeatureDescriptors} and {@link #getCommonPropertyType}. Instead, results are collected and combined from
- * all child <code>ELResolver</code>s for these methods.
- * </p>
- *
- * @see ELContext
- * @see ELResolver
- * @since Jakarta Server Pages 2.1
- */
-public class CompositeELResolver extends ELResolver {
-
-    public CompositeELResolver() {
-        this.size = 0;
-        this.elResolvers = new ELResolver[16];
-    }
-
-    /**
-     * Adds the given resolver to the list of component resolvers.
-     *
-     * <p>
-     * Resolvers are consulted in the order in which they are added.
-     * </p>
-     *
-     * @param elResolver The component resolver to add.
-     * @throws NullPointerException If the provided resolver is <code>null</code>.
-     */
-    public void add(ELResolver elResolver) {
-        if (elResolver == null) {
-            throw new NullPointerException();
-        }
-
-        if (size >= elResolvers.length) {
-            ELResolver[] newResolvers = new ELResolver[size * 2];
-            System.arraycopy(elResolvers, 0, newResolvers, 0, size);
-            elResolvers = newResolvers;
-        }
-
-        elResolvers[size++] = elResolver;
-    }
-
-    /**
-     * Attempts to resolve the given <code>property</code> object on the given <code>base</code> object by querying all
-     * component resolvers.
-     *
-     * <p>
-     * If this resolver handles the given (base, property) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller should ignore the return value.
-     *
-     * <p>
-     * First, <code>propertyResolved</code> is set to <code>false</code> on the provided <code>ELContext</code>.
-     *
-     * <p>
-     * Next, for each component resolver in this composite:
-     * <ol>
-     * <li>The <code>getValue()</code> method is called, passing in the provided <code>context</code>, <code>base</code> and
-     * <code>property</code>.</li>
-     * <li>If the <code>ELContext</code>'s <code>propertyResolved</code> flag is <code>false</code> then iteration
-     * continues.</li>
-     * <li>Otherwise, iteration stops and no more component resolvers are considered. The value returned by
-     * <code>getValue()</code> is returned by this method.</li>
-     * </ol>
-     *
-     * <p>
-     * If none of the component resolvers were able to perform this operation, the value <code>null</code> is returned and
-     * the <code>propertyResolved</code> flag remains set to <code>false</code>.
-     *
-     * <p>
-     * Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose property value is to be returned, or <code>null</code> to resolve a top-level
-     * variable.
-     * @param property The property or variable to be resolved.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the result of the variable or property resolution; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if the given (base, property) pair is handled by this <code>ELResolver</code> but
-     * the specified variable or property does not exist or is not readable.
-     * @throws ELException 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.
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        context.setPropertyResolved(false);
-
-        Object value = null;
-        for (int i = 0; i < size; i++) {
-            value = elResolvers[i].getValue(context, base, property);
-            if (context.isPropertyResolved()) {
-                return value;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Attempts to resolve and invoke the given <code>method</code> on the given <code>base</code> object by querying all
-     * component resolvers.
-     *
-     * <p>
-     * If this resolver handles the given (base, method) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * First, <code>propertyResolved</code> is set to <code>false</code> on the provided <code>ELContext</code>.
-     * </p>
-     *
-     * <p>
-     * Next, for each component resolver in this composite:
-     * <ol>
-     * <li>The <code>invoke()</code> method is called, passing in the provided <code>context</code>, <code>base</code>,
-     * <code>method</code>, <code>paramTypes</code>, and <code>params</code>.</li>
-     * <li>If the <code>ELContext</code>'s <code>propertyResolved</code> flag is <code>false</code> then iteration
-     * continues.</li>
-     * <li>Otherwise, iteration stops and no more component resolvers are considered. The value returned by
-     * <code>getValue()</code> is returned by this method.</li>
-     * </ol>
-     *
-     * <p>
-     * If none of the component resolvers were able to perform this operation, the value <code>null</code> is returned and
-     * the <code>propertyResolved</code> flag remains set to <code>false</code>
-     * </p>
-     * .
-     *
-     * <p>
-     * Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean on which to invoke the method
-     * @param method The simple name of the method to invoke. Will be coerced to a <code>String</code>.
-     * @param paramTypes An array of Class objects identifying the method's formal parameter types, in declared order. Use
-     * an empty array if the method has no parameters. Can be <code>null</code>, in which case the method's formal parameter
-     * types are assumed to be unknown.
-     * @param params The parameters to pass to the method, or <code>null</code> if no parameters.
-     * 
-     * @return The result of the method invocation (<code>null</code> if the method has a <code>void</code> return type).
-     * 
-     * @since Jakarta Expression Language 2.2
-     */
-    @Override
-    public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {
-        context.setPropertyResolved(false);
-
-        Object value;
-        for (int i = 0; i < size; i++) {
-            value = elResolvers[i].invoke(context, base, method, paramTypes, params);
-            if (context.isPropertyResolved()) {
-                return value;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * For a given <code>base</code> and <code>property</code>, attempts to identify the most general type that is
-     * acceptable for an object to be passed as the <code>value</code> parameter in a future call to the {@link #setValue}
-     * method. The result is obtained by querying all component resolvers.
-     *
-     * <p>
-     * If this resolver handles the given (base, property) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * First, <code>propertyResolved</code> is set to <code>false</code> on the provided <code>ELContext</code>.
-     * </p>
-     *
-     * <p>
-     * Next, for each component resolver in this composite:
-     * <ol>
-     * <li>The <code>getType()</code> method is called, passing in the provided <code>context</code>, <code>base</code> and
-     * <code>property</code>.</li>
-     * <li>If the <code>ELContext</code>'s <code>propertyResolved</code> flag is <code>false</code> then iteration
-     * continues.</li>
-     * <li>Otherwise, iteration stops and no more component resolvers are considered. The value returned by
-     * <code>getType()</code> is returned by this method.</li>
-     * </ol>
-     *
-     * <p>
-     * If none of the component resolvers were able to perform this operation, the value <code>null</code> is returned and
-     * the <code>propertyResolved</code> flag remains set to <code>false</code>.
-     * </p>
-     *
-     *
-     * <p>
-     * Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose property value is to be analyzed, or <code>null</code> to analyze a top-level
-     * variable.
-     * @param property The property or variable to return the acceptable type for.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the most general acceptable type; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if the given (base, property) pair is handled by this <code>ELResolver</code> but
-     * the specified variable or property does not exist or is not readable.
-     * @throws ELException 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.
-     */
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        context.setPropertyResolved(false);
-
-        Class<?> type;
-        for (int i = 0; i < size; i++) {
-            type = elResolvers[i].getType(context, base, property);
-            if (context.isPropertyResolved()) {
-                return type;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Attempts to set the value of the given <code>property</code> object on the given <code>base</code> object. All
-     * component resolvers are asked to attempt to set the value.
-     *
-     * <p>
-     * If this resolver handles the given (base, property) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller can safely assume no value has been set.
-     *
-     * <p>
-     * First, <code>propertyResolved</code> is set to <code>false</code> on the provided <code>ELContext</code>.
-     *
-     * <p>
-     * Next, for each component resolver in this composite:
-     * <ol>
-     * <li>The <code>setValue()</code> method is called, passing in the provided <code>context</code>, <code>base</code>,
-     * <code>property</code> and <code>value</code>.</li>
-     * <li>If the <code>ELContext</code>'s <code>propertyResolved</code> flag is <code>false</code> then iteration
-     * continues.</li>
-     * <li>Otherwise, iteration stops and no more component resolvers are considered.</li>
-     * </ol>
-     *
-     * <p>
-     * If none of the component resolvers were able to perform this operation, the <code>propertyResolved</code> flag
-     * remains set to <code>false</code>.
-     *
-     * <p>
-     * Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose property value is to be set, or <code>null</code> to set a top-level variable.
-     * @param property The property or variable to be set.
-     * @param val The value to set the property or variable to.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if the given (base, property) pair is handled by this <code>ELResolver</code> but
-     * the specified variable or property does not exist.
-     * @throws PropertyNotWritableException if the given (base, property) pair is handled by this <code>ELResolver</code>
-     * but the specified variable or property is not writable.
-     * @throws ELException 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.
-     */
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object val) {
-        context.setPropertyResolved(false);
-
-        for (int i = 0; i < size; i++) {
-            elResolvers[i].setValue(context, base, property, val);
-            if (context.isPropertyResolved()) {
-                return;
-            }
-        }
-    }
-
-    /**
-     * For a given <code>base</code> and <code>property</code>, attempts to determine whether a call to {@link #setValue}
-     * will always fail. The result is obtained by querying all component resolvers.
-     *
-     * <p>
-     * If this resolver handles the given (base, property) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * First, <code>propertyResolved</code> is set to <code>false</code> on the provided <code>ELContext</code>.
-     * </p>
-     *
-     * <p>
-     * Next, for each component resolver in this composite:
-     * <ol>
-     * <li>The <code>isReadOnly()</code> method is called, passing in the provided <code>context</code>, <code>base</code>
-     * and <code>property</code>.</li>
-     * <li>If the <code>ELContext</code>'s <code>propertyResolved</code> flag is <code>false</code> then iteration
-     * continues.</li>
-     * <li>Otherwise, iteration stops and no more component resolvers are considered. The value returned by
-     * <code>isReadOnly()</code> is returned by this method.</li>
-     * </ol>
-     *
-     * <p>
-     * If none of the component resolvers were able to perform this operation, the value <code>false</code> is returned and
-     * the <code>propertyResolved</code> flag remains set to <code>false</code>
-     * </p>
-     * .
-     *
-     * <p>
-     * Any exception thrown by component resolvers during the iteration is propagated to the caller of this method.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose property value is to be analyzed, or <code>null</code> to analyze a top-level
-     * variable.
-     * @param property The property or variable to return the read-only status for.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>true</code> if the property is read-only or <code>false</code> if not; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if the given (base, property) pair is handled by this <code>ELResolver</code> but
-     * the specified variable or property does not exist.
-     * @throws ELException 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.
-     */
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        context.setPropertyResolved(false);
-
-        boolean readOnly;
-        for (int i = 0; i < size; i++) {
-            readOnly = elResolvers[i].isReadOnly(context, base, property);
-            if (context.isPropertyResolved()) {
-                return readOnly;
-            }
-        }
-
-        return false; // Does not matter
-    }
-
-    /**
-     * Returns information about the set of variables or properties that can be resolved for the given <code>base</code>
-     * object. One use for this method is to assist tools in auto-completion. The results are collected from all component
-     * resolvers.
-     *
-     * <p>
-     * The <code>propertyResolved</code> property of the <code>ELContext</code> is not relevant to this method. The results
-     * of all <code>ELResolver</code>s are concatenated.
-     * </p>
-     *
-     * <p>
-     * The <code>Iterator</code> returned is an iterator over the collection of <code>FeatureDescriptor</code> objects
-     * returned by the iterators returned by each component resolver's <code>getFeatureDescriptors</code> method. If
-     * <code>null</code> is returned by a resolver, it is skipped.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose set of valid properties is to be enumerated, or <code>null</code> to enumerate the
-     * set of top-level variables that this resolver can evaluate.
-     * @return An <code>Iterator</code> containing zero or more (possibly infinitely more) <code>FeatureDescriptor</code>
-     * objects, or <code>null</code> if this resolver does not handle the given <code>base</code> object or that the results
-     * are too complex to represent with this method
-     */
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        return new CompositeIterator(elResolvers, size, context, base);
-    }
-
-    /**
-     * Returns the most general type that this resolver accepts for the <code>property</code> argument, given a
-     * <code>base</code> object. One use for this method is to assist tools in auto-completion. The result is obtained by
-     * querying all component resolvers.
-     *
-     * <p>
-     * The <code>Class</code> returned is the most specific class that is a common superclass of all the classes returned by
-     * each component resolver's <code>getCommonPropertyType</code> method. If <code>null</code> is returned by a resolver,
-     * it is skipped.
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object to return the most general property type for, or <code>null</code> to enumerate the set
-     * of top-level variables that this resolver can evaluate.
-     * 
-     * @return <code>null</code> if this <code>ELResolver</code> does not know how to handle the given <code>base</code>
-     * object; otherwise <code>Object.class</code> if any type of <code>property</code> is accepted; otherwise the most
-     * general <code>property</code> type accepted for the given <code>base</code>.
-     */
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        Class<?> commonPropertyType = null;
-        for (int i = 0; i < size; i++) {
-
-            Class<?> type = elResolvers[i].getCommonPropertyType(context, base);
-            if (type == null) {
-                // skip this Jakarta Expression Language Resolver
-                continue;
-            } else if (commonPropertyType == null) {
-                commonPropertyType = type;
-            } else if (commonPropertyType.isAssignableFrom(type)) {
-                continue;
-            } else if (type.isAssignableFrom(commonPropertyType)) {
-                commonPropertyType = type;
-            } else {
-                // Don't have a commonPropertyType
-                return null;
-            }
-        }
-
-        return commonPropertyType;
-    }
-
-    /**
-     * Converts an object to a specific type.
-     *
-     * <p>
-     * An <code>ELException</code> is thrown if an error occurs during the conversion.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param obj The object to convert.
-     * @param targetType The target type for the convertion.
-     * 
-     * @throws ELException thrown if errors occur.
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    @Override
-    public Object convertToType(ELContext context, Object obj, Class<?> targetType) {
-        context.setPropertyResolved(false);
-
-        Object value = null;
-        for (int i = 0; i < size; i++) {
-            value = elResolvers[i].convertToType(context, obj, targetType);
-            if (context.isPropertyResolved()) {
-                return value;
-            }
-        }
-
-        return null;
-    }
-
-    private ELResolver[] elResolvers;
-    private int size;
-
-    private static class CompositeIterator implements Iterator<FeatureDescriptor> {
-
-        ELResolver[] resolvers;
-        int size;
-        int index = 0;
-        Iterator<FeatureDescriptor> propertyIter = null;
-        ELContext context;
-        Object base;
-
-        CompositeIterator(ELResolver[] resolvers, int size, ELContext context, Object base) {
-            this.resolvers = resolvers;
-            this.size = size;
-            this.context = context;
-            this.base = base;
-        }
-
-        @Override
-        public boolean hasNext() {
-            if (propertyIter == null || !propertyIter.hasNext()) {
-                while (index < size) {
-                    ELResolver elResolver = resolvers[index++];
-                    propertyIter = elResolver.getFeatureDescriptors(context, base);
-                    if (propertyIter != null) {
-                        return propertyIter.hasNext();
-                    }
-                }
-                return false;
-            }
-            return propertyIter.hasNext();
-        }
-
-        @Override
-        public FeatureDescriptor next() {
-            if (propertyIter == null || !propertyIter.hasNext()) {
-                while (index < size) {
-                    ELResolver elResolver = resolvers[index++];
-                    propertyIter = elResolver.getFeatureDescriptors(context, base);
-                    if (propertyIter != null) {
-                        return propertyIter.next();
-                    }
-                }
-                return null;
-            }
-            return propertyIter.next();
-        }
-
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-    }
-}
diff --git a/api/src/main/java/javax/el/ELClass.java b/api/src/main/java/javax/el/ELClass.java
deleted file mode 100644
index 86355ed..0000000
--- a/api/src/main/java/javax/el/ELClass.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2013, 2018 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 javax.el;
-
-/**
- * A runtime representation of a Class in the Jakarta Expression Language expressions. It encapsulates the
- * java.lang.Class instance.
- *
- * <p>
- * This class is used only in {@link StaticFieldELResolver} and will probably only be of interest to Jakarta Expression
- * Language implementors, and not Jakarta Expression Language users.
- *
- * @since Jakarta Expression Language 3.0
- */
-public class ELClass {
-
-    private Class<?> klass;
-
-    /**
-     * Constructor
-     *
-     * @param klass The Class instance
-     */
-    public ELClass(Class<?> klass) {
-        this.klass = klass;
-    }
-
-    /**
-     * Returns the Class instance
-     *
-     * @return The Class instance
-     */
-    public Class<?> getKlass() {
-        return this.klass;
-    }
-}
diff --git a/api/src/main/java/javax/el/ELContext.java b/api/src/main/java/javax/el/ELContext.java
deleted file mode 100644
index 0b95e59..0000000
--- a/api/src/main/java/javax/el/ELContext.java
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * Context information for expression parsing and evaluation.
- *
- * <p>
- * To parse or evaluate an {@link Expression}, an <code>ELContext</code> must be provided. The <code>ELContext</code>
- * holds:
- * <ul>
- * <li>a reference to {@link FunctionMapper} that will be used to resolve Jakarta Expression Language Functions. This is
- * used only in parsing.</li>
- * <li>a reference to {@link VariableMapper} that will be used to resolve Jakarta Expression Language Variables. This is
- * used only in parsing.</li>
- * <li>a reference to the base {@link ELResolver} that will be consulted to resolve model objects and their
- * properties</li>
- * <li>a collection of all the relevant context objects for use by <code>ELResolver</code>s</li>
- * <li>state information during the evaluation of an expression, such as whether a property has been resolved yet</li>
- * <li>a reference to {@link ImportHandler} that will be consulted to resolve classes that have been imported</li>
- * <li>a reference to the arguments for the active {@link LambdaExpression}s</li>
- * <li>a reference to the list of registered evaluation listeners</li>
- * </ul>
- *
- * <p>
- * The collection of context objects is necessary because each <code>ELResolver</code> may need access to a different
- * context object. For example, Jakarta Server Pages and Jakarta Faces resolvers need access to a
- * <code>javax.servlet.jsp.JspContext</code> and a <code>javax.faces.context.FacesContext</code>, respectively.
- *
- * <p>
- * When used in a web container, the creation of <code>ELContext</code> objects is controlled through the underlying
- * technology. For example, in Jakarta Server Pages the <code>JspContext.getELContext()</code> factory method is used.
- * Some technologies provide the ability to add an {@link ELContextListener} so that applications and frameworks can
- * ensure their own context objects are attached to any newly created <code>ELContext</code>.
- *
- * <p>
- * When used in a stand-alone environment, {@link StandardELContext} provides a default <code>ELContext</code>, which is
- * managed and modified by {@link ELManager}.
- *
- * <p>
- * Because it stores state during expression evaluation, an <code>ELContext</code> object is not thread-safe. Care
- * should be taken to never share an <code>ELContext</code> instance between two or more threads.
- *
- * @see ELContextListener
- * @see ELContextEvent
- * @see ELResolver
- * @see FunctionMapper
- * @see VariableMapper
- * @see ImportHandler
- * @see LambdaExpression
- * @see StandardELContext
- * 
- * @since Jakarta Expression Language 2.1 and Jakarta Expression Language 3.0
- */
-public abstract class ELContext {
-
-    private boolean resolved;
-    private HashMap<Class<?>, Object> map = new HashMap<>();
-    private transient List<EvaluationListener> listeners;
-    private Stack<Map<String, Object>> lambdaArgs;
-    private ImportHandler importHandler;
-    private Locale locale;
-
-    /**
-     * Called to indicate that a <code>ELResolver</code> has successfully resolved a given (base, property) pair. Use
-     * {@link #setPropertyResolved(Object, Object)} if resolved is true and to notify {@link EvaluationListener}s.
-     *
-     * <p>
-     * The {@link CompositeELResolver} checks this property to determine whether it should consider or skip other component
-     * resolvers.
-     * </p>
-     *
-     * @see CompositeELResolver
-     * @param resolved true if the property has been resolved, or false if not.
-     */
-    public void setPropertyResolved(boolean resolved) {
-        this.resolved = resolved;
-    }
-
-    /**
-     * Called to indicate that a <code>ELResolver</code> has successfully resolved a given (base, property) pair and to
-     * notify the {@link EvaluationListener}s.
-     *
-     * <p>
-     * The {@link CompositeELResolver} checks this property to determine whether it should consider or skip other component
-     * resolvers.
-     *
-     * @see CompositeELResolver
-     * @param base The base object
-     * @param property The property object
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    public void setPropertyResolved(Object base, Object property) {
-        setPropertyResolved(true); // Don't set the variable here, for 2.2 users
-                                   // ELContext may be overridden or delegated.
-        notifyPropertyResolved(base, property);
-    }
-
-    /**
-     * Returns whether an {@link ELResolver} has successfully resolved a given (base, property) pair.
-     *
-     * <p>
-     * The {@link CompositeELResolver} checks this property to determine whether it should consider or skip other component
-     * resolvers.
-     *
-     * @see CompositeELResolver
-     * @return true if the property has been resolved, or false if not.
-     */
-    public boolean isPropertyResolved() {
-        return resolved;
-    }
-
-    /**
-     * Associates a context object with this <code>ELContext</code>.
-     *
-     * <p>
-     * The <code>ELContext</code> maintains a collection of context objects relevant to the evaluation of an expression.
-     * These context objects are used by <code>ELResolver</code>s. This method is used to add a context object to that
-     * collection.
-     * </p>
-     *
-     * <p>
-     * By convention, the <code>contextObject</code> will be of the type specified by the <code>key</code>. However, this is
-     * not required and the key is used strictly as a unique identifier.
-     * </p>
-     *
-     * @param key The key used by an @{link ELResolver} to identify this context object.
-     * @param contextObject The context object to add to the collection.
-     * @throws NullPointerException if key is null or contextObject is null.
-     */
-    public void putContext(Class key, Object contextObject) {
-        if (key == null || contextObject == null) {
-            throw new NullPointerException();
-        }
-
-        map.put(key, contextObject);
-    }
-
-    /**
-     * Returns the context object associated with the given key.
-     *
-     * <p>
-     * The <code>ELContext</code> maintains a collection of context objects relevant to the evaluation of an expression.
-     * These context objects are used by <code>ELResolver</code>s. This method is used to retrieve the context with the
-     * given key from the collection.
-     * </p>
-     *
-     * <p>
-     * By convention, the object returned will be of the type specified by the <code>key</code>. However, this is not
-     * required and the key is used strictly as a unique identifier.
-     * </p>
-     *
-     * @param key The unique identifier that was used to associate the context object with this <code>ELContext</code>.
-     * @return The context object associated with the given key, or null if no such context was found.
-     * @throws NullPointerException if key is null.
-     */
-    public Object getContext(Class key) {
-        if (key == null) {
-            throw new NullPointerException();
-        }
-
-        return map.get(key);
-    }
-
-    /**
-     * Retrieves the <code>ELResolver</code> associated with this context.
-     *
-     * <p>
-     * The <code>ELContext</code> maintains a reference to the <code>ELResolver</code> that will be consulted to resolve
-     * variables and properties during an expression evaluation. This method retrieves the reference to the resolver.
-     * </p>
-     *
-     * <p>
-     * Once an <code>ELContext</code> is constructed, the reference to the <code>ELResolver</code> associated with the
-     * context cannot be changed.
-     * </p>
-     *
-     * @return The resolver to be consulted for variable and property resolution during expression evaluation.
-     */
-    public abstract ELResolver getELResolver();
-
-    /**
-     * Retrieves the <code>ImportHandler</code> associated with this <code>ELContext</code>.
-     *
-     * @return The import handler to manage imports of classes and packages.
-     * 
-     * @since Jakarta Expression Language 3.0
-     */
-    public ImportHandler getImportHandler() {
-        if (importHandler == null) {
-            importHandler = new ImportHandler();
-        }
-
-        return importHandler;
-    }
-
-    /**
-     * Retrieves the <code>FunctionMapper</code> associated with this <code>ELContext</code>.
-     *
-     * @return The function mapper to be consulted for the resolution of Jakarta Expression Language functions.
-     */
-    public abstract FunctionMapper getFunctionMapper();
-
-    /**
-     * Get the <code>Locale</code> stored by a previous invocation to {@link #setLocale}. If this method returns non
-     * <code>null</code>, this <code>Locale</code> must be used for all localization needs in the implementation. The
-     * <code>Locale</code> must not be cached to allow for applications that change <code>Locale</code> dynamically.
-     *
-     * @return The <code>Locale</code> in which this instance is operating. Used primarily for message localization.
-     */
-    public Locale getLocale() {
-        return locale;
-    }
-
-    /**
-     * Sets the <code>Locale</code> for this instance.
-     *
-     * <p>
-     * This method may be called by the party creating the instance, such as Jakarta Faces or Jakarta Server Pages, to
-     * enable the Jakarta Expression Language implementation to provide localized messages to the user. If no
-     * <code>Locale</code> is set, the implementation must use the locale returned by <code>Locale.getDefault( )</code>.
-     *
-     * @param locale the locale for this instance
-     */
-    public void setLocale(Locale locale) {
-        this.locale = locale;
-    }
-
-    /**
-     * Retrieves the <code>VariableMapper</code> associated with this <code>ELContext</code>.
-     *
-     * @return The variable mapper to be consulted for the resolution of Jakarta Expression Language variables.
-     */
-    public abstract VariableMapper getVariableMapper();
-
-    /**
-     * Registers an evaluation listener to the ELContext.
-     *
-     * @param listener The listener to be added.
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    public void addEvaluationListener(EvaluationListener listener) {
-        if (listeners == null) {
-            listeners = new ArrayList<>();
-        }
-
-        listeners.add(listener);
-    }
-
-    /**
-     * Returns the list of registered evaluation listeners.
-     *
-     * @return The list of registered evaluation listeners.
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    public List<EvaluationListener> getEvaluationListeners() {
-        return listeners;
-    }
-
-    /**
-     * Notifies the listeners before an Jakarta Expression Language expression is evaluated
-     *
-     * @param expr The Jakarta Expression Language expression string to be evaluated
-     */
-    public void notifyBeforeEvaluation(String expr) {
-        if (getEvaluationListeners() == null) {
-            return;
-        }
-
-        for (EvaluationListener listener : getEvaluationListeners()) {
-            listener.beforeEvaluation(this, expr);
-        }
-    }
-
-    /**
-     * Notifies the listeners after an Jakarta Expression Language expression is evaluated
-     *
-     * @param expr The Jakarta Expression Language expression string that has been evaluated
-     */
-    public void notifyAfterEvaluation(String expr) {
-        if (getEvaluationListeners() == null) {
-            return;
-        }
-
-        for (EvaluationListener listener : getEvaluationListeners()) {
-            listener.afterEvaluation(this, expr);
-        }
-    }
-
-    /**
-     * Notifies the listeners when the (base, property) pair is resolved
-     *
-     * @param base The base object
-     * @param property The property Object
-     */
-    public void notifyPropertyResolved(Object base, Object property) {
-        if (getEvaluationListeners() == null) {
-            return;
-        }
-
-        for (EvaluationListener listener : getEvaluationListeners()) {
-            listener.propertyResolved(this, base, property);
-        }
-    }
-
-    /**
-     * Inquires if the name is a LambdaArgument
-     *
-     * @param arg A possible Lambda formal parameter name
-     * @return true if arg is a LambdaArgument, false otherwise.
-     */
-    public boolean isLambdaArgument(String arg) {
-        if (lambdaArgs == null) {
-            return false;
-        }
-
-        for (int i = lambdaArgs.size() - 1; i >= 0; i--) {
-            Map<String, Object> lmap = lambdaArgs.elementAt(i);
-            if (lmap.containsKey(arg)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * 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.
-     *
-     * @param arg The formal parameter for the Lambda argument
-     * @return The object associated with formal parameter. Null if no object has been associated with the parameter.
-     * 
-     * @since Jakarta Expression Language 3.0
-     */
-    public Object getLambdaArgument(String arg) {
-        if (lambdaArgs == null) {
-            return null;
-        }
-
-        for (int i = lambdaArgs.size() - 1; i >= 0; i--) {
-            Map<String, Object> lmap = lambdaArgs.elementAt(i);
-            Object v = lmap.get(arg);
-            if (v != null) {
-                return v;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * 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.
-     *
-     * @param args The Lambda arguments map
-     * 
-     * @since Jakarta Expression Language 3.0
-     */
-    public void enterLambdaScope(Map<String, Object> args) {
-        if (lambdaArgs == null) {
-            lambdaArgs = new Stack<>();
-        }
-
-        lambdaArgs.push(args);
-    }
-
-    /**
-     * Exits the Lambda expression evaluation. The Lambda argument map that was previously installed is removed.
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    public void exitLambdaScope() {
-        if (lambdaArgs != null) {
-            lambdaArgs.pop();
-        }
-    }
-
-    /**
-     * Converts an object to a specific type. If a custom converter in the <code>ELResolver</code> handles this conversion,
-     * it is used. Otherwise the standard coercions is applied.
-     *
-     * <p>
-     * An <code>ELException</code> is thrown if an error occurs during the conversion.
-     *
-     * @param obj The object to convert.
-     * @param targetType The target type for the conversion.
-     * 
-     * @return object converted to <code>targetType</code>
-     * @throws ELException thrown if errors occur.
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    public Object convertToType(Object obj, Class<?> targetType) {
-        boolean propertyResolvedSave = isPropertyResolved();
-        try {
-            setPropertyResolved(false);
-            ELResolver elResolver = getELResolver();
-            if (elResolver != null) {
-                Object res = elResolver.convertToType(this, obj, targetType);
-                if (isPropertyResolved()) {
-                    return res;
-                }
-            }
-        } catch (ELException ex) {
-            throw ex;
-        } catch (Exception ex) {
-            throw new ELException(ex);
-        } finally {
-            setPropertyResolved(propertyResolvedSave);
-        }
-
-        ExpressionFactory exprFactory = (ExpressionFactory) getContext(ExpressionFactory.class);
-        if (exprFactory == null) {
-            exprFactory = ELUtil.getExpressionFactory();
-        }
-
-        return exprFactory.coerceToType(obj, targetType);
-    }
-
-}
diff --git a/api/src/main/java/javax/el/ELContextEvent.java b/api/src/main/java/javax/el/ELContextEvent.java
deleted file mode 100644
index e59cc16..0000000
--- a/api/src/main/java/javax/el/ELContextEvent.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.util.EventObject;
-
-/**
- * An event which indicates that an {@link ELContext} has been created. The source object is the ELContext that was
- * created.
- *
- * @see ELContext
- * @see ELContextListener
- * 
- * @since Jakarta Server Pages 2.1
- */
-public class ELContextEvent extends EventObject {
-
-    private static final long serialVersionUID = 1255131906285426769L;
-
-    /**
-     * Constructs an ELContextEvent object to indicate that an <code>ELContext</code> has been created.
-     *
-     * @param source the <code>ELContext</code> that was created.
-     */
-    public ELContextEvent(ELContext source) {
-        super(source);
-    }
-
-    /**
-     * Returns the <code>ELContext</code> that was created. This is a type-safe equivalent of the {@link #getSource} method.
-     *
-     * @return the ELContext that was created.
-     */
-    public ELContext getELContext() {
-        return (ELContext) getSource();
-    }
-}
diff --git a/api/src/main/java/javax/el/ELContextListener.java b/api/src/main/java/javax/el/ELContextListener.java
deleted file mode 100644
index b6c663b..0000000
--- a/api/src/main/java/javax/el/ELContextListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * The listener interface for receiving notification when an {@link ELContext} is created.
- *
- * @see ELContext
- * @see ELContextEvent
- * 
- * @since Jakarta Server Pages 2.1
- */
-public interface ELContextListener extends java.util.EventListener {
-
-    /**
-     * Invoked when a new <code>ELContext</code> has been created.
-     *
-     * @param ece the notification event.
-     */
-    void contextCreated(ELContextEvent ece);
-
-}
diff --git a/api/src/main/java/javax/el/ELException.java b/api/src/main/java/javax/el/ELException.java
deleted file mode 100644
index eb9bcbc..0000000
--- a/api/src/main/java/javax/el/ELException.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * Represents any of the exception conditions that can arise during expression evaluation.
- *
- * @since Jakarta Server Pages 2.1
- */
-public class ELException extends RuntimeException {
-
-    private static final long serialVersionUID = -2161386187282690885L;
-
-    // -------------------------------------
-    /**
-     * Creates an <code>ELException</code> with no detail message.
-     */
-    public ELException() {
-        super();
-    }
-
-    // -------------------------------------
-    /**
-     * Creates an <code>ELException</code> with the provided detail message.
-     *
-     * @param pMessage the detail message
-     */
-    public ELException(String pMessage) {
-        super(pMessage);
-    }
-
-    // -------------------------------------
-    /**
-     * Creates an <code>ELException</code> with the given cause.
-     *
-     * @param pRootCause the originating cause of this exception
-     */
-    public ELException(Throwable pRootCause) {
-        super(pRootCause);
-    }
-
-    // -------------------------------------
-    /**
-     * Creates an ELException with the given detail message and root cause.
-     *
-     * @param pMessage the detail message
-     * @param pRootCause the originating cause of this exception
-     */
-    public ELException(String pMessage, Throwable pRootCause) {
-        super(pMessage, pRootCause);
-    }
-
-}
diff --git a/api/src/main/java/javax/el/ELManager.java b/api/src/main/java/javax/el/ELManager.java
deleted file mode 100644
index 5c56070..0000000
--- a/api/src/main/java/javax/el/ELManager.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2013, 2018 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 javax.el;
-
-import java.lang.reflect.Method;
-
-/**
- * Manages Jakarta Expression Language parsing and evaluation environment. The ELManager maintains an instance of
- * ExpressionFactory and StandardELContext, for parsing and evaluating Jakarta Expression Language expressions.
- *
- * @since Jakarta Expression Language 3.0
- */
-public class ELManager {
-
-    private StandardELContext elContext;
-
-    /**
-     * Return the ExpressionFactory instance used for Jakarta Expression Language evaluations.
-     *
-     * @return The ExpressionFactory
-     */
-    public static ExpressionFactory getExpressionFactory() {
-        return ELUtil.getExpressionFactory();
-    }
-
-    /**
-     * Return the ELContext used for parsing and evaluating Jakarta Expression Language expressions. If there is currently
-     * no ELContext, a default instance of StandardELContext is returned.
-     *
-     * @return The ELContext used for parsing and evaluating Jakarta Expression Language expressions..
-     */
-    public StandardELContext getELContext() {
-        if (elContext == null) {
-            elContext = new StandardELContext(getExpressionFactory());
-        }
-
-        return elContext;
-    }
-
-    /**
-     * Set the ELContext used for parsing and evaluating Jakarta Expression Language expressions. The supplied ELContext
-     * will not be modified, except for the context object map.
-     *
-     * @param context The new ELContext.
-     * @return The previous ELContext, null if none.
-     */
-    public ELContext setELContext(ELContext context) {
-        ELContext prevELContext = elContext;
-        elContext = new StandardELContext(context);
-        return prevELContext;
-    }
-
-    /**
-     * Register a BeanNameResolver. Construct a BeanNameELResolver with the BeanNameResolver and add it to the list of
-     * ELResolvers. Once registered, the BeanNameResolver cannot be removed.
-     *
-     * @param beanNameResolver The BeanNameResolver to be registered.
-     */
-    public void addBeanNameResolver(BeanNameResolver beanNameResolver) {
-        getELContext().addELResolver(new BeanNameELResolver(beanNameResolver));
-    }
-
-    /**
-     * 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.
-     *
-     * @param elResolver The ELResolver to be added to the list of ELResolvers in ELContext.
-     * @see StandardELContext#addELResolver
-     */
-    public void addELResolver(ELResolver elResolver) {
-        getELContext().addELResolver(elResolver);
-    }
-
-    /**
-     * Maps a static method to Jakarta Expression Language function.
-     *
-     * @param prefix The namespace of the functions, can be "".
-     * @param function The name of the function.
-     * @param method The static method to be invoked when the function is used.
-     */
-    public void mapFunction(String prefix, String function, Method method) {
-        getELContext().getFunctionMapper().mapFunction(prefix, function, method);
-    }
-
-    /**
-     * Assign a ValueExpression to a Jakarta Expression Language variable, replacing any previous assignment to the same
-     * variable. The assignment for the variable is removed if the expression is <code>null</code>.
-     *
-     * @param variable The variable name
-     * @param expression The ValueExpression to be assigned to the variable.
-     */
-    public void setVariable(String variable, ValueExpression expression) {
-        getELContext().getVariableMapper().setVariable(variable, expression);
-    }
-
-    /**
-     * Import a static field or method. The class of the static member must be loadable from the classloader, at class
-     * resolution time.
-     *
-     * @param staticMemberName The full class name of the class to be imported
-     * @throws ELException if the name is not a full class name.
-     */
-    public void importStatic(String staticMemberName) throws ELException {
-        getELContext().getImportHandler().importStatic(staticMemberName);
-    }
-
-    /**
-     * Import a class. The imported class must be loadable from the classloader at the expression evaluation time.
-     *
-     * @param className The full class name of the class to be imported
-     * @throws ELException if the name is not a full class name.
-     */
-    public void importClass(String className) throws ELException {
-        getELContext().getImportHandler().importClass(className);
-    }
-
-    /**
-     * Import a package. At the expression evaluation 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.
-     *
-     * @param packageName The package name to be imported
-     */
-    public void importPackage(String packageName) {
-        getELContext().getImportHandler().importPackage(packageName);
-    }
-
-    /**
-     * Define a bean in the local bean repository
-     *
-     * @param name The name of the bean
-     * @param bean The bean instance to be defined. If null, the definition of the bean is removed.
-     * @return the previous bean (if any) mapped to <code>name</code>
-     */
-    public Object defineBean(String name, Object bean) {
-        Object previousBean = getELContext().getBeans().get(name);
-        getELContext().getBeans().put(name, bean);
-        return previousBean;
-    }
-
-    /**
-     * Register an evaluation listener.
-     *
-     * @param listener The evaluation listener to be added.
-     */
-    public void addEvaluationListener(EvaluationListener listener) {
-        getELContext().addEvaluationListener(listener);
-    }
-}
diff --git a/api/src/main/java/javax/el/ELProcessor.java b/api/src/main/java/javax/el/ELProcessor.java
deleted file mode 100644
index 4725d14..0000000
--- a/api/src/main/java/javax/el/ELProcessor.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-/**
- * Provides an API for using Jakarta Expression Language in a stand-alone environment.
- *
- * <p>
- * This class provides a direct and simple interface for
- * <ul>
- * <li>Evaluating Jakarta Expression Language expressions.</li>
- * <li>Assigning values to beans or setting a bean property.</li>
- * <li>Setting a {@link ValueExpression} to a Jakarta Expression Language variable.</li>
- * <li>Defining a static method as Jakarta Expression Language function.</li>
- * <li>Defining an object instance as Jakarta Expression Language name.
- * </ul>
- *
- * <p>
- * This API is not a replacement for the APIs in Jakarta Expression Language 2.2. Containers that maintain Jakarta
- * Expression Language environments can continue to do so, without using this API.
- *
- * <p>
- * For Jakarta Expression Language users who want to manipulate Jakarta Expression Language environments, like adding
- * custom {@link ELResolver}s, {@link ELManager} can be used.
- *
- * <h3>Scope and Life Cycle</h3>
- * <p>
- * Since it maintains the state of the Jakarta Expression Language environments, <code>ELProcessor</code> is not thread
- * safe. In the simplest case, an instance can be created and destroyed before and after evaluating Jakarta Expression
- * Language expressions. A more general usage is to use an instance of <code>ELProcessor</code> for a session, so that
- * the user can configure the Jakarta Expression Language evaluation environment for that session.
- * </p>
- *
- * <h3>Automatic Bracketing of Expressions</h3>
- * <p>
- * A note about the Jakarta Expression Language expressions strings used in the class. The strings allowed in the methods
- * {@link ELProcessor#getValue}, {@link ELProcessor#setValue}, and {@link ELProcessor#setVariable} are limited to
- * non-composite expressions, i.e. expressions of the form ${...} or #{...} only. Also, it is not necessary (in fact not
- * allowed) to bracket the expression strings with ${ or #{ and } in these methods: they will be automatically
- * bracketed. This reduces the visual cluster, without any lost of functionalities (thanks to the addition of the
- * concatenation operator).
- *
- * <h3>Example</h3> The following code snippet illustrates the use of ELProcessor to define a bean and evaluate its
- * property. <blockquote>
- *
- * <pre>
- * ELProcessor elp = new ELProcessor();
- * elp.defineBean("employee", new Employee("Charlie Brown"));
- * String name = elp.eval("employee.name");
- * </pre>
- *
- * </blockquote>
- *
- * @since Jakarta Expression Language 3.0
- */
-public class ELProcessor {
-
-    private ELManager elManager = new ELManager();
-    private ExpressionFactory factory = ELManager.getExpressionFactory();
-
-    /**
-     * Return the ELManager used for Jakarta Expression Language processing.
-     *
-     * @return The ELManager used for Jakarta Expression Language processing.
-     */
-    public ELManager getELManager() {
-        return elManager;
-    }
-
-    /**
-     * Evaluates an Jakarta Expression Language expression.
-     *
-     * @param expression The Jakarta Expression Language expression to be evaluated.
-     * @return The result of the expression evaluation.
-     */
-    public Object eval(String expression) {
-        return getValue(expression, Object.class);
-    }
-
-    /**
-     * Evaluates an Jakarta Expression Language expression, and coerces the result to the specified type.
-     *
-     * @param expression The Jakarta Expression Language expression to be evaluated.
-     * @param expectedType Specifies the type that the resultant evaluation will be coerced to.
-     * @return The result of the expression evaluation.
-     */
-    public Object getValue(String expression, Class<?> expectedType) {
-        ValueExpression exp = factory.createValueExpression(elManager.getELContext(), bracket(expression), expectedType);
-        return exp.getValue(elManager.getELContext());
-    }
-
-    /**
-     * 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.
-     *
-     * @param expression The target expression
-     * @param value The new value to set.
-     * 
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws PropertyNotWritableException if the final variable or property resolution failed because the specified
-     * variable or property is not writable.
-     * @throws ELException 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.
-     */
-    public void setValue(String expression, Object value) {
-        ValueExpression exp = factory.createValueExpression(elManager.getELContext(), bracket(expression), Object.class);
-        exp.setValue(elManager.getELContext(), value);
-    }
-
-    /**
-     * Assign a Jakarta Expression Language expression to a Jakarta Expression Language variable. The expression is parsed,
-     * but not evaluated, and the parsed expression is mapped to the Jakarta Expression Language variable in the local
-     * variable map. Any previously assigned expression to the same variable will be replaced. If the expression is
-     * <code>null</code>, the variable will be removed.
-     *
-     * @param var The name of the variable.
-     * @param expression The Jakarta Expression Language expression to be assigned to the variable.
-     */
-    public void setVariable(String var, String expression) {
-        ValueExpression exp = factory.createValueExpression(elManager.getELContext(), bracket(expression), Object.class);
-        elManager.setVariable(var, exp);
-    }
-
-    /**
-     * Define a Jakarta Expression Language function in the local function mapper.
-     *
-     * @param prefix The namespace for the function or "" for no namesapce.
-     * @param function The name of the function. If empty (""), the method name is used as the function name.
-     * @param className The full Java class name that implements the function.
-     * @param method The name (specified without parenthesis) or the signature (as in the Java Language Spec) of the static
-     * method that implements the function. If the name (e.g. "sum") is given, the first declared method in class that
-     * matches the name is selected. If the signature (e.g. "int sum(int, int)" ) is given, then the declared method with
-     * the signature is selected.
-     *
-     * @throws NullPointerException if any of the arguments is null.
-     * @throws ClassNotFoundException if the specified class does not exists.
-     * @throws 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, or if the method is not a static method.
-     */
-    public void defineFunction(String prefix, String function, String className, String method) throws ClassNotFoundException, NoSuchMethodException {
-        if (prefix == null || function == null || className == null || method == null) {
-            throw new NullPointerException("Null argument for defineFunction");
-        }
-
-        Method meth = null;
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        if (loader == null) {
-            loader = getClass().getClassLoader();
-        }
-
-        Class<?> klass = Class.forName(className, false, loader);
-        int j = method.indexOf('(');
-        if (j < 0) {
-            // Just a name is given
-            for (Method m : klass.getDeclaredMethods()) {
-                if (m.getName().equals(method)) {
-                    meth = m;
-                }
-            }
-            if (meth == null) {
-                throw new NoSuchMethodException("Bad method name: " + method);
-            }
-        } else {
-            // method is the signature
-            // First get the method name, ignore the return type
-            int p = method.indexOf(' ');
-            if (p < 0) {
-                throw new NoSuchMethodException("Bad method singnature: " + method);
-            }
-
-            String methodName = method.substring(p + 1, j).trim();
-
-            // Extract parameter types
-            p = method.indexOf(')', j + 1);
-            if (p < 0) {
-                throw new NoSuchMethodException("Bad method singnature: " + method);
-            }
-            String[] params = method.substring(j + 1, p).split(",");
-            Class<?>[] paramTypes = new Class<?>[params.length];
-            for (int i = 0; i < params.length; i++) {
-                paramTypes[i] = toClass(params[i], loader);
-            }
-            meth = klass.getDeclaredMethod(methodName, paramTypes);
-        }
-        if (!Modifier.isStatic(meth.getModifiers())) {
-            throw new NoSuchMethodException("The method specified in defineFunction must be static: " + meth);
-        }
-
-        if (function.equals("")) {
-            function = method;
-        }
-
-        elManager.mapFunction(prefix, function, meth);
-    }
-
-    /**
-     * Define a Jakarta Expression Language function in the local function mapper.
-     *
-     * @param prefix The namespace for the function or "" for no namesapce.
-     * @param function The name of the function. If empty (""), the method name is used as the function name.
-     * @param method The <code>java.lang.reflect.Method</code> instance of the method that implements the function.
-     * 
-     * @throws NullPointerException if any of the arguments is null.
-     * @throws NoSuchMethodException if the method is not a static method
-     */
-    public void defineFunction(String prefix, String function, Method method) throws NoSuchMethodException {
-        if (prefix == null || function == null || method == null) {
-            throw new NullPointerException("Null argument for defineFunction");
-        }
-        if (!Modifier.isStatic(method.getModifiers())) {
-            throw new NoSuchMethodException("The method specified in defineFunction must be static: " + method);
-        }
-        if (function.equals("")) {
-            function = method.getName();
-        }
-
-        elManager.mapFunction(prefix, function, method);
-    }
-
-    /**
-     * Define a bean in a local bean repository, hiding other beans of the same name.
-     *
-     * @param name The name of the bean
-     * @param bean The bean instance to be defined. If <code>null</code>, the name will be removed from the local bean
-     * repository.
-     */
-    public void defineBean(String name, Object bean) {
-        elManager.defineBean(name, bean);
-    }
-
-    /**
-     * Return the Class object associated with the class or interface with the given name.
-     */
-    private static Class<?> toClass(String type, ClassLoader loader) throws ClassNotFoundException {
-        Class<?> c = null;
-        int i0 = type.indexOf('[');
-        int dims = 0;
-        if (i0 > 0) {
-            // This is an array. Count the dimensions
-            for (int i = 0; i < type.length(); i++) {
-                if (type.charAt(i) == '[') {
-                    dims++;
-                }
-            }
-            type = type.substring(0, i0);
-        }
-
-        if ("boolean".equals(type)) {
-            c = boolean.class;
-        } else if ("char".equals(type)) {
-            c = char.class;
-        } else if ("byte".equals(type)) {
-            c = byte.class;
-        } else if ("short".equals(type)) {
-            c = short.class;
-        } else if ("int".equals(type)) {
-            c = int.class;
-        } else if ("long".equals(type)) {
-            c = long.class;
-        } else if ("float".equals(type)) {
-            c = float.class;
-        } else if ("double".equals(type)) {
-            c = double.class;
-        } else {
-            c = loader.loadClass(type);
-        }
-
-        if (dims == 0) {
-            return c;
-        }
-
-        if (dims == 1) {
-            return java.lang.reflect.Array.newInstance(c, 1).getClass();
-        }
-
-        // Array of more than i dimension
-        return Array.newInstance(c, new int[dims]).getClass();
-    }
-
-    private String bracket(String expression) {
-        return "${" + expression + '}';
-    }
-}
diff --git a/api/src/main/java/javax/el/ELResolver.java b/api/src/main/java/javax/el/ELResolver.java
deleted file mode 100644
index f21459d..0000000
--- a/api/src/main/java/javax/el/ELResolver.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.beans.FeatureDescriptor;
-import java.util.Iterator;
-
-/**
- * Enables customization of variable, property, method call, and type conversion resolution behavior for Jakarta
- * Expression Language expression evaluation.
- *
- * <p>
- * While evaluating an expression, the <code>ELResolver</code> associated with the {@link ELContext} is consulted to do
- * the initial resolution of the first variable of an expression. It is also consulted when a <code>.</code> or
- * <code>[]</code> operator is encountered.
- *
- * <p>
- * For example, in the Jakarta Expression Language expression <code>${employee.lastName}</code>, the
- * <code>ELResolver</code> determines what object <code>employee</code> refers to, and what it means to get the
- * <code>lastName</code> property on that object.
- *
- * <p>
- * Most methods in this class accept a <code>base</code> and <code>property</code> parameter. In the case of variable
- * resolution (e.g. determining what <code>employee</code> refers to in <code>${employee.lastName}</code>), the
- * <code>base</code> parameter will be <code>null</code> and the <code>property</code> parameter will always be of type
- * <code>String</code>. In this case, if the <code>property</code> is not a <code>String</code>, the behavior of the
- * <code>ELResolver</code> is undefined.
- *
- * <p>
- * In the case of property resolution, the <code>base</code> parameter identifies the base object and the
- * <code>property</code> object identifies the property on that base. For example, in the expression
- * <code>${employee.lastName}</code>, <code>base</code> is the result of the variable resolution for
- * <code>employee</code> and <code>property</code> is the string <code>"lastName"</code>. In the expression
- * <code>${y[x]}</code>, <code>base</code> is the result of the variable resolution for <code>y</code> and
- * <code>property</code> is the result of the variable resolution for <code>x</code>.
- *
- * <p>
- * In the case of method call resolution, the <code>base</code> parameter identifies the base object and the
- * <code>method</code> parameter identifies a method on that base. In the case of overloaded methods, the <code>
- * paramTypes</code> parameter can be optionally used to identify a method. The <code>params</code>parameter are the
- * parameters for the method call, and can also be used for resolving overloaded methods when the
- * <code>paramTypes</code> parameter is not specified.
- *
- * <p>
- * In the case of type conversion resolution, the <code>obj</code> parameter identifies the source object and the
- * <code>targetType</code> parameter identifies the target type the source to covert to.
- *
- * <p>
- * Though only a single <code>ELResolver</code> is associated with an <code>ELContext</code>, there are usually multiple
- * resolvers considered for any given variable or property resolution. <code>ELResolver</code>s are combined together
- * using {@link CompositeELResolver}s, to define rich semantics for evaluating an expression.
- * </p>
- *
- * <p>
- * For the {@link #getValue}, {@link #getType}, {@link #setValue}, and {@link #isReadOnly} methods, an
- * <code>ELResolver</code> is not responsible for resolving all possible (base, property) pairs. In fact, most resolvers
- * will only handle a <code>base</code> of a single type. To indicate that a resolver has successfully resolved a
- * particular (base, property) pair, it must set the <code>propertyResolved</code> property of the
- * <code>ELContext</code> to <code>true</code>. If it could not handle the given pair, it must leave this property
- * alone. The caller must ignore the return value of the method if <code>propertyResolved</code> is <code>false</code>.
- *
- * <p>
- * Similarly, for the {@link #convertToType} method an <code>ELResolver</code> must set the
- * <code>propertyResolved</code> to <code>true</code> to indicate that it handles the conversion of the object to the
- * target type.
- *
- * <p>
- * The {@link #getFeatureDescriptors} and {@link #getCommonPropertyType} methods are primarily designed for design-time
- * tool support, but must handle invocation at runtime as well. The {@link java.beans.Beans#isDesignTime} method can be
- * used to determine if the resolver is being consulted at design-time or runtime.
- *
- * @see CompositeELResolver
- * @see ELContext#getELResolver
- * @since Jakarta Server Pages 2.1
- */
-public abstract class ELResolver {
-
-    // --------------------------------------------------------- Constants
-
-    /**
-     * The attribute name of the named attribute in the <code>FeatureDescriptor</code> that specifies the runtime type of
-     * the variable or property.
-     */
-    public static final String TYPE = "type";
-
-    /**
-     * The attribute name of the named attribute in the <code>FeatureDescriptor</code> that specifies whether the variable
-     * or property can be resolved at runtime.
-     */
-    public static final String RESOLVABLE_AT_DESIGN_TIME = "resolvableAtDesignTime";
-
-    /**
-     * Attempts to resolve the given <code>property</code> object on the given <code>base</code> object.
-     *
-     * <p>
-     * If this resolver handles the given (base, property) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose property value is to be returned, or <code>null</code> to resolve a top-level
-     * variable.
-     * @param property The property or variable to be resolved.
-     * 
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the result of the variable or property resolution; otherwise undefined.
-     * 
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if the given (base, property) pair is handled by this <code>ELResolver</code> but
-     * the specified variable or property does not exist or is not readable.
-     * @throws ELException 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.
-     */
-    public abstract Object getValue(ELContext context, Object base, Object property);
-
-    /**
-     * Attempts to resolve and invoke the given <code>method</code> on the given <code>base</code> object.
-     *
-     * <p>
-     * If this resolver handles the given (base, method) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller should ignore the return value.
-     *
-     * <p>
-     * A default implementation is provided that returns null so that existing classes that extend ELResolver can continue
-     * to function.
-     *
-     * @param context The context of this evaluation.
-     * @param base The bean on which to invoke the method
-     * @param method The simple name of the method to invoke. Will be coerced to a <code>String</code>.
-     * @param paramTypes An array of Class objects identifying the method's formal parameter types, in declared order. Use
-     * an empty array if the method has no parameters. Can be <code>null</code>, in which case the method's formal parameter
-     * types are assumed to be unknown.
-     * @param params The parameters to pass to the method, or <code>null</code> if no parameters.
-     * 
-     * @return The result of the method invocation (<code>null</code> if the method has a <code>void</code> return type).
-     * 
-     * @throws MethodNotFoundException if no suitable method can be found.
-     * @throws ELException 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
-     * <code>InvocationTargetException</code>, extract its <code>cause</code> and pass it to the <code>ELException</code>
-     * constructor.
-     * 
-     * @since Jakarta Expression Language 2.2
-     */
-    public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {
-        return null;
-    }
-
-    /**
-     * For a given <code>base</code> and <code>property</code>, attempts to identify the most general type that is
-     * acceptable for an object to be passed as the <code>value</code> parameter in a future call to the {@link #setValue}
-     * method.
-     *
-     * <p>
-     * If this resolver handles the given (base, property) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * This is not always the same as <code>getValue().getClass()</code>. For example, in the case of an
-     * {@link ArrayELResolver}, the <code>getType</code> 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.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose property value is to be analyzed, or <code>null</code> to analyze a top-level
-     * variable.
-     * @param property The property or variable to return the acceptable type for.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the most general acceptable type; otherwise undefined.
-     * @throws PropertyNotFoundException if the given (base, property) pair is handled by this <code>ELResolver</code> but
-     * the specified variable or property does not exist or is not readable.
-     * @throws ELException 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.
-     */
-    public abstract Class<?> getType(ELContext context, Object base, Object property);
-
-    /**
-     * Attempts to set the value of the given <code>property</code> object on the given <code>base</code> object.
-     *
-     * <p>
-     * If this resolver handles the given (base, property) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller can safely assume no value has been set.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose property value is to be set, or <code>null</code> to set a top-level variable.
-     * @param property The property or variable to be set.
-     * @param value The value to set the property or variable to.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if the given (base, property) pair is handled by this <code>ELResolver</code> but
-     * the specified variable or property does not exist.
-     * @throws PropertyNotWritableException if the given (base, property) pair is handled by this <code>ELResolver</code>
-     * but the specified variable or property is not writable.
-     * @throws ELException 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.
-     */
-    public abstract void setValue(ELContext context, Object base, Object property, Object value);
-
-    /**
-     * For a given <code>base</code> and <code>property</code>, attempts to determine whether a call to {@link #setValue}
-     * will always fail.
-     *
-     * <p>
-     * If this resolver handles the given (base, property) pair, the <code>propertyResolved</code> property of the
-     * <code>ELContext</code> object must be set to <code>true</code> by the resolver, before returning. If this property is
-     * not <code>true</code> after this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose property value is to be analyzed, or <code>null</code> to analyze a top-level
-     * variable.
-     * @param property The property or variable to return the read-only status for.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>true</code> if the property is read-only or <code>false</code> if not; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if the given (base, property) pair is handled by this <code>ELResolver</code> but
-     * the specified variable or property does not exist.
-     * @throws ELException 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.
-     */
-    public abstract boolean isReadOnly(ELContext context, Object base, Object property);
-
-    /**
-     * Returns information about the set of variables or properties that can be resolved for the given <code>base</code>
-     * object. One use for this method is to assist tools in auto-completion.
-     *
-     * <p>
-     * If the <code>base</code> parameter is <code>null</code>, the resolver must enumerate the list of top-level variables
-     * it can resolve.
-     * </p>
-     *
-     * <p>
-     * The <code>Iterator</code> returned must contain zero or more instances of {@link java.beans.FeatureDescriptor}, in no
-     * guaranteed order. In the case of primitive types such as <code>int</code>, the value <code>null</code> must be
-     * returned. This is to prevent the useless iteration through all possible primitive values. A return value of
-     * <code>null</code> indicates that this resolver does not handle the given <code>base</code> object or that the results
-     * are too complex to represent with this method and the {@link #getCommonPropertyType} method should be used instead.
-     * </p>
-     *
-     * <p>
-     * Each <code>FeatureDescriptor</code> will contain information about a single variable or property. In addition to the
-     * standard properties, the <code>FeatureDescriptor</code> must have two named attributes (as set by the
-     * <code>setValue</code> method):
-     * <ul>
-     * <li>{@link #TYPE} - The value of this named attribute must be an instance of <code>java.lang.Class</code> and specify
-     * the runtime type of the variable or property.</li>
-     * <li>{@link #RESOLVABLE_AT_DESIGN_TIME} - The value of this named attribute must be an instance of
-     * <code>java.lang.Boolean</code> 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 <code>ELResolver</code> needs access to
-     * a resource that is only available at runtime and no acceptable simulated value can be provided.</li>
-     * </ul>
-     *
-     * <p>
-     * The caller should be aware that the <code>Iterator</code> 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.
-     *
-     * <p>
-     * This is a "best-effort" list. Not all <code>ELResolver</code>s will return completely accurate results, but all must
-     * be callable at both design-time and runtime (i.e. whether or not <code>Beans.isDesignTime()</code> returns
-     * <code>true</code>), without causing errors.
-     *
-     * <p>
-     * The <code>propertyResolved</code> property of the <code>ELContext</code> is not relevant to this method. The results
-     * of all <code>ELResolver</code>s are concatenated in the case of composite resolvers.
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object whose set of valid properties is to be enumerated, or <code>null</code> to enumerate the
-     * set of top-level variables that this resolver can evaluate.
-     * @return An <code>Iterator</code> containing zero or more (possibly infinitely more) <code>FeatureDescriptor</code>
-     * objects, or <code>null</code> if this resolver does not handle the given <code>base</code> object or that the results
-     * are too complex to represent with this method
-     * @see java.beans.FeatureDescriptor
-     */
-    public abstract Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base);
-
-    /**
-     * Returns the most general type that this resolver accepts for the <code>property</code> argument, given a
-     * <code>base</code> object. One use for this method is to assist tools in auto-completion.
-     *
-     * <p>
-     * 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 {@link ArrayELResolver} will accept any <code>int</code> as
-     * a <code>property</code>, so the return value would be <code>Integer.class</code>.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The base object to return the most general property type for, or <code>null</code> to enumerate the set
-     * of top-level variables that this resolver can evaluate.
-     * @return <code>null</code> if this <code>ELResolver</code> does not know how to handle the given <code>base</code>
-     * object; otherwise <code>Object.class</code> if any type of <code>property</code> is accepted; otherwise the most
-     * general <code>property</code> type accepted for the given <code>base</code>.
-     */
-    public abstract Class<?> getCommonPropertyType(ELContext context, Object base);
-
-    /**
-     * Converts an object to a specific type.
-     *
-     * <p>
-     * An <code>ELException</code> is thrown if an error occurs during the conversion.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param obj The object to convert.
-     * @param targetType The target type for the conversion.
-     * @return object converted to <code>targetType</code>
-     * @throws ELException thrown if errors occur.
-     */
-    public Object convertToType(ELContext context, Object obj, Class<?> targetType) {
-        return null;
-    }
-}
diff --git a/api/src/main/java/javax/el/ELUtil.java b/api/src/main/java/javax/el/ELUtil.java
deleted file mode 100644
index 4df4a44..0000000
--- a/api/src/main/java/javax/el/ELUtil.java
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * Utility methods for this portion of the Jakarta Expression Language implementation
- *
- * <p>
- * Methods on this class use a Map instance stored in ThreadLocal storage to minimize the performance impact on
- * operations that take place multiple times on a single Thread. The keys and values of the Map are implementation
- * private.
- *
- * @author edburns
- * @author Kin-man Chung
- * @author Dongbin Nie
- */
-class ELUtil {
-
-    /**
-     * This class may not be constructed.
-     */
-    private ELUtil() {
-    }
-
-    /*
-     * For testing Backward Compatibility option static java.util.Properties properties = new java.util.Properties(); static
-     * { properties.setProperty("javax.el.bc2.2", "true"); }
-     */
-    public static ExpressionFactory exprFactory = ExpressionFactory.newInstance(/* properties */);
-
-    /**
-     * <p>
-     * The <code>ThreadLocal</code> variable used to record the <code>javax.faces.context.FacesContext</code> instance for
-     * each processing thread.
-     * </p>
-     */
-    private static ThreadLocal<Map<String, ResourceBundle>> instance = new ThreadLocal<Map<String, ResourceBundle>>() {
-        @Override
-        protected Map<String, ResourceBundle> initialValue() {
-            return (null);
-        }
-    };
-
-    /**
-     * @return a Map stored in ThreadLocal storage. This may be used by methods of this class to minimize the performance
-     * impact for operations that may take place multiple times on a given Thread instance.
-     */
-    private static Map<String, ResourceBundle> getCurrentInstance() {
-        Map<String, ResourceBundle> result = instance.get();
-        if (result == null) {
-            result = new HashMap<>();
-            setCurrentInstance(result);
-        }
-
-        return result;
-
-    }
-
-    /**
-     * Replace the Map with the argument context.
-     *
-     * @param context the Map to be stored in ThreadLocal storage.
-     */
-    private static void setCurrentInstance(Map<String, ResourceBundle> context) {
-        instance.set(context);
-    }
-
-    /**
-     * Convenience method, calls through to getExceptionMessageString(javax.el.ELContext,java.lang.String,Object []).
-     *
-     * @param context the ELContext from which the Locale for this message is extracted.
-     * @param messageId the messageId String in the ResourceBundle
-     *
-     * @return a localized String for the argument messageId
-     */
-    public static String getExceptionMessageString(ELContext context, String messageId) {
-        return getExceptionMessageString(context, messageId, null);
-    }
-
-    /*
-     * <p>Return a Localized message String suitable for use as an Exception message. Examine the argument
-     * <code>context</code> for a <code>Locale</code>. If not present, use <code>Locale.getDefault()</code>. Load the
-     * <code>ResourceBundle</code> "javax.el.Messages" using that locale. Get the message string for argument
-     * <code>messageId</code>. If not found return "Missing Resource in Jakarta Expression Language implementation ??? messageId ???" with messageId
-     * substituted with the runtime value of argument <code>messageId</code>. If found, and argument <code>params</code> is
-     * non-null, format the message using the params. If formatting fails, return a sensible message including the
-     * <code>messageId</code>. If argument <code>params</code> is <code>null</code>, skip formatting and return the message
-     * directly, otherwise return the formatted message.</p>
-     *
-     * @param context the ELContext from which the Locale for this message is extracted.
-     *
-     * @param messageId the messageId String in the ResourceBundle
-     *
-     * @param params parameters to the message
-     *
-     * @return a localized String for the argument messageId
-     */
-    public static String getExceptionMessageString(ELContext context, String messageId, Object[] params) {
-        String result = "";
-        Locale locale = null;
-
-        if (null == context || null == messageId) {
-            return result;
-        }
-
-        if (null == (locale = context.getLocale())) {
-            locale = Locale.getDefault();
-        }
-
-        if (locale != null) {
-            Map<String, ResourceBundle> threadMap = getCurrentInstance();
-            ResourceBundle resourceBundle = null;
-            if (null == (resourceBundle = threadMap.get(locale.toString()))) {
-                resourceBundle = ResourceBundle.getBundle("javax.el.PrivateMessages", locale);
-                threadMap.put(locale.toString(), resourceBundle);
-            }
-
-            if (null != resourceBundle) {
-                try {
-                    result = resourceBundle.getString(messageId);
-                    if (null != params) {
-                        result = MessageFormat.format(result, params);
-                    }
-                } catch (IllegalArgumentException iae) {
-                    result = "Can't get localized message: parameters to message appear to be incorrect.  Message to format: " + messageId;
-                } catch (MissingResourceException mre) {
-                    result = "Missing Resource in Jakarta Expression Language implementation: ???" + messageId + "???";
-                } catch (Exception e) {
-                    result = "Exception resolving message in Jakarta Expression Language implementation: ???" + messageId + "???";
-                }
-            }
-        }
-
-        return result;
-    }
-
-    static ExpressionFactory getExpressionFactory() {
-        return exprFactory;
-    }
-
-    static Constructor<?> findConstructor(Class<?> klass, Class<?>[] paramTypes, Object[] params) {
-        String methodName = "<init>";
-
-        if (klass == null) {
-            throw new MethodNotFoundException("Method not found: " + klass + "." + methodName + "(" + paramString(paramTypes) + ")");
-        }
-
-        if (paramTypes == null) {
-            paramTypes = getTypesFromValues(params);
-        }
-
-        Constructor<?>[] constructors = klass.getConstructors();
-
-        List<Wrapper> wrappers = Wrapper.wrap(constructors);
-
-        Wrapper result = findWrapper(klass, wrappers, methodName, paramTypes, params);
-
-        if (result == null) {
-            return null;
-        }
-
-        return getConstructor(klass, (Constructor<?>) result.unWrap());
-    }
-
-    static Object invokeConstructor(ELContext context, Constructor<?> constructor, Object[] params) {
-        Object[] parameters = buildParameters(context, constructor.getParameterTypes(), constructor.isVarArgs(), params);
-        try {
-            return constructor.newInstance(parameters);
-        } catch (IllegalAccessException iae) {
-            throw new ELException(iae);
-        } catch (IllegalArgumentException iae) {
-            throw new ELException(iae);
-        } catch (InvocationTargetException ite) {
-            throw new ELException(ite.getCause());
-        } catch (InstantiationException ie) {
-            throw new ELException(ie.getCause());
-        }
-    }
-
-    static Method findMethod(Class<?> klass, String methodName, Class<?>[] paramTypes, Object[] params, boolean staticOnly) {
-        Method method = findMethod(klass, methodName, paramTypes, params);
-        if (staticOnly && !Modifier.isStatic(method.getModifiers())) {
-            throw new MethodNotFoundException("Method " + methodName + "for class " + klass + " not found or accessible");
-        }
-
-        return method;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    static Object invokeMethod(ELContext context, Method method, Object base, Object[] params) {
-
-        Object[] parameters = buildParameters(context, method.getParameterTypes(), method.isVarArgs(), params);
-        try {
-            return method.invoke(base, parameters);
-        } catch (IllegalAccessException iae) {
-            throw new ELException(iae);
-        } catch (IllegalArgumentException iae) {
-            throw new ELException(iae);
-        } catch (InvocationTargetException ite) {
-            throw new ELException(ite.getCause());
-        }
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    static Method findMethod(Class<?> clazz, String methodName, Class<?>[] paramTypes, Object[] paramValues) {
-        if (clazz == null || methodName == null) {
-            throw new MethodNotFoundException("Method not found: " + clazz + "." + methodName + "(" + paramString(paramTypes) + ")");
-        }
-
-        if (paramTypes == null) {
-            paramTypes = getTypesFromValues(paramValues);
-        }
-
-        Method[] methods = clazz.getMethods();
-
-        List<Wrapper> wrappers = Wrapper.wrap(methods, methodName);
-
-        Wrapper result = findWrapper(clazz, wrappers, methodName, paramTypes, paramValues);
-
-        if (result == null) {
-            return null;
-        }
-
-        return getMethod(clazz, (Method) result.unWrap());
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    @SuppressWarnings("null")
-    private static Wrapper findWrapper(Class<?> clazz, List<Wrapper> wrappers, String name, Class<?>[] paramTypes, Object[] paramValues) {
-        List<Wrapper> assignableCandidates = new ArrayList<>();
-        List<Wrapper> coercibleCandidates = new ArrayList<>();
-        List<Wrapper> varArgsCandidates = new ArrayList<>();
-
-        int paramCount;
-        if (paramTypes == null) {
-            paramCount = 0;
-        } else {
-            paramCount = paramTypes.length;
-        }
-
-        for (Wrapper w : wrappers) {
-            Class<?>[] mParamTypes = w.getParameterTypes();
-            int mParamCount;
-            if (mParamTypes == null) {
-                mParamCount = 0;
-            } else {
-                mParamCount = mParamTypes.length;
-            }
-
-            // Check the number of parameters
-            if (!(paramCount == mParamCount || (w.isVarArgs() && paramCount >= mParamCount - 1))) {
-                // Method has wrong number of parameters
-                continue;
-            }
-
-            // Check the parameters match
-            boolean assignable = false;
-            boolean coercible = false;
-            boolean varArgs = false;
-            boolean noMatch = false;
-            for (int i = 0; i < mParamCount; i++) {
-                if (i == (mParamCount - 1) && w.isVarArgs()) {
-                    varArgs = true;
-                    // exact var array type match
-                    if (mParamCount == paramCount) {
-                        if (mParamTypes[i] == paramTypes[i]) {
-                            continue;
-                        }
-                    }
-
-                    // unwrap the array's component type
-                    Class<?> varType = mParamTypes[i].getComponentType();
-                    for (int j = i; j < paramCount; j++) {
-                        if (!isAssignableFrom(paramTypes[j], varType)
-                                && !(paramValues != null && j < paramValues.length && isCoercibleFrom(paramValues[j], varType))) {
-                            noMatch = true;
-                            break;
-                        }
-                    }
-                } else if (mParamTypes[i].equals(paramTypes[i])) {
-                } else if (isAssignableFrom(paramTypes[i], mParamTypes[i])) {
-                    assignable = true;
-                } else {
-                    if (paramValues == null || i >= paramValues.length) {
-                        noMatch = true;
-                        break;
-                    } else {
-                        if (isCoercibleFrom(paramValues[i], mParamTypes[i])) {
-                            coercible = true;
-                        } else {
-                            noMatch = true;
-                            break;
-                        }
-                    }
-                }
-            }
-            if (noMatch) {
-                continue;
-            }
-
-            if (varArgs) {
-                varArgsCandidates.add(w);
-            } else if (coercible) {
-                coercibleCandidates.add(w);
-            } else if (assignable) {
-                assignableCandidates.add(w);
-            } else {
-                // If a method is found where every parameter matches exactly,
-                // return it
-                return w;
-            }
-
-        }
-
-        String errorMsg = "Unable to find unambiguous method: " + clazz + "." + name + "(" + paramString(paramTypes) + ")";
-        if (!assignableCandidates.isEmpty()) {
-            return findMostSpecificWrapper(assignableCandidates, paramTypes, false, errorMsg);
-        } else if (!coercibleCandidates.isEmpty()) {
-            return findMostSpecificWrapper(coercibleCandidates, paramTypes, true, errorMsg);
-        } else if (!varArgsCandidates.isEmpty()) {
-            return findMostSpecificWrapper(varArgsCandidates, paramTypes, true, errorMsg);
-        } else {
-            throw new MethodNotFoundException("Method not found: " + clazz + "." + name + "(" + paramString(paramTypes) + ")");
-        }
-
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static Wrapper findMostSpecificWrapper(List<Wrapper> candidates, Class<?>[] matchingTypes, boolean elSpecific, String errorMsg) {
-        List<Wrapper> ambiguouses = new ArrayList<>();
-        for (Wrapper candidate : candidates) {
-            boolean lessSpecific = false;
-
-            Iterator<Wrapper> it = ambiguouses.iterator();
-            while (it.hasNext()) {
-                int result = isMoreSpecific(candidate, it.next(), matchingTypes, elSpecific);
-                if (result == 1) {
-                    it.remove();
-                } else if (result == -1) {
-                    lessSpecific = true;
-                }
-            }
-
-            if (!lessSpecific) {
-                ambiguouses.add(candidate);
-            }
-        }
-
-        if (ambiguouses.size() > 1) {
-            throw new MethodNotFoundException(errorMsg);
-        }
-
-        return ambiguouses.get(0);
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static int isMoreSpecific(Wrapper wrapper1, Wrapper wrapper2, Class<?>[] matchingTypes, boolean elSpecific) {
-        Class<?>[] paramTypes1 = wrapper1.getParameterTypes();
-        Class<?>[] paramTypes2 = wrapper2.getParameterTypes();
-
-        if (wrapper1.isVarArgs()) {
-            // JLS8 15.12.2.5 Choosing the Most Specific Method
-            int length = Math.max(Math.max(paramTypes1.length, paramTypes2.length), matchingTypes.length);
-            paramTypes1 = getComparingParamTypesForVarArgsMethod(paramTypes1, length);
-            paramTypes2 = getComparingParamTypesForVarArgsMethod(paramTypes2, length);
-
-            if (length > matchingTypes.length) {
-                Class<?>[] matchingTypes2 = new Class<?>[length];
-                System.arraycopy(matchingTypes, 0, matchingTypes2, 0, matchingTypes.length);
-                matchingTypes = matchingTypes2;
-            }
-        }
-
-        int result = 0;
-        for (int i = 0; i < paramTypes1.length; i++) {
-            if (paramTypes1[i] != paramTypes2[i]) {
-                int r2 = isMoreSpecific(paramTypes1[i], paramTypes2[i], matchingTypes[i], elSpecific);
-                if (r2 == 1) {
-                    if (result == -1) {
-                        return 0;
-                    }
-                    result = 1;
-                } else if (r2 == -1) {
-                    if (result == 1) {
-                        return 0;
-                    }
-                    result = -1;
-                } else {
-                    return 0;
-                }
-            }
-        }
-
-        if (result == 0) {
-            // The nature of bridge methods is such that it actually
-            // doesn't matter which one we pick as long as we pick
-            // one. That said, pick the 'right' one (the non-bridge
-            // one) anyway.
-            result = Boolean.compare(wrapper1.isBridge(), wrapper2.isBridge());
-        }
-
-        return result;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static int isMoreSpecific(Class<?> type1, Class<?> type2, Class<?> matchingType, boolean elSpecific) {
-        type1 = getBoxingTypeIfPrimitive(type1);
-        type2 = getBoxingTypeIfPrimitive(type2);
-        if (type2.isAssignableFrom(type1)) {
-            return 1;
-        } else if (type1.isAssignableFrom(type2)) {
-            return -1;
-        } else {
-            if (elSpecific) {
-                /*
-                 * Number will be treated as more specific
-                 *
-                 * ASTInteger only return Long or BigInteger, no Byte / Short / Integer. ASTFloatingPoint also.
-                 *
-                 */
-                if (matchingType != null && Number.class.isAssignableFrom(matchingType)) {
-                    boolean b1 = Number.class.isAssignableFrom(type1) || type1.isPrimitive();
-                    boolean b2 = Number.class.isAssignableFrom(type2) || type2.isPrimitive();
-                    if (b1 && !b2) {
-                        return 1;
-                    } else if (b2 && !b1) {
-                        return -1;
-                    } else {
-                        return 0;
-                    }
-                }
-
-                return 0;
-            } else {
-                return 0;
-            }
-        }
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static Class<?> getBoxingTypeIfPrimitive(Class<?> clazz) {
-        if (clazz.isPrimitive()) {
-            if (clazz == Boolean.TYPE) {
-                return Boolean.class;
-            }
-            if (clazz == Character.TYPE) {
-                return Character.class;
-            }
-            if (clazz == Byte.TYPE) {
-                return Byte.class;
-            }
-            if (clazz == Short.TYPE) {
-                return Short.class;
-            }
-            if (clazz == Integer.TYPE) {
-                return Integer.class;
-            }
-            if (clazz == Long.TYPE) {
-                return Long.class;
-            }
-            if (clazz == Float.TYPE) {
-                return Float.class;
-            }
-
-            return Double.class;
-        } else {
-            return clazz;
-        }
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static Class<?>[] getComparingParamTypesForVarArgsMethod(Class<?>[] paramTypes, int length) {
-        Class<?>[] result = new Class<?>[length];
-        System.arraycopy(paramTypes, 0, result, 0, paramTypes.length - 1);
-        Class<?> type = paramTypes[paramTypes.length - 1].getComponentType();
-        for (int i = paramTypes.length - 1; i < length; i++) {
-            result[i] = type;
-        }
-
-        return result;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static final String paramString(Class<?>[] types) {
-        if (types != null) {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < types.length; i++) {
-                if (types[i] == null) {
-                    sb.append("null, ");
-                } else {
-                    sb.append(types[i].getName()).append(", ");
-                }
-            }
-            if (sb.length() > 2) {
-                sb.setLength(sb.length() - 2);
-            }
-            return sb.toString();
-        }
-        return null;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    static boolean isAssignableFrom(Class<?> src, Class<?> target) {
-        // src will always be an object
-        // Short-cut. null is always assignable to an object and in Jakarta Expression Language null
-        // can always be coerced to a valid value for a primitive
-        if (src == null) {
-            return true;
-        }
-
-        target = getBoxingTypeIfPrimitive(target);
-
-        return target.isAssignableFrom(src);
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static boolean isCoercibleFrom(Object src, Class<?> target) {
-        // TODO: This isn't pretty but it works. Significant refactoring would
-        // be required to avoid the exception.
-        try {
-            getExpressionFactory().coerceToType(src, target);
-        } catch (Exception e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static Class<?>[] getTypesFromValues(Object[] values) {
-        if (values == null) {
-            return null;
-        }
-
-        Class<?> result[] = new Class<?>[values.length];
-        for (int i = 0; i < values.length; i++) {
-            if (values[i] == null) {
-                result[i] = null;
-            } else {
-                result[i] = values[i].getClass();
-            }
-        }
-
-        return result;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     *
-     * Get a public method form a public class or interface of a given method. Note that if a PropertyDescriptor is obtained
-     * for a non-public class that implements a public interface, the read/write methods will be for the class, and
-     * therefore inaccessible. To correct this, a version of the same method must be found in a superclass or interface.
-     *
-     */
-    static Method getMethod(Class<?> type, Method m) {
-        if (m == null || Modifier.isPublic(type.getModifiers())) {
-            return m;
-        }
-        Class<?>[] inf = type.getInterfaces();
-        Method mp = null;
-        for (int i = 0; i < inf.length; i++) {
-            try {
-                mp = inf[i].getMethod(m.getName(), m.getParameterTypes());
-                mp = getMethod(mp.getDeclaringClass(), mp);
-                if (mp != null) {
-                    return mp;
-                }
-            } catch (NoSuchMethodException e) {
-                // Ignore
-            }
-        }
-        Class<?> sup = type.getSuperclass();
-        if (sup != null) {
-            try {
-                mp = sup.getMethod(m.getName(), m.getParameterTypes());
-                mp = getMethod(mp.getDeclaringClass(), mp);
-                if (mp != null) {
-                    return mp;
-                }
-            } catch (NoSuchMethodException e) {
-                // Ignore
-            }
-        }
-        return null;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    static Constructor<?> getConstructor(Class<?> type, Constructor<?> c) {
-        if (c == null || Modifier.isPublic(type.getModifiers())) {
-            return c;
-        }
-        Constructor<?> cp = null;
-        Class<?> sup = type.getSuperclass();
-        if (sup != null) {
-            try {
-                cp = sup.getConstructor(c.getParameterTypes());
-                cp = getConstructor(cp.getDeclaringClass(), cp);
-                if (cp != null) {
-                    return cp;
-                }
-            } catch (NoSuchMethodException e) {
-                // Ignore
-            }
-        }
-        return null;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    @SuppressWarnings("null")
-    static Object[] buildParameters(ELContext context, Class<?>[] parameterTypes, boolean isVarArgs, Object[] params) {
-        Object[] parameters = null;
-        if (parameterTypes.length > 0) {
-            parameters = new Object[parameterTypes.length];
-            int paramCount = params == null ? 0 : params.length;
-            if (isVarArgs) {
-                int varArgIndex = parameterTypes.length - 1;
-                // First argCount-1 parameters are standard
-                for (int i = 0; (i < varArgIndex && i < paramCount); i++) {
-                    parameters[i] = context.convertToType(params[i], parameterTypes[i]);
-                }
-                // Last parameter is the varargs
-                if (parameterTypes.length == paramCount && parameterTypes[varArgIndex] == params[varArgIndex].getClass()) {
-                    parameters[varArgIndex] = params[varArgIndex];
-                } else {
-                    Class<?> varArgClass = parameterTypes[varArgIndex].getComponentType();
-                    final Object varargs = Array.newInstance(varArgClass, (paramCount - varArgIndex));
-                    for (int i = (varArgIndex); i < paramCount; i++) {
-                        Array.set(varargs, i - varArgIndex, context.convertToType(params[i], varArgClass));
-                    }
-                    parameters[varArgIndex] = varargs;
-                }
-            } else {
-                for (int i = 0; i < parameterTypes.length && i < paramCount; i++) {
-                    parameters[i] = context.convertToType(params[i], parameterTypes[i]);
-                }
-            }
-        }
-        return parameters;
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private abstract static class Wrapper {
-
-        public static List<Wrapper> wrap(Method[] methods, String name) {
-            List<Wrapper> result = new ArrayList<>();
-            for (Method method : methods) {
-                if (method.getName().equals(name)) {
-                    result.add(new MethodWrapper(method));
-                }
-            }
-            return result;
-        }
-
-        public static List<Wrapper> wrap(Constructor<?>[] constructors) {
-            List<Wrapper> result = new ArrayList<>();
-            for (Constructor<?> constructor : constructors) {
-                result.add(new ConstructorWrapper(constructor));
-            }
-            return result;
-        }
-
-        public abstract Object unWrap();
-
-        public abstract Class<?>[] getParameterTypes();
-
-        public abstract boolean isVarArgs();
-
-        public abstract boolean isBridge();
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static class MethodWrapper extends Wrapper {
-        private final Method m;
-
-        public MethodWrapper(Method m) {
-            this.m = m;
-        }
-
-        @Override
-        public Object unWrap() {
-            return m;
-        }
-
-        @Override
-        public Class<?>[] getParameterTypes() {
-            return m.getParameterTypes();
-        }
-
-        @Override
-        public boolean isVarArgs() {
-            return m.isVarArgs();
-        }
-
-        @Override
-        public boolean isBridge() {
-            return m.isBridge();
-        }
-    }
-
-    /*
-     * This method duplicates code in com.sun.el.util.ReflectionUtil. When making changes keep the code in sync.
-     */
-    private static class ConstructorWrapper extends Wrapper {
-        private final Constructor<?> c;
-
-        public ConstructorWrapper(Constructor<?> c) {
-            this.c = c;
-        }
-
-        @Override
-        public Object unWrap() {
-            return c;
-        }
-
-        @Override
-        public Class<?>[] getParameterTypes() {
-            return c.getParameterTypes();
-        }
-
-        @Override
-        public boolean isVarArgs() {
-            return c.isVarArgs();
-        }
-
-        @Override
-        public boolean isBridge() {
-            return false;
-        }
-    }
-
-}
diff --git a/api/src/main/java/javax/el/EvaluationListener.java b/api/src/main/java/javax/el/EvaluationListener.java
deleted file mode 100644
index f359ad2..0000000
--- a/api/src/main/java/javax/el/EvaluationListener.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-/**
- * The listener interface for receiving notification when a Jakarta Expression Language expression is evaluated.
- *
- * @since Jakarta Expression Language 3.0
- */
-public abstract class EvaluationListener {
-
-    /**
-     * Receives notification before a Jakarta Expression Language expression is evaluated
-     *
-     * @param context The ELContext
-     * @param expression The Jakarta Expression Language expression string to be evaluated
-     */
-    public void beforeEvaluation(ELContext context, String expression) {
-    }
-
-    /**
-     * Receives notification after a Jakarta Expression Language expression is evaluated
-     *
-     * @param context The ELContext
-     * @param expression The Jakarta Expression Language expression string to be evaluated
-     */
-    public void afterEvaluation(ELContext context, String expression) {
-    }
-
-    /**
-     * Receives notification when the (base, property) pair is resolved
-     *
-     * @param context The ELContext
-     * @param base The base object
-     * @param property The property object
-     */
-    public void propertyResolved(ELContext context, Object base, Object property) {
-    }
-
-}
diff --git a/api/src/main/java/javax/el/Expression.java b/api/src/main/java/javax/el/Expression.java
deleted file mode 100644
index fd00f8f..0000000
--- a/api/src/main/java/javax/el/Expression.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.io.Serializable;
-
-/**
- * Base class for the expression subclasses {@link ValueExpression} and {@link MethodExpression}, implementing
- * characteristics common to both.
- *
- * <p>
- * All expressions must implement the <code>equals()</code> and <code>hashCode()</code> methods so that two expressions
- * can be compared for equality. They are redefined abstract in this class to force their implementation in subclasses.
- * </p>
- *
- * <p>
- * All expressions must also be <code>Serializable</code> so that they can be saved and restored.
- * </p>
- *
- * <p>
- * <code>Expression</code>s are also designed to be immutable so that only one instance needs to be created for any
- * given expression String / {@link FunctionMapper}. This allows a container to pre-create expressions and not have to
- * re-parse them each time they are evaluated.
- * </p>
- *
- * @since Jakarta Server Pages 2.1
- */
-public abstract class Expression implements Serializable {
-
-    private static final long serialVersionUID = -6663767980471823812L;
-
-    /**
-     * Returns the original String used to create this <code>Expression</code>, unmodified.
-     *
-     * <p>
-     * 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).
-     * </p>
-     *
-     * <p>
-     * 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 <code>Expression</code>.
-     * </p>
-     *
-     * @return The original expression String.
-     */
-    public abstract String getExpressionString();
-
-    // Comparison
-
-    /**
-     * Determines whether the specified object is equal to this <code>Expression</code>.
-     *
-     * <p>
-     * The result is <code>true</code> if and only if the argument is not <code>null</code>, is an <code>Expression</code>
-     * object that is the of the same type (<code>ValueExpression</code> or <code>MethodExpression</code>), and has an
-     * identical parsed representation.
-     * </p>
-     *
-     * <p>
-     * Note that two expressions can be equal if their expression Strings are different. For example,
-     * <code>${fn1:foo()}</code> and <code>${fn2:foo()}</code> are equal if their corresponding <code>FunctionMapper</code>s
-     * mapped <code>fn1:foo</code> and <code>fn2:foo</code> to the same method.
-     * </p>
-     *
-     * @param obj the <code>Object</code> to test for equality.
-     * @return <code>true</code> if <code>obj</code> equals this <code>Expression</code>; <code>false</code> otherwise.
-     * @see java.util.Hashtable
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public abstract boolean equals(Object obj);
-
-    /**
-     * Returns the hash code for this <code>Expression</code>.
-     *
-     * <p>
-     * See the note in the {@link #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 <code>equals(Object)</code> method, then calling the
-     * <code>hashCode</code> method on each of the two objects must produce the same integer result. Implementations must
-     * take special note and implement <code>hashCode</code> correctly.
-     * </p>
-     *
-     * @return The hash code for this <code>Expression</code>.
-     * @see #equals
-     * @see java.util.Hashtable
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public abstract int hashCode();
-
-    /**
-     * Returns whether this expression was created from only literal text.
-     *
-     * <p>
-     * This method must return <code>true</code> if and only if the expression string this expression was created from
-     * contained no unescaped Jakarta Expression Language delimeters (<code>${...}</code> or <code>#{...}</code>).
-     *
-     * @return <code>true</code> if this expression was created from only literal text; <code>false</code> otherwise.
-     */
-    public abstract boolean isLiteralText();
-}
diff --git a/api/src/main/java/javax/el/ExpressionFactory.java b/api/src/main/java/javax/el/ExpressionFactory.java
deleted file mode 100644
index e005de4..0000000
--- a/api/src/main/java/javax/el/ExpressionFactory.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Provides an implementation for creating and evaluating Jakarta Expression Language expressions.
- *
- * <p>
- * Classes that implement the Jakarta Expression Language expression language expose their functionality via this
- * abstract class. An implementation supports the following functionalities.
- *
- * <ul>
- *   <li>Parses a <code>String</code> into a {@link ValueExpression} or {@link MethodExpression} instance for later
- *   evaluation.</li>
- *   <li>Implements an <code>ELResolver</code> for query operators</li>
- *   <li>Provides a default type coercion</li>
- * </ul>
- *
- * <p>
- * The {@link #newInstance} method can be used to obtain an instance of the implementation. Technologies such as
- * Jakarta Server Pages and Jakarta Faces provide access to an implementation via factory methods.
- *
- * <p>
- * The {@link #createValueExpression} method is used to parse expressions that evaluate to values (both l-values and
- * r-values are supported). The {@link #createMethodExpression} method is used to parse expressions that evaluate to a
- * reference to a method on an object.
- *
- * <p>
- * Resolution of model objects is performed at evaluation time, via the {@link ELResolver} associated with the
- * {@link ELContext} passed to the <code>ValueExpression</code> or <code>MethodExpression</code>.
- *
- * <p>
- * The ELContext object also provides access to the {@link FunctionMapper} and {@link VariableMapper} to be used when
- * parsing the expression. Jakarta Expression Language function and variable mapping is performed at parse-time, and the
- * results are bound to the expression. Therefore, the {@link ELContext}, {@link FunctionMapper}, and
- * {@link VariableMapper} are not stored for future use and do not have to be <code>Serializable</code>.
- *
- * <p>
- * The <code>createValueExpression</code> and <code>createMethodExpression</code> methods must be thread-safe. That is,
- * multiple threads may call these methods on the same <code>ExpressionFactory</code> object simultaneously.
- * Implementations should synchronize access if they depend on transient state. Implementations should not, however,
- * assume that only one object of each <code>ExpressionFactory</code> type will be instantiated; global caching should
- * therefore be static.
- *
- * <p>
- * The <code>ExpressionFactory</code> must be able to handle the following types of input for the
- * <code>expression</code> parameter:
- * <ul>
- *   <li>Single expressions using the <code>${}</code> delimiter (e.g. <code>"${employee.lastName}"</code>).</li>
- *   <li>Single expressions using the <code>#{}</code> delimiter (e.g. <code>"#{employee.lastName}"</code>).</li>
- *   <li>Literal text containing no <code>${}</code> or <code>#{}</code> delimiters (e.g. <code>"John Doe"</code>).</li>
- *   <li>Multiple expressions using the same delimiter (e.g. <code>"${employee.firstName}${employee.lastName}"</code> or
- *   <code>"#{employee.firstName}#{employee.lastName}"</code>).</li>
- *   <li>Mixed literal text and expressions using the same delimiter (e.g.
- *   <code>"Name: ${employee.firstName} ${employee.lastName}"</code>).</li>
- * </ul>
- *
- * <p>
- * The following types of input are illegal and must cause an {@link ELException} to be thrown:
- * <ul>
- *   <li>Multiple expressions using different delimiters (e.g.
- *   <code>"${employee.firstName}#{employee.lastName}"</code>).</li>
- *   <li>Mixed literal text and expressions using different delimiters(e.g.
- *   <code>"Name: ${employee.firstName} #{employee.lastName}"</code>).</li>
- * </ul>
- *
- * @since Jakarta Server Pages 2.1
- */
-public abstract class ExpressionFactory {
-
-    /**
-     * Creates a new instance of a <code>ExpressionFactory</code>. This method uses the following ordered lookup procedure
-     * to determine the <code>ExpressionFactory</code> implementation class to load:
-     *
-     * <ul>
-     * <li>Use the Services API (as detailed in the JAR specification). If a resource with the name of
-     * <code>META-INF/services/javax.el.ExpressionFactory</code> exists, then its first line, if present, is used as the
-     * UTF-8 encoded name of the implementation class.</li>
-     * <li>Use the properties file "lib/el.properties" in the JRE directory. If this file exists and it is readable by the
-     * <code> java.util.Properties.load(InputStream)</code> method, and it contains an entry whose key is
-     * "javax.el.ExpressionFactory", then the value of that entry is used as the name of the implementation class.</li>
-     * <li>Use the <code>javax.el.ExpressionFactory</code> system property. If a system property with this name is defined,
-     * then its value is used as the name of the implementation class.</li>
-     * <li>Use a platform default implementation.</li>
-     * </ul>
-     *
-     * @return a new <code>ExpressionFactory</code> instance
-     */
-    public static ExpressionFactory newInstance() {
-        return ExpressionFactory.newInstance(null);
-    }
-
-    /**
-     * Create a new instance of a <code>ExpressionFactory</code>, with optional properties.
-     *
-     * <p>
-     * This method uses the same lookup procedure as the one used in <code>newInstance()</code>.
-     *
-     * <p>
-     * If the argument <code>properties</code> is not null, and if the implementation contains a constructor with a single
-     * parameter of type <code>java.util.Properties</code>, then the constructor is used to create the instance.
-     *
-     * <p>
-     * Properties are optional and can be ignored by an implementation.
-     *
-     * <p>
-     * The name of a property should start with "javax.el."
-     *
-     * <p>
-     * The following are some suggested names for properties.
-     * <ul>
-     * <li>javax.el.cacheSize</li>
-     * </ul>
-     *
-     * @param properties Properties passed to the implementation. If null, then no properties.
-     *
-     * @return a new <code>ExpressionFactory</code> instance
-     */
-    public static ExpressionFactory newInstance(Properties properties) {
-        return (ExpressionFactory) FactoryFinder.find("javax.el.ExpressionFactory", "com.sun.el.ExpressionFactoryImpl", properties);
-    }
-
-    /**
-     * Parses an expression into a {@link ValueExpression} for later evaluation. Use this method for expressions that refer
-     * to values.
-     *
-     * <p>
-     * This method should perform syntactic validation of the expression. If in doing so it detects errors, it should raise
-     * an <code>ELException</code>.
-     *
-     * @param context The Jakarta Expression Language context used to parse the expression. The <code>FunctionMapper</code>
-     * and <code>VariableMapper</code> stored in the ELContext are used to resolve functions and variables found in the
-     * expression. They can be <code>null</code>, in which case functions or variables are not supported for this
-     * expression. The object returned must invoke the same functions and access the same variable mappings regardless of
-     * whether the mappings in the provided <code>FunctionMapper</code> and <code>VariableMapper</code> instances change
-     * between calling <code>ExpressionFactory.createValueExpression()</code> and any method on
-     * <code>ValueExpression</code>. Note that within Jakarta Expression Language, the ${} and #{} syntaxes are treated
-     * identically. This includes the use of VariableMapper and FunctionMapper at expression creation time. Each is invoked
-     * if not null, independent of whether the #{} or ${} syntax is used for the expression.
-     * @param expression The expression to parse
-     * @param expectedType The type the result of the expression will be coerced to after evaluation.
-     * 
-     * @return The parsed expression
-     * 
-     * @throws NullPointerException Thrown if expectedType is null.
-     * @throws ELException Thrown if there are syntactical errors in the provided expression.
-     */
-    public abstract ValueExpression createValueExpression(ELContext context, String expression, Class<?> expectedType);
-
-    /**
-     * Creates a ValueExpression that wraps an object instance.
-     *
-     * <p>
-     * 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 <code>getValue()</code> method, optionally coerced.
-     * </p>
-     *
-     * @param instance The object instance to be wrapped.
-     * @param expectedType The type the result of the expression will be coerced to after evaluation. There will be no
-     * coercion if it is Object.class,
-     * @throws NullPointerException Thrown if expectedType is null.
-     * @return a ValueExpression that wraps an object instance
-     */
-    public abstract ValueExpression createValueExpression(Object instance, Class<?> expectedType);
-
-    /**
-     * Parses an expression into a {@link MethodExpression} for later evaluation. Use this method for expressions that refer
-     * to methods.
-     *
-     * <p>
-     * If the expression is a String literal, a <code>MethodExpression
-     * </code> 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").
-     *
-     * <p>
-     * This method should perform syntactic validation of the expression. If in doing so it detects errors, it should raise
-     * an <code>ELException</code>.
-     *
-     * @param context The Jakarta Expression Language context used to parse the expression. The <code>FunctionMapper</code>
-     * and <code>VariableMapper</code> stored in the ELContext are used to resolve functions and variables found in the
-     * expression. They can be <code>null</code>, in which case functions or variables are not supported for this
-     * expression. The object returned must invoke the same functions and access the same variable mappings regardless of
-     * whether the mappings in the provided <code>FunctionMapper</code> and <code>VariableMapper</code> instances change
-     * between calling <code>ExpressionFactory.createMethodExpression()</code> and any method on
-     * <code>MethodExpression</code>. Note that within the EL, the ${} and #{} syntaxes are treated identically. This
-     * includes the use of VariableMapper and FunctionMapper at expression creation time. Each is invoked if not null,
-     * independent of whether the #{} or ${} syntax is used for the expression.
-     * @param expression The expression to parse
-     * @param expectedReturnType The expected return type for the method to be found. After evaluating the expression, the
-     * <code>MethodExpression</code> must check that the return type of the actual method matches this type. Passing in a
-     * value of <code>null</code> indicates the caller does not care what the return type is, and the check is disabled.
-     * @param expectedParamTypes The expected parameter types for the method to be found. Must be an array with no elements
-     * if there are no parameters expected. It is illegal to pass <code>null</code>, unless the method is specified with
-     * arguments in the Jakarta Expression Language expression, in which case these arguments are used for method selection,
-     * and this parameter is ignored.
-     * 
-     * @return The parsed expression
-     * 
-     * @throws ELException Thrown if there are syntactical errors in the provided expression.
-     * @throws NullPointerException if paramTypes is <code>null</code>.
-     */
-    public abstract MethodExpression createMethodExpression(ELContext context, String expression, Class<?> expectedReturnType, Class<?>[] expectedParamTypes);
-
-    /**
-     * Coerces an object to a specific type according to the Jakarta Expression Language type conversion rules. The custom
-     * type conversions in the <code>ELResolver</code>s are not considered.
-     *
-     * <p>
-     * An <code>ELException</code> is thrown if an error results from applying the conversion rules.
-     *
-     * @param obj The object to coerce.
-     * @param targetType The target type for the coercion.
-     * 
-     * @return an object coerced to <code>targetType</code>
-     * 
-     * @throws ELException thrown if an error results from applying the conversion rules.
-     */
-    public abstract Object coerceToType(Object obj, Class<?> targetType);
-
-    /**
-     * Retrieves an ELResolver that implements the operations in collections.
-     *
-     * <p>
-     * This ELResolver resolves the method invocation on the pair (<code>base</code>, <code>property</code>) when
-     * <code>base</code> is a <code>Collection</code> or a <code>Map</code>, and <code>property</code> is the name of the
-     * operation.
-     * 
-     * <p>
-     * See the specification document for detailed descriptions of these operators, their arguments, and return values.
-     *
-     * @return The <code>ELResolver</code> that implements the Query Operators.
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    public ELResolver getStreamELResolver() {
-        return null;
-    }
-
-    /**
-     * Retrieve a function map containing a pre-configured function mapping.
-     *
-     * @return A initial map for functions, null if there is none.
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    public Map<String, Method> getInitFunctionMap() {
-        return null;
-    }
-}
diff --git a/api/src/main/java/javax/el/FactoryFinder.java b/api/src/main/java/javax/el/FactoryFinder.java
deleted file mode 100644
index 273ab22..0000000
--- a/api/src/main/java/javax/el/FactoryFinder.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import static java.io.File.separator;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.reflect.Constructor;
-import java.util.Properties;
-
-class FactoryFinder {
-
-    /**
-     * Creates an instance of the specified class using the specified <code>ClassLoader</code> object.
-     *
-     * @exception ELException if the given class could not be found or could not be instantiated
-     */
-    private static Object newInstance(String className, ClassLoader classLoader, Properties properties) {
-        try {
-            Class<?> spiClass;
-            if (classLoader == null) {
-                spiClass = Class.forName(className);
-            } else {
-                spiClass = classLoader.loadClass(className);
-            }
-
-            if (properties != null) {
-                Constructor<?> constr = null;
-                try {
-                    constr = spiClass.getConstructor(Properties.class);
-                } catch (Exception ex) {
-                }
-
-                if (constr != null) {
-                    return constr.newInstance(properties);
-                }
-            }
-            return spiClass.newInstance();
-        } catch (ClassNotFoundException x) {
-            throw new ELException("Provider " + className + " not found", x);
-        } catch (Exception x) {
-            throw new ELException("Provider " + className + " could not be instantiated: " + x, x);
-        }
-    }
-
-    /**
-     * Finds the implementation <code>Class</code> object for the given factory name, or if that fails, finds the
-     * <code>Class</code> object for the given fallback class name. The arguments supplied must be used in order. If using
-     * the first argument is successful, the second one will not be used.
-     * <P>
-     * This method is package private so that this code can be shared.
-     *
-     * @return the <code>Class</code> object of the specified message factory; may not be <code>null</code>
-     *
-     * @param factoryId the name of the factory to find, which is a system property
-     * @param fallbackClassName the implementation class name, which is to be used only if nothing else is found;
-     * <code>null</code> to indicate that there is no fallback class name
-     * @exception ELException if there is an error
-     */
-    static Object find(String factoryId, String fallbackClassName, Properties properties) {
-        ClassLoader classLoader;
-        try {
-            classLoader = Thread.currentThread().getContextClassLoader();
-        } catch (Exception x) {
-            throw new ELException(x.toString(), x);
-        }
-
-        String serviceId = "META-INF/services/" + factoryId;
-
-        // try to find services in CLASSPATH
-        try {
-            InputStream is = null;
-            if (classLoader == null) {
-                is = ClassLoader.getSystemResourceAsStream(serviceId);
-            } else {
-                is = classLoader.getResourceAsStream(serviceId);
-            }
-
-            if (is != null) {
-                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
-
-                String factoryClassName = reader.readLine();
-                reader.close();
-
-                if (factoryClassName != null && !"".equals(factoryClassName)) {
-                    return newInstance(factoryClassName, classLoader, properties);
-                }
-            }
-        } catch (Exception ex) {
-        }
-
-        // Try to read from $java.home/lib/el.properties
-        try {
-            String javah = System.getProperty("java.home");
-            String configFileName = javah + separator + "lib" + separator + "el.properties";
-
-            File configFile = new File(configFileName);
-            if (configFile.exists()) {
-                Properties props = new Properties();
-                props.load(new FileInputStream(configFile));
-                String factoryClassName = props.getProperty(factoryId);
-
-                return newInstance(factoryClassName, classLoader, properties);
-            }
-        } catch (Exception ex) {
-        }
-
-        // Use the system property
-        try {
-            String systemProp = System.getProperty(factoryId);
-            if (systemProp != null) {
-                return newInstance(systemProp, classLoader, properties);
-            }
-        } catch (SecurityException se) {
-        }
-
-        if (fallbackClassName == null) {
-            throw new ELException("Provider for " + factoryId + " cannot be found", null);
-        }
-
-        return newInstance(fallbackClassName, classLoader, properties);
-    }
-}
diff --git a/api/src/main/java/javax/el/FunctionMapper.java b/api/src/main/java/javax/el/FunctionMapper.java
deleted file mode 100644
index 36e76a7..0000000
--- a/api/src/main/java/javax/el/FunctionMapper.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.lang.reflect.Method;
-
-/**
- * The interface to a map between Jakarta Expression Language function names and methods.
- *
- * <p>
- * A <code>FunctionMapper</code> maps <code>${prefix:name()}</code> style functions to a static method that can execute
- * that function.
- *
- * @since Jakarta Server Pages 2.1
- */
-public abstract class FunctionMapper {
-
-    /**
-     * Resolves the specified prefix and local name into a <code>java.lang.Method</code>.
-     *
-     * <p>
-     * Returns <code>null</code> if no function could be found that matches the given prefix and local name.
-     * </p>
-     *
-     * @param prefix the prefix of the function, or "" if no prefix. For example, <code>"fn"</code> in
-     * <code>${fn:method()}</code>, or <code>""</code> in <code>${method()}</code>.
-     * @param localName the short name of the function. For example, <code>"method"</code> in <code>${fn:method()}</code>.
-     * @return the static method to invoke, or <code>null</code> if no match was found.
-     */
-    public abstract Method resolveFunction(String prefix, String localName);
-
-    /**
-     * Adds a static method that can be used as a function.
-     *
-     * @param prefix the prefix of the function, or "" if no prefix. For example, <code>"fn"</code> in
-     * <code>${fn:method()}</code>, or <code>""</code> in <code>${method()}</code>.
-     * @param localName the short name of the function. For example, <code>"method"</code> in <code>${fn:method()}</code>.
-     * @param meth The static method that is to be invoked, when the function is referenced. The null value causes the
-     * function to be removed from the map.
-     *
-     * @since Jakarta Expression Language 3.0
-     */
-    public void mapFunction(String prefix, String localName, Method meth) {
-    }
-}
diff --git a/api/src/main/java/javax/el/ImportHandler.java b/api/src/main/java/javax/el/ImportHandler.java
deleted file mode 100644
index f81866e..0000000
--- a/api/src/main/java/javax/el/ImportHandler.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-import static java.lang.reflect.Modifier.isAbstract;
-import static java.lang.reflect.Modifier.isInterface;
-import static java.lang.reflect.Modifier.isPublic;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Handles imports of class names and package names. An imported package name implicitly imports all the classes in the
- * package. A class that has been imported can be used without its package name. The name is resolved to its full
- * (package and class) name at evaluation time.
- */
-public class ImportHandler {
-
-    private Map<String, String> classNameMap = new HashMap<>();
-    private Map<String, Class<?>> classMap = new HashMap<>();
-    private Map<String, String> staticNameMap = new HashMap<>();
-    private HashSet<String> notAClass = new HashSet<>();
-    private List<String> packages = new ArrayList<>();
-
-    {
-        importPackage("java.lang");
-    }
-
-    /**
-     * Import a static field or method.
-     *
-     * @param name The static member name, including the full class name, to be imported
-     * @throws ELException if the name does not include a ".".
-     */
-    public void importStatic(String name) throws ELException {
-        int i = name.lastIndexOf('.');
-        if (i <= 0) {
-            throw new ELException("The name " + name + " is not a full static member name");
-        }
-
-        String memberName = name.substring(i + 1);
-        String className = name.substring(0, i);
-
-        staticNameMap.put(memberName, className);
-    }
-
-    /**
-     * Import a class.
-     *
-     * @param name The full class name of the class to be imported
-     * @throws ELException if the name does not include a ".".
-     */
-    public void importClass(String name) throws ELException {
-        int i = name.lastIndexOf('.');
-        if (i <= 0) {
-            throw new ELException("The name " + name + " is not a full class name");
-        }
-
-        String className = name.substring(i + 1);
-
-        classNameMap.put(className, name);
-    }
-
-    /**
-     * Import all the classes in a package.
-     *
-     * @param packageName The package name to be imported
-     */
-    public void importPackage(String packageName) {
-        packages.add(packageName);
-    }
-
-    /**
-     * Resolve a class name.
-     *
-     * @param name The name of the class (without package name) to be resolved.
-     * @return If the class has been imported previously, with {@link #importClass} or {@link #importPackage}, then its
-     * Class instance. Otherwise <code>null</code>.
-     * @throws ELException if the class is abstract or is an interface, or not public.
-     */
-    public Class<?> resolveClass(String name) {
-        String className = classNameMap.get(name);
-        if (className != null) {
-            return resolveClassFor(className);
-        }
-
-        for (String packageName : packages) {
-            String fullClassName = packageName + "." + name;
-            Class<?> c = resolveClassFor(fullClassName);
-            if (c != null) {
-                classNameMap.put(name, fullClassName);
-                return c;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Resolve a static field or method name.
-     *
-     * @param name The name of the member(without package and class name) to be resolved.
-     * @return If the field or method has been imported previously, with {@link #importStatic}, then the class object
-     * representing the class that declares the static field or method. Otherwise <code>null</code>.
-     * @throws ELException if the class is not public, or is abstract or is an interface.
-     */
-    public Class<?> resolveStatic(String name) {
-        String className = staticNameMap.get(name);
-        if (className != null) {
-            Class<?> c = resolveClassFor(className);
-            if (c != null) {
-                return c;
-            }
-        }
-
-        return null;
-    }
-
-    private Class<?> resolveClassFor(String className) {
-        Class<?> c = classMap.get(className);
-        if (c != null) {
-            return c;
-        }
-
-        c = getClassFor(className);
-        if (c != null) {
-            checkModifiers(c.getModifiers());
-            classMap.put(className, c);
-        }
-
-        return c;
-    }
-
-    private Class<?> getClassFor(String className) {
-        if (!notAClass.contains(className)) {
-            try {
-                return Class.forName(className, false, Thread.currentThread().getContextClassLoader());
-            } catch (ClassNotFoundException ex) {
-                notAClass.add(className);
-            }
-        }
-
-        return null;
-    }
-
-    private void checkModifiers(int modifiers) {
-        if (isAbstract(modifiers) || isInterface(modifiers) || !isPublic((modifiers))) {
-            throw new ELException("Imported class must be public, and cannot be abstract or an interface");
-        }
-    }
-}
diff --git a/api/src/main/java/javax/el/LambdaExpression.java b/api/src/main/java/javax/el/LambdaExpression.java
deleted file mode 100644
index 540be11..0000000
--- a/api/src/main/java/javax/el/LambdaExpression.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Encapsulates a parameterized {@link ValueExpression}.
- *
- * <p>
- * A <code>LambdaExpression</code> is a representation of the Jakarta Expression Language Lambda expression syntax. It
- * consists of a list of the formal parameters and a body, represented by a {@link ValueExpression}. The body can be any
- * valid <code>Expression</code>, including another <code>LambdaExpression</code>.
- *
- * <p>
- * A <code>LambdaExpression</code> is created when an Jakarta Expression Language expression containing a Lambda
- * expression is evaluated.
- *
- * <p>
- * A <code>LambdaExpression</code> can be invoked by calling {@link LambdaExpression#invoke}, with an
- * {@link javax.el.ELContext} and a list of the actual arguments. Alternately, a <code>LambdaExpression</code> can be
- * invoked without passing a <code>ELContext</code>, in which case the <code>ELContext</code> previously set by calling
- * {@link LambdaExpression#setELContext} will be used. The evaluation of the <code>ValueExpression</code> in the body
- * uses the {@link ELContext} to resolve references to the parameters, and to evaluate the lambda expression. The result
- * of the evaluation is returned.
- *
- * @see ELContext#getLambdaArgument
- * @see ELContext#enterLambdaScope
- * @see ELContext#exitLambdaScope
- */
-public class LambdaExpression {
-
-    private List<String> formalParameters = new ArrayList<>();
-    private ValueExpression expression;
-    private ELContext context;
-    // Arguments from nesting lambdas, when the body is another lambda
-    private Map<String, Object> envirArgs;
-
-    /**
-     * Creates a new LambdaExpression.
-     *
-     * @param formalParameters The list of String representing the formal parameters.
-     * @param expression The <code>ValueExpression</code> representing the body.
-     */
-    public LambdaExpression(List<String> formalParameters, ValueExpression expression) {
-        this.formalParameters = formalParameters;
-        this.expression = expression;
-        this.envirArgs = new HashMap<>();
-    }
-
-    /**
-     * 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 {@link LambdaExpression#invoke}.
-     *
-     * @param context The ELContext to use in evaluating the LambdaExpression.
-     */
-    public void setELContext(ELContext context) {
-        this.context = context;
-    }
-
-    /**
-     * Invoke the encapsulated Lambda expression.
-     * <p>
-     * 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
-     * <code>ELException</code> is thrown.
-     * </p>
-     *
-     * <p>
-     * 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.
-     * </p>
-     *
-     * @param elContext The ELContext used for the evaluation of the expression The ELContext set by {@link #setELContext}
-     * is ignored.
-     * @param args The arguments to invoke the Lambda expression. For calls with no arguments, an empty array must be
-     * provided. A Lambda argument can be <code>null</code>.
-     * @return The result of invoking the Lambda expression
-     * @throws ELException if not enough arguments are provided
-     * @throws NullPointerException is elContext is null
-     */
-    public Object invoke(ELContext elContext, Object... args) throws ELException {
-        int i = 0;
-        Map<String, Object> lambdaArgs = new HashMap<>();
-
-        // First get arguments injected from the outter lambda, if any
-        lambdaArgs.putAll(envirArgs);
-
-        for (String fParam : formalParameters) {
-            if (i >= args.length) {
-                throw new ELException("Expected Argument " + fParam + " missing in Lambda Expression");
-            }
-            lambdaArgs.put(fParam, args[i++]);
-        }
-
-        elContext.enterLambdaScope(lambdaArgs);
-        Object ret = expression.getValue(elContext);
-
-        // If the result of evaluating the body is another LambdaExpression,
-        // whose body has not been evaluated yet. (A LambdaExpression is
-        // evaluated iff when its invoke method is called.) The current lambda
-        // arguments may be needed in that body when it is evaluated later,
-        // after the current lambda exits. To make these arguments available
-        // then, they are injected into it.
-        if (ret instanceof LambdaExpression) {
-            ((LambdaExpression) ret).envirArgs.putAll(lambdaArgs);
-        }
-        elContext.exitLambdaScope();
-
-        return ret;
-    }
-
-    /**
-     * Invoke the encapsulated Lambda expression.
-     * <p>
-     * 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
-     * <code>ELException</code> is thrown.
-     * </p>
-     *
-     * <p>
-     * 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.
-     * </p>
-     *
-     * The ELContext set by {@link LambdaExpression#setELContext} is used in the evaluation of the lambda Expression.
-     *
-     * @param args The arguments to invoke the Lambda expression. For calls with no arguments, an empty array must be
-     * provided. A Lambda argument can be <code>null</code>.
-     * @return The result of invoking the Lambda expression
-     * @throws ELException if not enough arguments are provided
-     */
-    public Object invoke(Object... args) {
-        return invoke(context, args);
-    }
-}
diff --git a/api/src/main/java/javax/el/ListELResolver.java b/api/src/main/java/javax/el/ListELResolver.java
deleted file mode 100644
index 4cd3a2e..0000000
--- a/api/src/main/java/javax/el/ListELResolver.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import java.beans.FeatureDescriptor;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Defines property resolution behavior on instances of {@link java.util.List}.
- *
- * <p>
- * This resolver handles base objects of type <code>java.util.List</code>. It accepts any object as a property and
- * coerces that object into an integer index into the list. The resulting value is the value in the list at that index.
- * </p>
- *
- * <p>
- * This resolver can be constructed in read-only mode, which means that {@link #isReadOnly} will always return
- * <code>true</code> and {@link #setValue} will always throw <code>PropertyNotWritableException</code>.
- * </p>
- *
- * <p>
- * <code>ELResolver</code>s are combined together using {@link CompositeELResolver}s, to define rich semantics for
- * evaluating an expression. See the javadocs for {@link ELResolver} for details.
- * </p>
- *
- * @see CompositeELResolver
- * @see ELResolver
- * @see java.util.List
- * @since Jakarta Server Pages 2.1
- */
-public class ListELResolver extends ELResolver {
-
-    static private Class<?> theUnmodifiableListClass = Collections.unmodifiableList(new ArrayList<>()).getClass();
-    private boolean isReadOnly;
-
-    /**
-     * Creates a new read/write <code>ListELResolver</code>.
-     */
-    public ListELResolver() {
-        isReadOnly = false;
-    }
-
-    /**
-     * Creates a new <code>ListELResolver</code> whose read-only status is determined by the given parameter.
-     *
-     * @param isReadOnly <code>true</code> if this resolver cannot modify lists; <code>false</code> otherwise.
-     */
-    public ListELResolver(boolean isReadOnly) {
-        this.isReadOnly = isReadOnly;
-    }
-
-    /**
-     * If the base object is a list, returns the most general acceptable type for a value in this list.
-     *
-     * <p>
-     * If the base is a <code>List</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * Assuming the base is a <code>List</code>, this method will always return <code>Object.class</code>. This is because
-     * <code>List</code>s accept any object as an element.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The list to analyze. Only bases of type <code>List</code> are handled by this resolver.
-     * @param property The index of the element in the list to return the acceptable type for. Will be coerced into an
-     * integer, but otherwise ignored by this resolver.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the most general acceptable type; otherwise undefined.
-     * @throws PropertyNotFoundException if the given index is out of bounds for this list.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws ELException 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.
-     */
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base instanceof List) {
-            context.setPropertyResolved(true);
-            List<?> list = (List<?>) base;
-            int index = toInteger(property);
-            if (index < 0 || index >= list.size()) {
-                throw new PropertyNotFoundException();
-            }
-
-            return Object.class;
-        }
-
-        return null;
-    }
-
-    /**
-     * If the base object is a list, returns the value at the given index. The index is specified by the
-     * <code>property</code> argument, and coerced into an integer. If the coercion could not be performed, an
-     * <code>IllegalArgumentException</code> is thrown. If the index is out of bounds, <code>null</code> is returned.
-     *
-     * <p>
-     * If the base is a <code>List</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The list to be analyzed. Only bases of type <code>List</code> are handled by this resolver.
-     * @param property The index of the value to be returned. Will be coerced into an integer.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the value at the given index or <code>null</code> if the index was out of bounds. Otherwise, undefined.
-     * @throws IllegalArgumentException if the property could not be coerced into an integer.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws ELException 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.
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base instanceof List) {
-            context.setPropertyResolved(base, property);
-            List<?> list = (List<?>) base;
-            int index = toInteger(property);
-            if (index < 0 || index >= list.size()) {
-                return null;
-            }
-
-            return list.get(index);
-        }
-
-        return null;
-    }
-
-    /**
-     * 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 <code>property</code> argument, and coerced into an integer. If the coercion could not be performed,
-     * an <code>IllegalArgumentException</code> is thrown. If the index is out of bounds, a
-     * <code>PropertyNotFoundException</code> is thrown.
-     *
-     * <p>
-     * If the base is a <code>List</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller can safely assume no value was set.
-     * </p>
-     *
-     * <p>
-     * If this resolver was constructed in read-only mode, this method will always throw
-     * <code>PropertyNotWritableException</code>.
-     * </p>
-     *
-     * <p>
-     * If a <code>List</code> was created using {@link java.util.Collections#unmodifiableList}, this method must throw
-     * <code>PropertyNotWritableException</code>. Unfortunately, there is no Collections API method to detect this. However,
-     * an implementation can create a prototype unmodifiable <code>List</code> and query its runtime type to see if it
-     * matches the runtime type of the base object as a workaround.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The list to be modified. Only bases of type <code>List</code> are handled by this resolver.
-     * @param property The index of the value to be set. Will be coerced into an integer.
-     * @param val The value to be set at the given index.
-     * @throws ClassCastException if the class of the specified element prevents it from being added to this list.
-     * @throws NullPointerException if context is <code>null</code>, or if the value is <code>null</code> and this
-     * <code>List</code> does not support <code>null</code> elements.
-     * @throws IllegalArgumentException 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.
-     * @throws PropertyNotWritableException if this resolver was constructed in read-only mode, or if the set operation is
-     * not supported by the underlying list.
-     * @throws PropertyNotFoundException if the given index is out of bounds for this list.
-     * @throws ELException 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.
-     */
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object val) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base instanceof List) {
-            context.setPropertyResolved(base, property);
-            // Safe cast
-            @SuppressWarnings("unchecked")
-            List<Object> list = (List<Object>) base;
-            int index = toInteger(property);
-            if (isReadOnly) {
-                throw new PropertyNotWritableException();
-            }
-
-            try {
-                list.set(index, val);
-            } catch (UnsupportedOperationException ex) {
-                throw new PropertyNotWritableException();
-            } catch (IndexOutOfBoundsException ex) {
-                throw new PropertyNotFoundException();
-            } catch (ClassCastException ex) {
-                throw ex;
-            } catch (NullPointerException ex) {
-                throw ex;
-            } catch (IllegalArgumentException ex) {
-                throw ex;
-            }
-        }
-    }
-
-    /**
-     * If the base object is a list, returns whether a call to {@link #setValue} will always fail.
-     *
-     * <p>
-     * If the base is a <code>List</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * If this resolver was constructed in read-only mode, this method will always return <code>true</code>.
-     * </p>
-     *
-     * <p>
-     * If a <code>List</code> was created using {@link java.util.Collections#unmodifiableList}, this method must return
-     * <code>true</code>. Unfortunately, there is no Collections API method to detect this. However, an implementation can
-     * create a prototype unmodifiable <code>List</code> and query its runtime type to see if it matches the runtime type of
-     * the base object as a workaround.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The list to analyze. Only bases of type <code>List</code> are handled by this resolver.
-     * @param property The index of the element in the list to return the acceptable type for. Will be coerced into an
-     * integer, but otherwise ignored by this resolver.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>true</code> if calling the <code>setValue</code> method will always fail or <code>false</code> if it is
-     * possible that such a call may succeed; otherwise undefined.
-     * @throws PropertyNotFoundException if the given index is out of bounds for this list.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws ELException 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.
-     */
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base instanceof List) {
-            context.setPropertyResolved(true);
-            List<?> list = (List<?>) base;
-            int index = toInteger(property);
-            if (index < 0 || index >= list.size()) {
-                throw new PropertyNotFoundException();
-            }
-
-            return list.getClass() == theUnmodifiableListClass || isReadOnly;
-        }
-
-        return false;
-    }
-
-    /**
-     * Always returns <code>null</code>, since there is no reason to iterate through set set of all integers.
-     *
-     * <p>
-     * The {@link #getCommonPropertyType} method returns sufficient information about what properties this resolver accepts.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The list. Only bases of type <code>List</code> are handled by this resolver.
-     * @return <code>null</code>.
-     */
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        return null;
-    }
-
-    /**
-     * If the base object is a list, returns the most general type that this resolver accepts for the <code>property</code>
-     * argument. Otherwise, returns <code>null</code>.
-     *
-     * <p>
-     * Assuming the base is a <code>List</code>, this method will always return <code>Integer.class</code>. This is because
-     * <code>List</code>s accept integers as their index.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The list to analyze. Only bases of type <code>List</code> are handled by this resolver.
-     * @return <code>null</code> if base is not a <code>List</code>; otherwise <code>Integer.class</code>.
-     */
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        if (base != null && base instanceof List) {
-            return Integer.class;
-        }
-
-        return null;
-    }
-
-    private int toInteger(Object p) {
-        if (p instanceof Integer) {
-            return ((Integer) p).intValue();
-        }
-        if (p instanceof Character) {
-            return ((Character) p).charValue();
-        }
-        if (p instanceof Number) {
-            return ((Number) p).intValue();
-        }
-        if (p instanceof String) {
-            return Integer.parseInt((String) p);
-        }
-        throw new IllegalArgumentException();
-    }
-}
diff --git a/api/src/main/java/javax/el/MapELResolver.java b/api/src/main/java/javax/el/MapELResolver.java
deleted file mode 100644
index cca84f2..0000000
--- a/api/src/main/java/javax/el/MapELResolver.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import static java.lang.Boolean.TRUE;
-
-import java.beans.FeatureDescriptor;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Defines property resolution behavior on instances of {@link java.util.Map}.
- *
- * <p>
- * This resolver handles base objects of type <code>java.util.Map</code>. It accepts any object as a property and uses
- * that object as a key in the map. The resulting value is the value in the map that is associated with that key.
- * </p>
- *
- * <p>
- * This resolver can be constructed in read-only mode, which means that {@link #isReadOnly} will always return
- * <code>true</code> and {@link #setValue} will always throw <code>PropertyNotWritableException</code>.
- * </p>
- *
- * <p>
- * <code>ELResolver</code>s are combined together using {@link CompositeELResolver}s, to define rich semantics for
- * evaluating an expression. See the javadocs for {@link ELResolver} for details.
- * </p>
- *
- * @see CompositeELResolver
- * @see ELResolver
- * @see java.util.Map
- * @since Jakarta Server Pages 2.1
- */
-public class MapELResolver extends ELResolver {
-
-    static private Class<?> theUnmodifiableMapClass = Collections.unmodifiableMap(new HashMap<>()).getClass();
-    private boolean isReadOnly;
-
-    /**
-     * Creates a new read/write <code>MapELResolver</code>.
-     */
-    public MapELResolver() {
-        isReadOnly = false;
-    }
-
-    /**
-     * Creates a new <code>MapELResolver</code> whose read-only status is determined by the given parameter.
-     *
-     * @param isReadOnly <code>true</code> if this resolver cannot modify maps; <code>false</code> otherwise.
-     */
-    public MapELResolver(boolean isReadOnly) {
-        this.isReadOnly = isReadOnly;
-    }
-
-    /**
-     * If the base object is a map, returns the most general acceptable type for a value in this map.
-     *
-     * <p>
-     * If the base is a <code>Map</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * Assuming the base is a <code>Map</code>, this method will always return <code>Object.class</code>. This is because
-     * <code>Map</code>s accept any object as the value for a given key.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The map to analyze. Only bases of type <code>Map</code> are handled by this resolver.
-     * @param property The key to return the acceptable type for. Ignored by this resolver.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the most general acceptable type; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws ELException 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.
-     */
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base instanceof Map) {
-            context.setPropertyResolved(true);
-            return Object.class;
-        }
-
-        return null;
-    }
-
-    /**
-     * If the base object is a map, returns the value associated with the given key, as specified by the
-     * <code>property</code> argument. If the key was not found, <code>null</code> is returned.
-     *
-     * <p>
-     * If the base is a <code>Map</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * Just as in {@link java.util.Map#get}, just because <code>null</code> is returned doesn't mean there is no mapping for
-     * the key; it's also possible that the <code>Map</code> explicitly maps the key to <code>null</code>.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The map to be analyzed. Only bases of type <code>Map</code> are handled by this resolver.
-     * @param property The key whose associated value is to be returned.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the value associated with the given key or <code>null</code> if the key was not found. Otherwise, undefined.
-     * @throws ClassCastException if the key is of an inappropriate type for this map (optionally thrown by the underlying
-     * <code>Map</code>).
-     * @throws NullPointerException if context is <code>null</code>, or if the key is null and this map does not permit null
-     * keys (the latter is optionally thrown by the underlying <code>Map</code>).
-     * @throws ELException 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.
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base instanceof Map) {
-            context.setPropertyResolved(base, property);
-            Map<?, ?> map = (Map<?, ?>) base;
-            return map.get(property);
-        }
-
-        return null;
-    }
-
-    /**
-     * If the base object is a map, attempts to set the value associated with the given key, as specified by the
-     * <code>property</code> argument.
-     *
-     * <p>
-     * If the base is a <code>Map</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller can safely assume no value was set.
-     * </p>
-     *
-     * <p>
-     * If this resolver was constructed in read-only mode, this method will always throw
-     * <code>PropertyNotWritableException</code>.
-     * </p>
-     *
-     * <p>
-     * If a <code>Map</code> was created using {@link java.util.Collections#unmodifiableMap}, this method must throw
-     * <code>PropertyNotWritableException</code>. Unfortunately, there is no Collections API method to detect this. However,
-     * an implementation can create a prototype unmodifiable <code>Map</code> and query its runtime type to see if it
-     * matches the runtime type of the base object as a workaround.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The map to be modified. Only bases of type <code>Map</code> are handled by this resolver.
-     * @param property The key with which the specified value is to be associated.
-     * @param val The value to be associated with the specified key.
-     * @throws ClassCastException if the class of the specified key or value prevents it from being stored in this map.
-     * @throws NullPointerException if context is <code>null</code>, or if this map does not permit <code>null</code> keys
-     * or values, and the specified key or value is <code>null</code>.
-     * @throws IllegalArgumentException if some aspect of this key or value prevents it from being stored in this map.
-     * @throws ELException 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.
-     * @throws PropertyNotWritableException if this resolver was constructed in read-only mode, or if the put operation is
-     * not supported by the underlying map.
-     */
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object val) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base instanceof Map) {
-            context.setPropertyResolved(base, property);
-
-            // The cast is safe
-            @SuppressWarnings("unchecked")
-            Map<Object, Object> map = (Map<Object, Object>) base;
-            if (isReadOnly || map.getClass() == theUnmodifiableMapClass) {
-                throw new PropertyNotWritableException();
-            }
-
-            try {
-                map.put(property, val);
-            } catch (UnsupportedOperationException ex) {
-                throw new PropertyNotWritableException();
-            }
-        }
-    }
-
-    /**
-     * If the base object is a map, returns whether a call to {@link #setValue} will always fail.
-     *
-     * <p>
-     * If the base is a <code>Map</code>, the <code>propertyResolved</code> property of the <code>ELContext</code> object
-     * must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
-     * this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * <p>
-     * If this resolver was constructed in read-only mode, this method will always return <code>true</code>.
-     * </p>
-     *
-     * <p>
-     * If a <code>Map</code> was created using {@link java.util.Collections#unmodifiableMap}, this method must return
-     * <code>true</code>. Unfortunately, there is no Collections API method to detect this. However, an implementation can
-     * create a prototype unmodifiable <code>Map</code> and query its runtime type to see if it matches the runtime type of
-     * the base object as a workaround.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The map to analyze. Only bases of type <code>Map</code> are handled by this resolver.
-     * @param property The key to return the read-only status for. Ignored by this resolver.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>true</code> if calling the <code>setValue</code> method will always fail or <code>false</code> if it is
-     * possible that such a call may succeed; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws ELException 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.
-     */
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base != null && base instanceof Map) {
-            context.setPropertyResolved(true);
-            Map<?, ?> map = (Map<?, ?>) base;
-            return isReadOnly || map.getClass() == theUnmodifiableMapClass;
-        }
-
-        return false;
-    }
-
-    /**
-     * If the base object is a map, returns an <code>Iterator</code> containing the set of keys available in the
-     * <code>Map</code>. Otherwise, returns <code>null</code>.
-     *
-     * <p>
-     * The <code>Iterator</code> returned must contain zero or more instances of {@link java.beans.FeatureDescriptor}. Each
-     * info object contains information about a key in the Map, and is initialized as follows:
-     * <ul>
-     * <li>displayName - The return value of calling the <code>toString</code> method on this key, or <code>"null"</code> if
-     * the key is <code>null</code>.</li>
-     * <li>name - Same as displayName property.</li>
-     * <li>shortDescription - Empty string</li>
-     * <li>expert - <code>false</code></li>
-     * <li>hidden - <code>false</code></li>
-     * <li>preferred - <code>true</code></li>
-     * </ul>
-     *
-     * In addition, the following named attributes must be set in the returned <code>FeatureDescriptor</code>s:
-     * <ul>
-     * <li>{@link ELResolver#TYPE} - The return value of calling the <code>getClass()</code> method on this key, or
-     * <code>null</code> if the key is <code>null</code>.</li>
-     * <li>{@link ELResolver#RESOLVABLE_AT_DESIGN_TIME} - <code>true</code></li>
-     * </ul>
-     *
-     *
-     * @param context The context of this evaluation.
-     * @param base The map whose keys are to be iterated over. Only bases of type <code>Map</code> are handled by this
-     * resolver.
-     * @return An <code>Iterator</code> containing zero or more (possibly infinitely more) <code>FeatureDescriptor</code>
-     * objects, each representing a key in this map, or <code>null</code> if the base object is not a map.
-     */
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        if (base != null && base instanceof Map) {
-            Map<?, ?> map = (Map<?, ?>) base;
-            Iterator<?> iter = map.keySet().iterator();
-            List<FeatureDescriptor> list = new ArrayList<>();
-
-            while (iter.hasNext()) {
-                Object key = iter.next();
-                FeatureDescriptor descriptor = new FeatureDescriptor();
-                String name = key == null ? null : key.toString();
-                descriptor.setName(name);
-                descriptor.setDisplayName(name);
-                descriptor.setShortDescription("");
-                descriptor.setExpert(false);
-                descriptor.setHidden(false);
-                descriptor.setPreferred(true);
-
-                if (key != null) {
-                    descriptor.setValue("type", key.getClass());
-                }
-
-                descriptor.setValue("resolvableAtDesignTime", TRUE);
-                list.add(descriptor);
-            }
-
-            return list.iterator();
-        }
-
-        return null;
-    }
-
-    /**
-     * If the base object is a map, returns the most general type that this resolver accepts for the <code>property</code>
-     * argument. Otherwise, returns <code>null</code>.
-     *
-     * <p>
-     * Assuming the base is a <code>Map</code>, this method will always return <code>Object.class</code>. This is because
-     * <code>Map</code>s accept any object as a key.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The map to analyze. Only bases of type <code>Map</code> are handled by this resolver.
-     * @return <code>null</code> if base is not a <code>Map</code>; otherwise <code>Object.class</code>.
-     */
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        if (base != null && base instanceof Map) {
-            return Object.class;
-        }
-
-        return null;
-    }
-
-}
diff --git a/api/src/main/java/javax/el/MethodExpression.java b/api/src/main/java/javax/el/MethodExpression.java
deleted file mode 100644
index 38b02e5..0000000
--- a/api/src/main/java/javax/el/MethodExpression.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * An <code>Expression</code> that refers to a method on an object.
- *
- * <p>
- * The {@link javax.el.ExpressionFactory#createMethodExpression} method can be used to parse an expression string and
- * return a concrete instance of <code>MethodExpression</code> that encapsulates the parsed expression. The
- * {@link FunctionMapper} is used at parse time, not evaluation time, so one is not needed to evaluate an expression
- * using this class. However, the {@link ELContext} is needed at evaluation time.
- * </p>
- *
- * <p>
- * The {@link #getMethodInfo} and {@link #invoke} methods will evaluate the expression each time they are called. The
- * {@link ELResolver} in the <code>ELContext</code> is used to resolve the top-level variables and to determine the
- * behavior of the <code>.</code> and <code>[]</code> operators. For any of the two methods, the
- * {@link javax.el.ELResolver#getValue} method is used to resolve all properties up to but excluding the last one. This
- * provides the <code>base</code> object on which the method appears. If the <code>base</code> object is null, a
- * <code>PropertyNotFoundException</code> must be thrown. At the last resolution, the final <code>property</code> is
- * then coerced to a <code>String</code>, which provides the name of the method to be found. A method matching the name
- * and expected parameters provided at parse time is found and it is either queried or invoked (depending on the method
- * called on this <code>MethodExpression</code>).
- * </p>
- *
- * <p>
- * See the notes about comparison, serialization and immutability in the {@link Expression} javadocs.
- *
- * @see ELResolver
- * @see Expression
- * @see ExpressionFactory
- * @since Jakarta Server Pages 2.1
- */
-public abstract class MethodExpression extends Expression {
-
-    private static final long serialVersionUID = -1151639017737837708L;
-
-    // Evaluation
-
-    /**
-     * Evaluates the expression relative to the provided context, and returns information about the actual referenced
-     * method.
-     *
-     * @param context The context of this evaluation
-     * @return an instance of <code>MethodInfo</code> containing information about the method the expression evaluated to.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws MethodNotFoundException if no suitable method can be found.
-     * @throws ELException 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.
-     */
-    public abstract MethodInfo getMethodInfo(ELContext context);
-
-    /**
-     * If a String literal is specified as the expression, returns the String literal coerced to the expected return type of
-     * the method signature. An <code>ELException</code> is thrown if <code>expectedReturnType</code> is void or if the
-     * coercion of the String literal to the <code>expectedReturnType</code> yields an error (see Section "1.18 Type
-     * Conversion" of the Jakarta Expression Language 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.
-     *
-     * @param context The context of this evaluation.
-     * @param params The parameters to pass to the method, or <code>null</code> if no parameters.
-     * @return the result of the method invocation (<code>null</code> if the method has a <code>void</code> return type).
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws MethodNotFoundException if no suitable method can be found.
-     * @throws ELException 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").
-     * @throws ELException 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
-     * <code>InvocationTargetException</code>, extract its <code>cause</code> and pass it to the <code>ELException</code>
-     * constructor.
-     */
-    public abstract Object invoke(ELContext context, Object[] params);
-
-    /**
-     * Return whether this MethodExpression was created with parameters.
-     *
-     * <p>
-     * This method must return <code>true</code> if and only if parameters are specified in the EL, using the
-     * expr-a.expr-b(...) syntax.
-     *
-     * @return <code>true</code> if the MethodExpression was created with parameters, <code>false</code> otherwise.
-     * 
-     * @since Jakarta Expression Language 2.2
-     */
-    public boolean isParametersProvided() {
-        return false;
-    }
-
-    /**
-     * Use isParametersProvided instead.
-     *
-     * @return <code>true</code> if the MethodExpression was created with parameters, <code>false</code> otherwise.
-     */
-    @Deprecated
-    public boolean isParmetersProvided() {
-        return isParametersProvided();
-    }
-}
diff --git a/api/src/main/java/javax/el/MethodInfo.java b/api/src/main/java/javax/el/MethodInfo.java
deleted file mode 100644
index b79f077..0000000
--- a/api/src/main/java/javax/el/MethodInfo.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * Holds information about a method that a {@link MethodExpression} evaluated to.
- *
- * @since Jakarta Server Pages 2.1
- */
-public class MethodInfo {
-
-    private String name;
-    private Class<?> returnType;
-    private Class<?>[] paramTypes;
-
-    /**
-     * Creates a new instance of <code>MethodInfo</code> with the given information.
-     *
-     * @param name The name of the method
-     * @param returnType The return type of the method
-     * @param paramTypes The types of each of the method's parameters
-     */
-    public MethodInfo(String name, Class<?> returnType, Class<?>[] paramTypes) {
-        this.name = name;
-        this.returnType = returnType;
-        this.paramTypes = paramTypes;
-    }
-
-    /**
-     * Returns the name of the method
-     *
-     * @return the name of the method
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the return type of the method
-     *
-     * @return the return type of the method
-     */
-    public Class<?> getReturnType() {
-        return returnType;
-    }
-
-    /**
-     * Returns the parameter types of the method
-     *
-     * @return the parameter types of the method
-     */
-    public Class<?>[] getParamTypes() {
-        return paramTypes;
-    }
-
-}
diff --git a/api/src/main/java/javax/el/MethodNotFoundException.java b/api/src/main/java/javax/el/MethodNotFoundException.java
deleted file mode 100644
index a306094..0000000
--- a/api/src/main/java/javax/el/MethodNotFoundException.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * Thrown when a method could not be found while evaluating a {@link MethodExpression}.
- *
- * @see MethodExpression
- * @since Jakarta Server Pages 2.1
- */
-public class MethodNotFoundException extends ELException {
-
-    private static final long serialVersionUID = 7727548537051164640L;
-
-    /**
-     * Creates a <code>MethodNotFoundException</code> with no detail message.
-     */
-    public MethodNotFoundException() {
-        super();
-    }
-
-    /**
-     * Creates a <code>MethodNotFoundException</code> with the provided detail message.
-     *
-     * @param message the detail message
-     */
-    public MethodNotFoundException(String message) {
-        super(message);
-    }
-
-    /**
-     * Creates a <code>MethodNotFoundException</code> with the given root cause.
-     *
-     * @param exception the originating cause of this exception
-     */
-    public MethodNotFoundException(Throwable exception) {
-        super(exception);
-    }
-
-    /**
-     * Creates a <code>MethodNotFoundException</code> with the given detail message and root cause.
-     *
-     * @param pMessage the detail message
-     * @param pRootCause the originating cause of this exception
-     */
-    public MethodNotFoundException(String pMessage, Throwable pRootCause) {
-        super(pMessage, pRootCause);
-    }
-}
diff --git a/api/src/main/java/javax/el/PrivateMessages.properties b/api/src/main/java/javax/el/PrivateMessages.properties
deleted file mode 100644
index e628977..0000000
--- a/api/src/main/java/javax/el/PrivateMessages.properties
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
-# Copyright 2004 The Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# This properties file is essentially "package private" but because
-# there is no way to attach an access specifier to a properties file we
-# are including this comment to serve as such.
-setPropertyFailed=Can''t set property ''{0}'' on class ''{1}'' to value ''{2}''.
-propertyNotFound=The class ''{0}'' does not have the property ''{1}''.
-propertyNotReadable=The class ''{0}'' does not have a readable property ''{1}''.
-resolverNotWritable=The ELResolver for the class ''{0}'' is not writable.
-propertyNotWritable=The class ''{0}'' does not have a writable property ''{1}''.
-staticFieldReadError=Either ''{1}'' is not a public static field of the class ''{0}'' or field is inaccessible
-staticFieldWriteError=Cannot write to the field ''{1}}'' of the class ''{0}''
diff --git a/api/src/main/java/javax/el/PropertyNotFoundException.java b/api/src/main/java/javax/el/PropertyNotFoundException.java
deleted file mode 100644
index 8a829e1..0000000
--- a/api/src/main/java/javax/el/PropertyNotFoundException.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * Thrown when a property could not be found while evaluating a {@link ValueExpression} or {@link MethodExpression}.
- *
- * <p>
- * For example, this could be triggered by an index out of bounds while setting an array value, or by an unreadable
- * property while getting the value of a JavaBeans property.
- * </p>
- *
- * @since Jakarta Server Pages 2.1
- */
-public class PropertyNotFoundException extends ELException {
-
-    private static final long serialVersionUID = 7876728153282609955L;
-
-    // -------------------------------------
-    /**
-     * Creates a <code>PropertyNotFoundException</code> with no detail message.
-     */
-    public PropertyNotFoundException() {
-        super();
-    }
-
-    // -------------------------------------
-    /**
-     * Creates a <code>PropertyNotFoundException</code> with the provided detail message.
-     *
-     * @param message the detail message
-     */
-    public PropertyNotFoundException(String message) {
-        super(message);
-    }
-
-    /**
-     * Creates a <code>PropertyNotFoundException</code> with the given root cause.
-     *
-     * @param exception the originating cause of this exception
-     */
-    public PropertyNotFoundException(Throwable exception) {
-        super(exception);
-    }
-
-    /**
-     * Creates a <code>PropertyNotFoundException</code> with the given detail message and root cause.
-     *
-     * @param pMessage the detail message
-     * @param pRootCause the originating cause of this exception
-     */
-    public PropertyNotFoundException(String pMessage, Throwable pRootCause) {
-        super(pMessage, pRootCause);
-    }
-
-}
diff --git a/api/src/main/java/javax/el/PropertyNotWritableException.java b/api/src/main/java/javax/el/PropertyNotWritableException.java
deleted file mode 100644
index e814168..0000000
--- a/api/src/main/java/javax/el/PropertyNotWritableException.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * Thrown when a property could not be written to while setting the value on a {@link ValueExpression}.
- *
- * <p>
- * For example, this could be triggered by trying to set a map value on an unmodifiable map.
- * </p>
- *
- * @since Jakarta Server Pages 2.1
- */
-public class PropertyNotWritableException extends ELException {
-
-    private static final long serialVersionUID = 4511862414551151572L;
-
-    /**
-     * Creates a <code>PropertyNotWritableException</code> with no detail message.
-     */
-    public PropertyNotWritableException() {
-        super();
-    }
-
-    /**
-     * Creates a <code>PropertyNotWritableException</code> with the provided detail message.
-     *
-     * @param pMessage the detail message
-     */
-    public PropertyNotWritableException(String pMessage) {
-        super(pMessage);
-    }
-
-    /**
-     * Creates a <code>PropertyNotWritableException</code> with the given root cause.
-     *
-     * @param exception the originating cause of this exception
-     */
-    public PropertyNotWritableException(Throwable exception) {
-        super(exception);
-    }
-
-    /**
-     * Creates a <code>PropertyNotWritableException</code> with the given detail message and root cause.
-     *
-     * @param pMessage the detail message
-     * @param pRootCause the originating cause of this exception
-     */
-    public PropertyNotWritableException(String pMessage, Throwable pRootCause) {
-        super(pMessage, pRootCause);
-    }
-
-}
diff --git a/api/src/main/java/javax/el/ResourceBundleELResolver.java b/api/src/main/java/javax/el/ResourceBundleELResolver.java
deleted file mode 100644
index cd5e02f..0000000
--- a/api/src/main/java/javax/el/ResourceBundleELResolver.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-import static java.lang.Boolean.TRUE;
-
-import java.beans.FeatureDescriptor;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-/**
- * Defines property resolution behavior on instances of {@link java.util.ResourceBundle}.
- *
- * <p>
- * This resolver handles base objects of type <code>java.util.ResourceBundle</code>. It accepts any object as a property
- * and coerces it to a <code>java.lang.String</code> for invoking
- * {@link java.util.ResourceBundle#getObject(java.lang.String)}.
- *
- * <p>
- * This resolver is read only and will throw a {@link PropertyNotWritableException} if <code>setValue</code> is called.
- *
- * <p>
- * <code>ELResolver</code>s are combined together using {@link CompositeELResolver}s, to define rich semantics for
- * evaluating an expression. See the javadocs for {@link ELResolver} for details.
- *
- * @see CompositeELResolver
- * @see ELResolver
- * @see java.util.ResourceBundle
- * 
- * @since Jakarta Server Pages 2.1
- */
-public class ResourceBundleELResolver extends ELResolver {
-
-    /**
-     * If the base object is an instance of <code>ResourceBundle</code>, the provided property will first be coerced to a
-     * <code>String</code>. The <code>Object</code> returned by <code>getObject</code> on the base
-     * <code>ResourceBundle</code> will be returned.
-     *
-     * <p>
-     * If the base is <code>ResourceBundle</code>, the <code>propertyResolved</code> property of the <code>ELContext</code>
-     * object must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code>
-     * after this method is called, the caller should ignore the return value.
-     *
-     * @param context The context of this evaluation.
-     * @param base The ResourceBundle to analyze.
-     * @param property The name of the property to analyze. Will be coerced to a <code>String</code>.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>null</code> if property is <code>null</code>; otherwise the <code>Object</code> for the given key (property
-     * coerced to <code>String</code>) from the <code>ResourceBundle</code>. If no object for the given key can be found,
-     * then the <code>String</code> "???" + key + "???".
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws ELException 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.
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof ResourceBundle) {
-            context.setPropertyResolved(true);
-            if (property != null) {
-                try {
-                    return ((ResourceBundle) base).getObject(property.toString());
-                } catch (MissingResourceException e) {
-                    return "???" + property + "???";
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * If the base object is an instance of <code>ResourceBundle</code>, return <code>null</code>, since the resolver is
-     * read only.
-     *
-     * <p>
-     * If the base is <code>ResourceBundle</code>, the <code>propertyResolved</code> property of the <code>ELContext</code>
-     * object must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code>
-     * after this method is called, the caller should ignore the return value.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base The ResourceBundle to analyze.
-     * @param property The name of the property to analyze.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>null</code>; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     */
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof ResourceBundle) {
-            context.setPropertyResolved(true);
-        }
-
-        return null;
-    }
-
-    /**
-     * If the base object is a ResourceBundle, throw a {@link PropertyNotWritableException}.
-     *
-     * @param context The context of this evaluation.
-     * @param base The ResourceBundle to be modified. Only bases that are of type ResourceBundle are handled.
-     * @param property The String property to use.
-     * @param value The value to be set.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotWritableException Always thrown if base is an instance of ReasourceBundle.
-     */
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object value) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof ResourceBundle) {
-            context.setPropertyResolved(true);
-            throw new PropertyNotWritableException("ResourceBundles are immutable");
-        }
-    }
-
-    /**
-     * If the base object is not null and an <code>instanceof</code> {@link ResourceBundle}, return <code>true</code>.
-     *
-     * @param context The context of this evaluation.
-     * @param base The ResourceBundle to be modified. Only bases that are of type ResourceBundle are handled.
-     * @param property The String property to use.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * <code>true</code>; otherwise undefined.
-     * @throws NullPointerException if context is <code>null</code>
-     */
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof ResourceBundle) {
-            context.setPropertyResolved(true);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * If the base object is a ResourceBundle, returns an <code>Iterator</code> containing the set of keys available in the
-     * <code>ResourceBundle</code>. Otherwise, returns <code>null</code>.
-     *
-     * <p>
-     * The <code>Iterator</code> returned must contain zero or more instances of {@link java.beans.FeatureDescriptor}. Each
-     * info object contains information about a key in the ResourceBundle, and is initialized as follows:
-     * <ul>
-     * <li>displayName - The <code>String</code> key
-     * <li>name - Same as displayName property.</li>
-     * <li>shortDescription - Empty string</li>
-     * <li>expert - <code>false</code></li>
-     * <li>hidden - <code>false</code></li>
-     * <li>preferred - <code>true</code></li>
-     * </ul>
-     *
-     * In addition, the following named attributes must be set in the returned <code>FeatureDescriptor</code>s:
-     * <ul>
-     * <li>{@link ELResolver#TYPE} - <code>String.class</code></li>
-     * <li>{@link ELResolver#RESOLVABLE_AT_DESIGN_TIME} - <code>true</code></li>
-     * </ul>
-     *
-     *
-     * @param context The context of this evaluation.
-     * @param base The bundle whose keys are to be iterated over. Only bases of type <code>ResourceBundle</code> are handled
-     * by this resolver.
-     * @return An <code>Iterator</code> containing zero or more (possibly infinitely more) <code>FeatureDescriptor</code>
-     * objects, each representing a key in this bundle, or <code>null</code> if the base object is not a ResourceBundle.
-     */
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        if (base instanceof ResourceBundle) {
-            ResourceBundle bundle = (ResourceBundle) base;
-            List<FeatureDescriptor> features = new ArrayList<>();
-            String key = null;
-            FeatureDescriptor desc = null;
-
-            for (Enumeration<String> e = bundle.getKeys(); e.hasMoreElements();) {
-                key = e.nextElement();
-                desc = new FeatureDescriptor();
-                desc.setDisplayName(key);
-                desc.setExpert(false);
-                desc.setHidden(false);
-                desc.setName(key);
-                desc.setPreferred(true);
-                desc.setValue(TYPE, String.class);
-                desc.setValue(RESOLVABLE_AT_DESIGN_TIME, TRUE);
-                features.add(desc);
-            }
-
-            return features.iterator();
-        }
-
-        return null;
-    }
-
-    /**
-     * If the base object is a ResourceBundle, returns the most general type that this resolver accepts for the
-     * <code>property</code> argument. Otherwise, returns <code>null</code>.
-     *
-     * <p>
-     * Assuming the base is a <code>ResourceBundle</code>, this method will always return <code>String.class</code>.
-     *
-     * @param context The context of this evaluation.
-     * @param base The bundle to analyze. Only bases of type <code>ResourceBundle</code> are handled by this resolver.
-     * @return <code>null</code> if base is not a <code>ResourceBundle</code>; otherwise <code>String.class</code>.
-     */
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        if (base instanceof ResourceBundle) {
-            return String.class;
-        }
-
-        return null;
-    }
-}
diff --git a/api/src/main/java/javax/el/StandardELContext.java b/api/src/main/java/javax/el/StandardELContext.java
deleted file mode 100644
index 1c17be7..0000000
--- a/api/src/main/java/javax/el/StandardELContext.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A standard ELContext suitable for use in a stand alone environment. This class provides a default implementation of
- * an ELResolver that contains a number of useful ELResolvers. It also provides local repositories for the
- * FunctionMapper, VariableMapper, and BeanNameResolver.
- *
- * @since Jakarta Expression Language 3.0
- */
-public class StandardELContext extends ELContext {
-
-    /*
-     * The ELResolver for this ELContext.
-     */
-    private ELResolver elResolver;
-
-    /*
-     * The list of the custom ELResolvers added to the ELResolvers. An ELResolver is added to the list when addELResolver is
-     * called.
-     */
-    private CompositeELResolver customResolvers;
-
-    /*
-     * The ELResolver implementing the query operators.
-     */
-    private ELResolver streamELResolver;
-
-    /*
-     * The FunctionMapper for this ELContext.
-     */
-    private FunctionMapper functionMapper;
-
-    /*
-     * The pre-configured init function map;
-     */
-    private Map<String, Method> initFunctionMap;
-
-    /*
-     * The VariableMapper for this ELContext.
-     */
-    private VariableMapper variableMapper;
-
-    /*
-     * If non-null, indicates the presence of a delegate ELContext. When a Standard is constructed from another ELContext,
-     * there is no easy way to get its private context map, therefore delegation is needed.
-     */
-    private ELContext delegate;
-
-    /**
-     * A bean repository local to this context
-     */
-    private Map<String, Object> beans = new HashMap<>();
-
-    /**
-     * Construct a default ELContext for a stand-alone environment.
-     *
-     * @param factory The ExpressionFactory
-     */
-    public StandardELContext(ExpressionFactory factory) {
-        streamELResolver = factory.getStreamELResolver();
-        initFunctionMap = factory.getInitFunctionMap();
-    }
-
-    /**
-     * Construct a StandardELContext from another ELContext.
-     *
-     * @param context The ELContext that acts as a delegate in most cases
-     */
-    public StandardELContext(ELContext context) {
-        delegate = context;
-
-        // Copy all attributes except map and resolved
-        CompositeELResolver compositeELResolver = new CompositeELResolver();
-        compositeELResolver.add(new BeanNameELResolver(new LocalBeanNameResolver()));
-        customResolvers = new CompositeELResolver();
-
-        compositeELResolver.add(customResolvers);
-        compositeELResolver.add(context.getELResolver());
-        elResolver = compositeELResolver;
-
-        functionMapper = context.getFunctionMapper();
-        variableMapper = context.getVariableMapper();
-        setLocale(context.getLocale());
-    }
-
-    @Override
-    public void putContext(Class key, Object contextObject) {
-        if (delegate != null) {
-            delegate.putContext(key, contextObject);
-        } else {
-            super.putContext(key, contextObject);
-        }
-    }
-
-    @Override
-    public Object getContext(Class key) {
-        if (delegate == null) {
-            return super.getContext(key);
-        }
-
-        return delegate.getContext(key);
-    }
-
-    /**
-     * Construct (if needed) and return a default ELResolver.
-     *
-     * <p>
-     * Retrieves the <code>ELResolver</code> associated with this context. This is a <code>CompositeELResover</code>
-     * consists of an ordered list of <code>ELResolver</code>s.
-     *
-     * <ol>
-     * <li>A {@link BeanNameELResolver} for beans defined locally</li>
-     * <li>Any custom <code>ELResolver</code>s</li>
-     * <li>An <code>ELResolver</code> supporting the collection operations</li>
-     * <li>A {@link StaticFieldELResolver} for resolving static fields</li>
-     * <li>A {@link MapELResolver} for resolving Map properties</li>
-     * <li>A {@link ResourceBundleELResolver} for resolving ResourceBundle properties</li>
-     * <li>A {@link ListELResolver} for resolving List properties</li>
-     * <li>An {@link ArrayELResolver} for resolving array properties</li>
-     * <li>A {@link BeanELResolver} for resolving bean properties</li>
-     * </ol>
-     *
-     * @return The ELResolver for this context.
-     */
-    @Override
-    public ELResolver getELResolver() {
-        if (elResolver == null) {
-            CompositeELResolver resolver = new CompositeELResolver();
-            customResolvers = new CompositeELResolver();
-            resolver.add(customResolvers);
-            resolver.add(new BeanNameELResolver(new LocalBeanNameResolver()));
-            if (streamELResolver != null) {
-                resolver.add(streamELResolver);
-            }
-            resolver.add(new StaticFieldELResolver());
-            resolver.add(new MapELResolver());
-            resolver.add(new ResourceBundleELResolver());
-            resolver.add(new ListELResolver());
-            resolver.add(new ArrayELResolver());
-            resolver.add(new BeanELResolver());
-            elResolver = resolver;
-        }
-
-        return elResolver;
-    }
-
-    /**
-     * 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.
-     *
-     * @param cELResolver The new ELResolver to be added to the context
-     */
-    public void addELResolver(ELResolver cELResolver) {
-        getELResolver(); // make sure elResolver is constructed
-        customResolvers.add(cELResolver);
-    }
-
-    /**
-     * Get the local bean repository
-     *
-     * @return the bean repository
-     */
-    Map<String, Object> getBeans() {
-        return beans;
-    }
-
-    /**
-     * Construct (if needed) and return a default FunctionMapper.
-     *
-     * @return The default FunctionMapper
-     */
-    @Override
-    public FunctionMapper getFunctionMapper() {
-        if (functionMapper == null) {
-            functionMapper = new DefaultFunctionMapper(initFunctionMap);
-        }
-
-        return functionMapper;
-    }
-
-    /**
-     * Construct (if needed) and return a default VariableMapper() {
-     *
-     * @return The default Variable
-     */
-    @Override
-    public VariableMapper getVariableMapper() {
-        if (variableMapper == null) {
-            variableMapper = new DefaultVariableMapper();
-        }
-
-        return variableMapper;
-    }
-
-    private static class DefaultFunctionMapper extends FunctionMapper {
-
-        private Map<String, Method> functions;
-
-        DefaultFunctionMapper(Map<String, Method> initMap) {
-            functions = (initMap == null) ? new HashMap<String, Method>() : new HashMap<>(initMap);
-        }
-
-        @Override
-        public Method resolveFunction(String prefix, String localName) {
-            return functions.get(prefix + ":" + localName);
-        }
-
-        @Override
-        public void mapFunction(String prefix, String localName, Method meth) {
-            functions.put(prefix + ":" + localName, meth);
-        }
-    }
-
-    private static class DefaultVariableMapper extends VariableMapper {
-
-        private Map<String, ValueExpression> variables;
-
-        @Override
-        public ValueExpression resolveVariable(String variable) {
-            if (variables == null) {
-                return null;
-            }
-
-            return variables.get(variable);
-        }
-
-        @Override
-        public ValueExpression setVariable(String variable, ValueExpression expression) {
-            if (variables == null) {
-                variables = new HashMap<>();
-            }
-
-            ValueExpression prev = null;
-            if (expression == null) {
-                prev = variables.remove(variable);
-            } else {
-                prev = variables.put(variable, expression);
-            }
-
-            return prev;
-        }
-    }
-
-    private class LocalBeanNameResolver extends BeanNameResolver {
-
-        @Override
-        public boolean isNameResolved(String beanName) {
-            return beans.containsKey(beanName);
-        }
-
-        @Override
-        public Object getBean(String beanName) {
-            return beans.get(beanName);
-        }
-
-        @Override
-        public void setBeanValue(String beanName, Object value) {
-            beans.put(beanName, value);
-        }
-
-        @Override
-        public boolean isReadOnly(String beanName) {
-            return false;
-        }
-
-        @Override
-        public boolean canCreateBean(String beanName) {
-            return true;
-        }
-    }
-}
diff --git a/api/src/main/java/javax/el/StaticFieldELResolver.java b/api/src/main/java/javax/el/StaticFieldELResolver.java
deleted file mode 100644
index a945e0d..0000000
--- a/api/src/main/java/javax/el/StaticFieldELResolver.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-import static java.lang.reflect.Modifier.isPublic;
-import static java.lang.reflect.Modifier.isStatic;
-import static javax.el.ELUtil.getExceptionMessageString;
-
-import java.beans.FeatureDescriptor;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Iterator;
-
-/**
- * An {@link ELResolver} for resolving static fields, enum constants and static methods. Also handles constructor calls
- * as a special case.
- * 
- * <p>
- * The resolver handles base objects of the type {@link ELClass}, which is usually generated by a Jakarta Expression
- * Language implementation.
- *
- * @see ELClass
- * @since Jakarta Expression Language 3.0
- */
-public class StaticFieldELResolver extends ELResolver {
-
-    /**
-     * <p>
-     * Returns the value of a static field.
-     * </p>
-     * <p>
-     * If the base object is an instance of <code>ELClass</code> and the property is String, the
-     * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by this
-     * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller should
-     * ignore the return value.
-     * </p>
-     *
-     * If the property is a public static field of class specified in <code>ELClass</code>, 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.
-     *
-     * @param context The context of this evaluation.
-     * @param base An <code>ELClass</code>.
-     * @param property A static field name.
-     * 
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the static field value.
-     * 
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotFoundException 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 inaccessible.
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof ELClass && property instanceof String) {
-            Class<?> klass = ((ELClass) base).getKlass();
-            String fieldName = (String) property;
-            try {
-                context.setPropertyResolved(base, property);
-                Field field = klass.getField(fieldName);
-
-                int mod = field.getModifiers();
-                if (Modifier.isPublic(mod) && Modifier.isStatic(mod)) {
-                    return field.get(null);
-                }
-            } catch (NoSuchFieldException ex) {
-            } catch (IllegalAccessException ex) {
-            }
-
-            throw new PropertyNotFoundException(ELUtil.getExceptionMessageString(context, "staticFieldReadError", new Object[] { klass.getName(), fieldName }));
-        }
-
-        return null;
-    }
-
-    /**
-     * <p>
-     * Attempts to write to a static field.
-     * </p>
-     * <p>
-     * If the base object is an instance of <code>ELClass</code>and the property is String, a
-     * <code>PropertyNotWritableException</code> will always be thrown, because writing to a static field is not allowed.
-     *
-     * @param context The context of this evaluation.
-     * @param base An <code>ELClass</code>
-     * @param property The name of the field
-     * @param value The value to set the field of the class to.
-     * @throws NullPointerException if context is <code>null</code>
-     * @throws PropertyNotWritableException if base object instance of <code>ELClass</code>and <code>property</code>
-     * instance of String
-     */
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object value) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof ELClass && property instanceof String) {
-            Class<?> klass = ((ELClass) base).getKlass();
-            String fieldName = (String) property;
-            throw new PropertyNotWritableException(
-                    getExceptionMessageString(context, "staticFieldWriteError", new Object[] { klass.getName(), fieldName }));
-        }
-    }
-
-    /**
-     * Invokes a public static method or the constructor for a class.
-     *
-     * <p>
-     * If the base object is an instance of <code>ELClass</code> and the method is a String, the
-     * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by the
-     * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller should
-     * ignore the return value.
-     *
-     * <p>
-     * Invoke the public static method specified by <code>method</code>.
-     *
-     * <p>
-     * The process involved in the method selection is the same as that used in {@link BeanELResolver}.
-     *
-     * <p>
-     * As a special case, if the name of the method is "&lt;init&gt;", the constructor for the class will be invoked.
-     *
-     * @param base An <code>ELClass</code>
-     * @param methodName When coerced to a <code>String</code>, the simple name of the method.
-     * @param paramTypes An array of Class objects identifying the method's formal parameter types, in declared order. Use
-     * an empty array if the method has no parameters. Can be <code>null</code>, in which case the method's formal parameter
-     * types are assumed to be unknown.
-     * @param params The parameters to pass to the method, or <code>null</code> if no parameters.
-     * @return The result of the method invocation (<code>null</code> if the method has a <code>void</code> return type).
-     * @throws MethodNotFoundException if no suitable method can be found.
-     * @throws ELException 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
-     * <code>InvocationTargetException</code>, extract its <code>cause</code> and pass it to the <code>ELException</code>
-     * constructor.
-     */
-    @Override
-    public Object invoke(ELContext context, Object base, Object methodName, Class<?>[] paramTypes, Object[] params) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (!(base instanceof ELClass && methodName instanceof String)) {
-            return null;
-        }
-
-        Class<?> klass = ((ELClass) base).getKlass();
-        String name = (String) methodName;
-
-        Object ret;
-        if ("<init>".equals(name)) {
-            Constructor<?> constructor = ELUtil.findConstructor(klass, paramTypes, params);
-            ret = ELUtil.invokeConstructor(context, constructor, params);
-        } else {
-            Method method = ELUtil.findMethod(klass, name, paramTypes, params, true);
-            ret = ELUtil.invokeMethod(context, method, null, params);
-        }
-        context.setPropertyResolved(base, methodName);
-
-        return ret;
-    }
-
-    /**
-     * Returns the type of a static field.
-     *
-     * <p>
-     * If the base object is an instance of <code>ELClass</code>and the property is a String, the
-     * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by the
-     * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller can
-     * safely assume no value has been set.
-     *
-     * <p>
-     * If the property string is a public static field of class specified in ELClass, return the type of the static field.
-     *
-     * @param context The context of this evaluation.
-     * @param base An <code>ELClass</code>.
-     * @param property The name of the field.
-     * @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
-     * the type of the type of the field.
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotFoundException if field is not a public static filed of the class, or if the field is
-     * inaccessible.
-     */
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof ELClass && property instanceof String) {
-            Class<?> klass = ((ELClass) base).getKlass();
-            String fieldName = (String) property;
-            try {
-                context.setPropertyResolved(true);
-                Field field = klass.getField(fieldName);
-
-                int mod = field.getModifiers();
-                if (isPublic(mod) && isStatic(mod)) {
-                    return field.getType();
-                }
-            } catch (NoSuchFieldException ex) {
-            }
-            throw new PropertyNotFoundException(getExceptionMessageString(context, "staticFieldReadError", new Object[] { klass.getName(), fieldName }));
-        }
-
-        return null;
-    }
-
-    /**
-     * <p>
-     * Inquires whether the static field is writable.
-     * </p>
-     * <p>
-     * If the base object is an instance of <code>ELClass</code>and the property is a String, the
-     * <code>propertyResolved</code> property of the <code>ELContext</code> object must be set to <code>true</code> by the
-     * resolver, before returning. If this property is not <code>true</code> after this method is called, the caller can
-     * safely assume no value has been set.
-     * </p>
-     *
-     * <p>
-     * Always returns a <code>true</code> because writing to a static field is not allowed.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param base An <code>ELClass</code>.
-     * @param property The name of the bean.
-     * @return <code>true</code>
-     * @throws NullPointerException if context is <code>null</code>.
-     */
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof ELClass && property instanceof String) {
-            ((ELClass) base).getKlass();
-            context.setPropertyResolved(true);
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns the properties that can be resolved. Always returns <code>null</code>, since there is no reason to iterate
-     * through a list of one element: field name.
-     *
-     * @param context The context of this evaluation.
-     * @param base An <code>ELClass</code>.
-     * @return <code>null</code>.
-     */
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        return null;
-    }
-
-    /**
-     * Returns the type of the property. Always returns <code>String.class</code>, since a field name is a String.
-     *
-     * @param context The context of this evaluation.
-     * @param base An <code>ELClass</code>.
-     * @return <code>String.class</code>.
-     */
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        return String.class;
-    }
-}
diff --git a/api/src/main/java/javax/el/TypeConverter.java b/api/src/main/java/javax/el/TypeConverter.java
deleted file mode 100644
index e9b3dcd..0000000
--- a/api/src/main/java/javax/el/TypeConverter.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2012, 2018 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 javax.el;
-
-import java.beans.FeatureDescriptor;
-import java.util.Iterator;
-
-/**
- * A convenient class for writing an ELResolver to do custom type conversions.
- *
- * <p>
- * For example, to convert a String to an instance of MyDate, one can write
- *
- * <pre>
- * <code>
- *     ELProcessor elp = new ELProcessor();
- *     elp.getELManager().addELResolver(new TypeConverter() {
- *         Object convertToType(ELContext context, Object obj, Class&lt;?&gt; type) {
- *             if ((obj instanceof String) &amp;&amp; type == MyDate.class) {
- *                 context.setPropertyResolved(obj, type);
- *                 return (obj == null)? null: new MyDate(obj.toString());
- *             }
- *             return null;
- *         }
- *      };
- * </code>
- * </pre>
- *
- * @since Jakarta Expression Language 3.0
- */
-public abstract class TypeConverter extends ELResolver {
-
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        return null;
-    }
-
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        return null;
-    }
-
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object value) {
-    }
-
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        return false;
-    }
-
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        return null;
-    }
-
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        return null;
-    }
-
-    /**
-     * Converts an object to a specific type.
-     *
-     * <p>
-     * An <code>ELException</code> is thrown if an error occurs during the conversion.
-     * </p>
-     *
-     * @param context The context of this evaluation.
-     * @param obj The object to convert.
-     * @param targetType The target type for the conversion.
-     * @throws ELException thrown if errors occur.
-     */
-    @Override
-    abstract public Object convertToType(ELContext context, Object obj, Class<?> targetType);
-}
diff --git a/api/src/main/java/javax/el/ValueExpression.java b/api/src/main/java/javax/el/ValueExpression.java
deleted file mode 100644
index 7f9cfdc..0000000
--- a/api/src/main/java/javax/el/ValueExpression.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * An <code>Expression</code> that can get or set a value.
- *
- * <p>
- * In previous incarnations of this API, expressions could only be read. <code>ValueExpression</code> objects can now be
- * used both to retrieve a value and to set a value. Expressions that can have a value set on them are referred to as
- * l-value expressions. Those that cannot are referred to as r-value expressions. Not all r-value expressions can be
- * used as l-value expressions (e.g. <code>"${1+1}"</code> or <code>"${firstName} ${lastName}"</code>). See the EL
- * Specification for details. Expressions that cannot be used as l-values must always return <code>true</code> from
- * <code>isReadOnly()</code>.
- * </p>
- *
- * <p>
- * The <code>{@link ExpressionFactory#createValueExpression}</code> method can be used to parse an expression string and
- * return a concrete instance of <code>ValueExpression</code> that encapsulates the parsed expression. The
- * {@link FunctionMapper} is used at parse time, not evaluation time, so one is not needed to evaluate an expression
- * using this class. However, the {@link ELContext} is needed at evaluation time.
- * </p>
- *
- * <p>
- * The {@link #getValue}, {@link #setValue}, {@link #isReadOnly}, {@link #getType} and {@link #getValueReference}
- * methods will evaluate the expression each time they are called. The {@link ELResolver} in the <code>ELContext</code>
- * is used to resolve the top-level variables and to determine the behavior of the <code>.</code> and <code>[]</code>
- * operators. For any of the five methods, the {@link ELResolver#getValue} method is used to resolve all properties up
- * to but excluding the last one. This provides the <code>base</code> object. For all methods other than the
- * {@link #getValueReference} method, at the last resolution, the <code>ValueExpression</code> will call the
- * corresponding {@link ELResolver#getValue}, {@link ELResolver#setValue}, {@link ELResolver#isReadOnly} or
- * {@link ELResolver#getType} method, depending on which was called on the <code>ValueExpression</code>. For the
- * {@link #getValueReference} method, the (base, property) is not resolved by the ELResolver, but an instance of
- * {@link ValueReference} is created to encapsulate this (base ,property), and returned.
- * </p>
- *
- * <p>
- * See the notes about comparison, serialization and immutability in the {@link Expression} javadocs.
- *
- * @see ELResolver
- * @see Expression
- * @see ExpressionFactory
- * 
- * @since Jakarta Server Pages 2.1
- */
-public abstract class ValueExpression extends Expression {
-
-    private static final long serialVersionUID = -8466802188968516519L;
-
-    /**
-     * Evaluates the expression relative to the provided context, and returns the resulting value.
-     *
-     * <p>
-     * The resulting value is automatically coerced to the type returned by <code>getExpectedType()</code>, which was
-     * provided to the <code>ExpressionFactory</code> when this expression was created.
-     *
-     * @param context The context of this evaluation.
-     * 
-     * @return The result of the expression evaluation.
-     * 
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws ELException 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.
-     */
-    public abstract Object getValue(ELContext context);
-
-    /**
-     * Evaluates the expression relative to the provided context, and sets the result to the provided value.
-     *
-     * @param context The context of this evaluation.
-     * @param value The new value to be set.
-     * 
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws PropertyNotWritableException if the final variable or property resolution failed because the specified
-     * variable or property is not writable.
-     * @throws ELException 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.
-     */
-    public abstract void setValue(ELContext context, Object value);
-
-    /**
-     * Evaluates the expression relative to the provided context, and returns <code>true</code> if a call to
-     * {@link #setValue} will always fail.
-     *
-     * @param context The context of this evaluation.
-     * 
-     * @return <code>true</code> if the expression is read-only or <code>false</code> if not.
-     * 
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws ELException 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
-     * <code>null</code>
-     */
-    public abstract boolean isReadOnly(ELContext context);
-
-    /**
-     * 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 <code>value</code> parameter in a future call to the {@link #setValue} method.
-     *
-     * <p>
-     * This is not always the same as <code>getValue().getClass()</code>. For example, in the case of an expression that
-     * references an array element, the <code>getType</code> 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.
-     *
-     * @param context The context of this evaluation.
-     * 
-     * @return the most general acceptable type; otherwise undefined.
-     * 
-     * @throws NullPointerException if context is <code>null</code>.
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws ELException 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.
-     */
-    public abstract Class<?> getType(ELContext context);
-
-    /**
-     * Returns the type the result of the expression will be coerced to after evaluation.
-     *
-     * @return the <code>expectedType</code> passed to the <code>ExpressionFactory.createValueExpression</code> method that
-     * created this <code>ValueExpression</code>.
-     */
-    public abstract Class<?> getExpectedType();
-
-    /**
-     * Returns a {@link ValueReference} for this expression instance.
-     *
-     * @param context the context of this evaluation
-     * 
-     * @return the <code>ValueReference</code> for this <code>ValueExpression</code>, or <code>null</code> if this
-     * <code>ValueExpression</code> is not a reference to a base (null or non-null) and a property. If the base is null, and
-     * the property is a Jakarta Expression Language variable, return the <code>ValueReference</code> for the 
-     * <code>ValueExpression</code> associated with this Jakarta Expression Language variable.
-     *
-     * @since Jakarta Expression Language 2.2
-     */
-    public ValueReference getValueReference(ELContext context) {
-        return null;
-    }
-}
diff --git a/api/src/main/java/javax/el/ValueReference.java b/api/src/main/java/javax/el/ValueReference.java
deleted file mode 100644
index d486c7f..0000000
--- a/api/src/main/java/javax/el/ValueReference.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2010, 2018 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 javax.el;
-
-import java.io.Serializable;
-
-/**
- * This encapsulates a base model object and one of its properties.
- *
- * @since Jakarta Expression Language 2.2
- */
-public class ValueReference implements Serializable {
-
-    private static final long serialVersionUID = -4076659531951367109L;
-
-    private Object base;
-    private Object property;
-
-    public ValueReference(Object base, Object property) {
-        this.base = base;
-        this.property = property;
-    }
-
-    public Object getBase() {
-        return base;
-    }
-
-    public Object getProperty() {
-        return property;
-    }
-
-}
diff --git a/api/src/main/java/javax/el/VariableMapper.java b/api/src/main/java/javax/el/VariableMapper.java
deleted file mode 100644
index 1b84214..0000000
--- a/api/src/main/java/javax/el/VariableMapper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 1997-2018 Oracle and/or its affiliates and others.
- * All rights reserved.
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.el;
-
-/**
- * The interface to a map between Jakarta Expression Language variables and the Jakarta Expression Language expressions
- * they are associated with.
- *
- * @since Jakarta Server Pages 2.1
- */
-public abstract class VariableMapper {
-
-    /**
-     * @param variable The variable name
-     * 
-     * @return the ValueExpression assigned to the variable, null if there is no previous assignment to this variable.
-     */
-    public abstract ValueExpression resolveVariable(String variable);
-
-    /**
-     * Assign a ValueExpression to an Jakarta Expression Language variable, replacing any previously assignment to the same
-     * variable. The assignment for the variable is removed if the expression is <code>null</code>.
-     *
-     * @param variable The variable name
-     * @param expression The ValueExpression to be assigned to the variable.
-     * 
-     * @return The previous ValueExpression assigned to this variable, null if there is no previous assignment to this
-     * variable.
-     */
-    public abstract ValueExpression setVariable(String variable, ValueExpression expression);
-}
diff --git a/api/src/main/java/javax/el/package.html b/api/src/main/java/javax/el/package.html
deleted file mode 100644
index 22e6086..0000000
--- a/api/src/main/java/javax/el/package.html
+++ /dev/null
@@ -1,239 +0,0 @@
-<!--
-
-    Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
-    Copyright 2004 The Apache Software Foundation
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-</head>
-
-<body bgcolor="white">
-Provides the API for <strong>Jakarta Expression Language 3.0</strong>
-
-<p>Jakarta Expression Language is a simple language originally designed to
-satisfy the specific needs of web application developers. It has evolved
-into its own specification intended for general use inside and outside of the
-web containers.</p>
-
-<p>This package contains the classes and interfaces that describe
-and define the programmatic access to the Jakarta Expression Language engine. 
-The API is logically partitioned as follows:
-
-<ul>
-  <li><a href="#Context">Jakarta Expression Language Context</a></li>
-  <li><a href="#ExpressionObjects">Expression Objects</a></li>
-  <li><a href="#ExpressionCreation">Creation of Expressions</a></li>
-  <li><a href="#ExpressionEvaluation">Evaluation of Expressions</a></li>
-  <li><a href="#EvaluationListener">Evaluation Listeners</a></li>
-  <li><a href="#Resolver">Resolution of Model Objects and their Properties</a></li>
-  <li><a href="#Functions">Jakarta Expression Language Functions</a></li>
-  <li><a href="#Variables">Jakarta Expression Language Variables</a></li>
-  <li><a href="#Standalone">Jakarta Expression Language in Stand-alone environment</a></li>
-</ul>
-
-<h3><a name="Context">Jakarta Expression Language Context</a></h3>
-
-<p>An important goal of Jakarta Expression Language is to ensure it can be used in 
-a variety of environments. It must therefore provide enough flexibility
-to adapt to the specific requirements of the environment where it is
-being used.</p>
-
-<p>Class {@link javax.el.ELContext} is what links 
-the Jakarta Expression Language with the specific environment where it is being used.
-It provides the mechanism through which all relevant context for creating or
-evaluating an expression is specified.
-</p>
-
-<p>When Jakarta Expression Language is used in a web container, the creation of <code>ELContext
-</code> objects is controlled through the underlying technology.
-For example, in Jakarta Server Pages, the
- <code>JspContext.getELContext()</code> factory method is used.  In an
-stand-alone environment, a default {@link javax.el.StandardELContext} is
-provided.</p>
- 
- <p>Some technologies provide the ability to add an {@link javax.el.ELContextListener}
- so that applications and frameworks can ensure their own context objects
- are attached to any newly created <code>ELContext</code>.</p>
- 
-<h3><a name="ExpressionObjects">Expression Objects</a></h3>
-
-<p>At the core of the Expression Language is the notion of an <i>expression</i>
-that gets parsed according to the grammar defined by the Expression Language.</p>
-
-<p>There are two types of expressions defined by Jakarta Expression Language: <i>value expressions</i>
-and <i>method expressions</i>. A {@link javax.el.ValueExpression} such as 
-<code>"${customer.name}"</code> can be used either
-as an <i>rvalue</i> (return the value associated with property <code>name</code>
-of the model object <code>customer</code>) or as an <i>lvalue</i> 
-(set the value of the property <code>name</code> of the model object
-<code>customer</code>).</p>
-
-<p>A {@link javax.el.MethodExpression} such as 
-<code>"${handler.process}"</code> makes it possible to invoke a method 
-(<code>process</code>) on a specific model object (<code>handler</code>).</p>
-
-<p>In version 2.2 and later, either type of Jakarta Expression Language expression can represent a method
-invocation, such as <code>${trader.buy("JAVA")}</code>, where the arguments to
-the method invocation are specified in the expression.</p>
-
-<p>All expression classes extend the base class {@link javax.el.Expression}, making them
-serializable and forcing them to implement <code>equals()</code> and 
-<code>hashCode()</code>. Moreover, each method on these expression classes 
-that actually evaluates an expression receives a parameter
-of class {@link javax.el.ELContext},
-which provides the context required to evaluate the expression.</p>
-
-<h3><a name="ExpressionCreation">Creation of Expressions</a></h3>
-
-<p>An expression is created through the {@link javax.el.ExpressionFactory} class.
-The factory provides two creation methods; one for each type of expression
- supported by Jakarta Expression Language.</p>
-
-<p>To create an expression, one must provide an {@link javax.el.ELContext}, 
-a string representing 
-the expression, and the expected type (<code>ValueExpression</code>) or signature 
-(<code>MethodExpression</code>). 
-
-The <code>ELContext</code> provides the context necessary to parse an expression.
-Specifically, if the expression uses a Jakarta Expression Language function 
-(for example <code>${fn:toUpperCase(customer.name)}</code>) or a Jakarta Expression Language 
-variable, then {@link javax.el.FunctionMapper} and {@link javax.el.VariableMapper}
-objects must be available within the <code>ELContext</code> so that Jakarta Expression Language 
-functions and Jakarta Expression Language variables are properly mapped.
-
-<h3><a name="ExpressionEvaluation">Evaluation of Expressions</a></h3>
-<p>The creation and the evaluation of an expression are done in two separate
-steps.  At the evaluation of an expression, the {@link javax.el.ELContext} 
-provides the context necessary to support property and method resolution
-for modal objects.</p>
-
-<p>A deferred expression is one that is created but not immediately evaluated.
-In a Jakarta Faces request processing life cycle, Jakarta Expression Language 
-expressions are typically created in the tree building phase and evaluated in the 
-rendering phrase.</p>
-
-<p>Adding parameters to a <code>ValueExpression</code> further enhances the
-power of deferred expressions.  The {@link javax.el.LambdaExpression}
-encapsulates such a construct.  A <code>LambdaExpression</code> can be
-invoked by supplying the actual parameters at evaluation.  It plays
-an important role in the support for collections operators.</p>
-
-<h3><a name="EvaluationListener">Evaluation Listeners</a></h3>
-<p>By registering {@link javax.el.EvaluationListener}s in ELContext, a user can
-receive notifications during the Jakarta Expression Language expression evaluations.  
-There are three events that trigger the notification:
-<ul>
-  <li>Before evaluation</li>
-  <li>After evaluation</li>
-  <li>When (base, property) is resolved</li>
-</ul></p>
-
-<h3><a name="Resolver">Resolution of Model Objects and their Properties</a></h3>
-
-<p>Through the {@link javax.el.ELResolver} base class, Jakarta Expression Language 
-features a pluggable mechanism to resolve model object references as well as properties 
-and method invocations of these objects.</p>
-
-<p>The Jakarta Expression Language API provides implementations of <code>ELResolver</code> supporting 
-property resolution for common data types which include arrays 
-({@link javax.el.ArrayELResolver}), JavaBeans ({@link javax.el.BeanELResolver}), <code>List</code>s ({@link javax.el.ListELResolver}), 
-<code>Map</code>s ({@link javax.el.MapELResolver}), and <code>ResourceBundle</code>s ({@link javax.el.ResourceBundleELResolver}).</p>
-
-<p>Tools can easily obtain more information about resolvable model objects and their 
-resolvable properties by calling
-method <code>getFeatureDescriptors</code> on the <code>ELResolver</code>. This method exposes objects
-of type <code>java.beans.FeatureDescriptor</code>, providing all information of interest 
-on top-level model objects as well as their properties.</p> 
-
-<h3><a name="Functions">Jakarta Expression Language Functions</a></h3>
-
-<p>If a Jakarta Expression Language expression uses a function 
-(for example <code>${fn:toUpperCase(customer.name)}</code>), then a 
-{@link javax.el.FunctionMapper} object must also be specified within 
-the <code>ELContext</code>. 
-
-The <code>FunctionMapper</code> is responsible to map
- <code>${prefix:name()}</code> style functions to 
-static methods that can execute the specified functions. 
-</p>
-
-<h3><a name="Variables">Jakarta Expression Language Variables</a></h3>
-
-<p>Just like {@link javax.el.FunctionMapper} provides
-a flexible mechanism to add functions to Jakarta Expression Language, 
-{@link javax.el.VariableMapper} provides a flexible mechanism to support the notion of 
-<strong>Jakarta Expression Language variables</strong>.
-</p>
- 
-<p>
-A Jakarta Expression Language variable does not directly refer to a model object that can then
-be resolved by an <code>ELResolver</code>. Instead, it refers to a Jakarta Expression Language
-expression. The evaluation of that Jakarta Expression Language expression gives the
-Jakarta Expression Language variable its value.
-</p>
-
-<p>
-For example, in the following code snippet
-<blockquote>
-  <code>&lt;h:inputText value="#{handler.customer.name}"/></code>
-</blockquote>
-
-<code>handler</code> refers to a model object that can be resolved by a Jakarta Expression Language Resolver.
-</p>
-<p>
-However, in this other example:
-<blockquote>
-<pre>
-&lt;c:forEach var="item" items="#{model.list}">
-   &lt;h:inputText value="#{item.name}"/>
-&lt;/c:forEach>
-</pre>
-</blockquote>
-
-<code>item</code> is a Jakarta Expression Language variable because it does not refer directly to a model
-object.  Instead, it refers to another Jakarta Expression Language expression, namely a
-specific item in the collection referred to by the Jakarta Expression Language expression
-<code>#{model.list}</code>.
-</p>
-
-<p>
-Assuming that there are three elements in <code>${model.list}</code>, this means
-that for each invocation of <code>&lt;h:inputText></code>, the following information 
-about <code>item</code> must be preserved in the {@link javax.el.VariableMapper}:
-<blockquote>
-    first invocation: <code>item</code> maps to first element in <code>${model.list}</code><br>
-    second invocation: <code>item</code> maps to second element in <code>${model.list}</code><br>
-    third invocation: <code>item</code> maps to third element in <code>${model.list}</code><br>
-</blockquote>
-<p>
-<code>VariableMapper</code> provides the mechanisms required to allow the mapping
-of a Jakarta Expression Language variable to the Jakarta Expression Language expression from which it gets its value.
-</p>
-
-<h3><a name="Standalone">Jakarta Expression Language in Stand-alone environment</a></h3>
-<p>Jakarta Expression Language 3.0 includes APIs for using Jakarta Expression Language in a stand-alone environment.</p>
-<p>{@link javax.el.ELProcessor} provides simple APIs for the direct
-evaluations of expressions. It also makes it easy to define functions,
-set variables, and define beans locally.</p>
-
-<p>{@link javax.el.ELManager} provides lower level APIs for managing the Jakarta Expression Language
-parsing and evaluation environment.  It contains a default ELContext {@link javax.el.StandardELContext}.</p>
-
-</body>
-</html>
-
diff --git a/impl/build.xml b/impl/build.xml
deleted file mode 100644
index 2ed734c..0000000
--- a/impl/build.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<!--
-
-    Copyright (c) 2010, 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
-
--->
-
-<!-- Use ant to generate .jj and .java files.  Use mvn for build. -->
-
-<project name="el-impl" default="generate" basedir=".">
-
-    <property name="javacc.home" value="/Users/kichung/tools/javacc-5.0"/>
-    <property name="dir" value="src/main/java/com/sun/el/parser"/>
-
-    <target name="generate" description="Generate java files">
-
-        <jjtree target="${dir}/ELParser.jjt"
-                outputdirectory="${dir}"
-                javacchome="${javacc.home}"/>
-        <javacc target="${dir}/ELParser.jj"
-                outputdirectory="${dir}"
-                javacchome="${javacc.home}"/>
-
-        <replaceregexp byline="true">
-          <regexp pattern="final private LookaheadSuccess"/>
-          <substitution expression="static final private LookaheadSuccess"/>
-          <fileset dir="src/main/java/com/sun/el/parser">
-            <include name="ELParser.java"/>
-          </fileset>
-        </replaceregexp>
-
-    </target>
-</project>
-
diff --git a/impl/pom.xml b/impl/pom.xml
deleted file mode 100644
index 9c28069..0000000
--- a/impl/pom.xml
+++ /dev/null
@@ -1,276 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 1997, 2018 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>
-        <relativePath/>
-    </parent>
-    
-    <groupId>com.sun.el</groupId>
-    <artifactId>el-ri</artifactId>
-    <version>3.0.3-SNAPSHOT</version>
-
-    <name>Jakarta Expression Language 3.0 Implementation</name>
-    <description>Jakarta Expression Language Implementation</description>
-    <url>https://projects.eclipse.org/projects/ee4j.el</url>
-    
-    <properties>
-        <!-- the bundle build number must be the same as the maven number -->
-        <bundle.version>3.0.3</bundle.version>
-        <!-- The most current api version -->
-        <spec.version>3.0</spec.version>
-        <extensionName>javax.el.impl</extensionName>
-        <bundle.symbolicName>com.sun.el.javax.el</bundle.symbolicName>
-        <vendorName>Oracle Corporation</vendorName>
-        <findbugs.version>2.5.2</findbugs.version>
-        <findbugs.exclude>${project.basedir}/exclude.xml</findbugs.exclude>
-        <findbugs.threshold>High</findbugs.threshold>
-        <tlda-license.url>http://hudson-sca.us.oracle.com/job/tlda-license/lastSuccessfulBuild/artifact</tlda-license.url>
-    </properties>
-
-    <issueManagement>
-        <system>github</system>
-        <url>https://github.com/eclipse-ee4j/el-ri/issues</url>
-    </issueManagement>
-
-    <licenses>
-        <license>
-            <name>EPL 2.0</name>
-            <url>http://www.eclipse.org/legal/epl-2.0</url>
-            <distribution>repo</distribution>
-        </license>
-        <license>
-            <name>GPL2 w/ CPE</name>
-            <url>https://www.gnu.org/software/classpath/license.html</url>
-            <distribution>repo</distribution>
-        </license>
-    </licenses>
-    
-    <mailingLists>
-        <mailingList>
-            <name>Jakarta Expression Language 3.0 mailing list</name>
-            <post>el-dev@eclipse.org</post>
-            <subscribe>https://dev.eclipse.org/mailman/listinfo/el-dev</subscribe>
-            <unsubscribe>https://dev.eclipse.org/mailman/listinfo/el-dev</unsubscribe>
-            <archive>https://dev.eclipse.org/mhonarc/lists/el-dev</archive>
-        </mailingList>
-    </mailingLists>
-
-    <scm>
-        <connection>scm:git:https://github.com/eclipse-ee4j/el-ri.git</connection>
-        <developerConnection>
-            scm:git:git@github.com:eclipse-ee4j/el-ri.git
-        </developerConnection>
-        <url>https://github.com/eclipse-ee4j/el-ri</url>
-        <tag>HEAD</tag>
-    </scm>
-
-    <developers>
-        <developer>
-            <id>yaminikb</id>
-            <name>Yamini K B</name>
-            <organization>Oracle Corporation</organization>
-            <organizationUrl>http://www.oracle.com/</organizationUrl>
-        </developer>
-    </developers>
-
-    <contributors>
-        <contributor>
-            <name>Kin-man Chung</name>
-        </contributor>
-    </contributors>
-
-    <build>
-        <resources>
-            <resource>
-                <directory>src/main/java</directory>
-                <includes>
-                    <include>**/*.properties</include>
-                    <include>**/*.xml</include>
-                </includes>
-            </resource>
-            <resource>
-                <directory>${project.basedir}/..</directory>
-                <includes>
-                    <include>LICENSE.md</include>
-                    <include>NOTICE.md</include>
-                </includes>
-                <targetPath>META-INF</targetPath>
-            </resource>
-        </resources>
-    
-    
-        <plugins>
-            <!-- Configure maven-bundle-plugin to generate OSGi manifest. Please note: we use the manifest goal only and not the bundle goal. 
-                The bundle goal can lead to very surprising results if the package names are not correctly specified. So, we use the jar plugin to generate the 
-                jar. -->
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <version>1.4.3</version>
-                <configuration>
-                    <instructions>
-                        <Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName>
-                        <Bundle-Description>
-                            Jakarta Expression Language ${spec.version} Implementation
-                        </Bundle-Description>
-                        <Bundle-Version>${bundle.version}</Bundle-Version>
-                        <Extension-Name>${extensionName}</Extension-Name>
-                        <Specification-Version>${spec.version}</Specification-Version>
-                        <Specification-Vendor>${vendorName}</Specification-Vendor>
-                        <Implementation-Version>${project.version}</Implementation-Version>
-                        <Implementation-Vendor>${vendorName}</Implementation-Vendor>
-                        <Export-Package>com.sun.el</Export-Package>
-                    </instructions>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>bundle-manifest</id>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>manifest</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            
-            <plugin>
-                <artifactId>maven-jar-plugin</artifactId>
-                <version>2.4</version>
-                <configuration>
-                    <archive>
-                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
-                    </archive>
-                </configuration>
-            </plugin>
-            
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <version>3.0</version>
-                <configuration>
-                    <source>1.7</source>
-                    <target>1.7</target>
-                    <compilerArgument>-Xlint:unchecked</compilerArgument>
-                </configuration>
-            </plugin>
-
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <version>3.0.1</version>
-                <executions>
-                    <execution>
-                        <id>attach-javadocs</id>
-                        <goals>
-                            <goal>jar</goal>
-                        </goals>
-                        <configuration>
-                            <additionalJOption>-Xdoclint:none</additionalJOption>
-                            <groups>
-                                <group>
-                                    <title>Jakarta Expression Language 3.0 Implementation</title>
-                                    <packages>com.sun.el</packages>
-                                </group>
-                            </groups>
-                            <bottom> Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. Use is subject to license terms. </bottom>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            
-            <!-- Use ant to manually invoke javacc, as this required is very infrequently <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>javacc-maven-plugin</artifactId> 
-                <version>2.6</version> <executions> <execution> <id>jjtree-javacc</id> <goals> <goal>jjtree-javacc</goal> </goals> <configuration> <sourceDirectory>src/main/java/com/sun/el/parser</sourceDirectory> 
-                <outputDirectory>src/main/java/com/sun/el/parser</outputDirectory> </configuration> </execution> </executions> </plugin> -->
-            
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>findbugs-maven-plugin</artifactId>
-                <version>${findbugs.version}</version>
-                <configuration>
-                    <threshold>${findbugs.threshold}</threshold>
-                    <excludeFilterFile>${findbugs.exclude}</excludeFilterFile>
-                    <findbugsXmlOutput>true</findbugsXmlOutput>
-                    <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
-                </configuration>
-            </plugin>
-            
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-release-plugin</artifactId>
-                <configuration>
-                    <mavenExecutorId>forked-path</mavenExecutorId>
-                    <useReleaseProfile>false</useReleaseProfile>
-                    <arguments>${release.arguments}</arguments>
-                </configuration>
-            </plugin>
-            
-            <plugin>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <version>2.7.1</version>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.apache.maven.surefire</groupId>
-                        <artifactId>surefire-junit47</artifactId>
-                        <version>2.7.1</version>
-                    </dependency>
-                </dependencies>
-                <configuration>
-                    <forkMode>never</forkMode>
-                </configuration>
-            </plugin>
-	</plugins>
-    </build>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>findbugs-maven-plugin</artifactId>
-                <version>${findbugs.version}</version>
-                <configuration>
-                    <threshold>${findbugs.threshold}</threshold>
-                    <excludeFilterFile>${findbugs.exclude}</excludeFilterFile>
-                </configuration>
-            </plugin>
-        </plugins>
-    </reporting>
-
-    <dependencies>
-        <dependency>
-            <groupId>jakarta.el</groupId>
-            <artifactId>jakarta.el-api</artifactId>
-            <version>${bundle.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>4.12</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-   
-</project>
diff --git a/impl/src/main/java/com/sun/el/ExpressionFactoryImpl.java b/impl/src/main/java/com/sun/el/ExpressionFactoryImpl.java
deleted file mode 100644
index ee9a042..0000000
--- a/impl/src/main/java/com/sun/el/ExpressionFactoryImpl.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.ELResolver;
-import javax.el.ExpressionFactory;
-import javax.el.MethodExpression;
-import javax.el.ValueExpression;
-
-import com.sun.el.lang.ELSupport;
-import com.sun.el.lang.ExpressionBuilder;
-import com.sun.el.stream.StreamELResolver;
-import com.sun.el.util.MessageFactory;
-
-/**
- * @see javax.el.ExpressionFactory
- *
- * @author Jacob Hookom [jacob@hookom.net]
- * @author Kin-man Chung
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public class ExpressionFactoryImpl extends ExpressionFactory {
-
-    private Properties properties;
-    private boolean isBackwardCompatible22;
-
-    public ExpressionFactoryImpl() {
-        super();
-    }
-
-    public ExpressionFactoryImpl(Properties properties) {
-        super();
-        this.properties = properties;
-        this.isBackwardCompatible22 = "true".equals(getProperty("javax.el.bc2.2"));
-    }
-
-    @Override
-    public Object coerceToType(Object obj, Class<?> type) {
-        try {
-            return ELSupport.coerceToType(obj, type, isBackwardCompatible22);
-        } catch (IllegalArgumentException ex) {
-            throw new ELException(ex);
-        }
-    }
-
-    @Override
-    public MethodExpression createMethodExpression(ELContext context, String expression, Class<?> expectedReturnType, Class<?>[] expectedParamTypes) {
-        MethodExpression methodExpression =
-                new ExpressionBuilder(expression, context)
-                    .createMethodExpression(expectedReturnType, expectedParamTypes);
-
-        if (expectedParamTypes == null && !methodExpression.isParametersProvided()) {
-            throw new NullPointerException(MessageFactory.get("error.method.nullParms"));
-        }
-
-        return methodExpression;
-    }
-
-    @Override
-    public ValueExpression createValueExpression(ELContext context, String expression, Class<?> expectedType) {
-        if (expectedType == null) {
-            throw new NullPointerException(MessageFactory.get("error.value.expectedType"));
-        }
-
-        return new ExpressionBuilder(expression, context).createValueExpression(expectedType);
-    }
-
-    @Override
-    public ValueExpression createValueExpression(Object instance, Class<?> expectedType) {
-        if (expectedType == null) {
-            throw new NullPointerException(MessageFactory.get("error.value.expectedType"));
-        }
-
-        return new ValueExpressionLiteral(instance, expectedType);
-    }
-
-    public String getProperty(String key) {
-        if (properties == null) {
-            return null;
-        }
-
-        return properties.getProperty(key);
-    }
-
-    @Override
-    public ELResolver getStreamELResolver() {
-        return new StreamELResolver();
-    }
-
-    @Override
-    public Map<String, Method> getInitFunctionMap() {
-        return new HashMap<String, Method>();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/Messages.properties b/impl/src/main/java/com/sun/el/Messages.properties
deleted file mode 100644
index 802a38a..0000000
--- a/impl/src/main/java/com/sun/el/Messages.properties
+++ /dev/null
@@ -1,79 +0,0 @@
-#
-# Copyright (c) 1997, 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
-#
-
-# General Errors
-error.convert=Cannot convert {0} of type {1} to {2}
-error.compare=Cannot compare {0} to {1}
-error.function=Problems calling function ''{0}''
-error.function.syntax=Syntax error in calling function ''{0}''
-error.unreachable.base=Target Unreachable, identifier ''{0}'' resolved to null
-error.unreachable.property=Target Unreachable, ''{0}'' returned null
-error.resolver.unhandled=ELResolver did not handle type: {0} with property of ''{1}''
-error.resolver.unhandled.null=ELResolver cannot handle a null base Object with identifier ''{0}''
-
-# ValueExpressionLiteral
-error.value.literal.write=ValueExpression is a literal and not writable: {0}
-
-# ExpressionFactoryImpl
-error.null=Expression cannot be null
-error.mixed=Expression cannot contain both '#{..}' and '${..}' : {0}
-error.method=Not a valid MethodExpression : {0}
-error.method.nullParms=Parameter types cannot be null
-error.value.expectedType=Expected type cannot be null
-
-# ExpressionMediator
-error.eval=Error Evaluating {0} : {1}
-
-# ValueSetVisitor
-error.syntax.set=Illegal Syntax for Set Operation
-
-error.syntax.assign=Illegal Syntax for Assign Operation
-
-# ReflectionUtil
-error.method.notfound=Method not found: {0}.{1}({2})
-error.method.ambiguous=Unable to find unambiguous method: {0}.{1}({2})
-error.property.notfound=Property ''{1}'' not found on {0}
-
-# ValidatingVisitor
-error.fnMapper.null=Expression uses functions, but no FunctionMapper was provided
-error.fnMapper.method=Function ''{0}'' not found
-error.fnMapper.paramcount=Function ''{0}'' specifies {1} params, but {2} were supplied
-
-# **ExpressionImpl
-error.context.null=ELContext was null
-
-# ArrayELResolver
-error.array.outofbounds=Index {0} is out of bounds for array of size {1}
-
-# ListELResolver
-error.list.outofbounds=Index {0} is out of bounds for list of size {1}
-
-# BeanELResolver
-error.property.notfound=Property ''{1}'' not found on type: {0}
-error.property.invocation=Property ''{1}'' threw an exception from type: {0}
-error.property.notreadable=Property ''{1}'' doesn't have a 'get' specified on type: {0}
-error.property.notwritable=Property ''{1}'' doesn't have a 'set' specified on type: {0}
-
-# AstValue
-error.method.name=An instance of {0} is specified as the static method name, it
-must be a String
-
-# AstType
-error.class.notfound=The specified class ''{0}'' not found
-
-# AstLambdaExpression
-error.lambda.call=A Lambda expression must return another Lambda expression in this syntax
-error.lambda.parameter.readonly=The Lambda parameter ''{0}'' is not writable
diff --git a/impl/src/main/java/com/sun/el/MethodExpressionImpl.java b/impl/src/main/java/com/sun/el/MethodExpressionImpl.java
deleted file mode 100644
index fb0aea4..0000000
--- a/impl/src/main/java/com/sun/el/MethodExpressionImpl.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el;
-
-import static com.sun.el.util.ReflectionUtil.forName;
-import static com.sun.el.util.ReflectionUtil.toTypeArray;
-import static com.sun.el.util.ReflectionUtil.toTypeNameArray;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.ELResolver;
-import javax.el.Expression;
-import javax.el.ExpressionFactory;
-import javax.el.FunctionMapper;
-import javax.el.MethodExpression;
-import javax.el.MethodInfo;
-import javax.el.MethodNotFoundException;
-import javax.el.PropertyNotFoundException;
-import javax.el.VariableMapper;
-
-import com.sun.el.lang.EvaluationContext;
-import com.sun.el.lang.ExpressionBuilder;
-import com.sun.el.parser.Node;
-
-/**
- * An <code>Expression</code> that refers to a method on an object.
- *
- * <p>
- * The {@link ExpressionFactory#createMethodExpression} method can be used to parse an expression string and return a
- * concrete instance of <code>MethodExpression</code> that encapsulates the parsed expression. The
- * {@link FunctionMapper} is used at parse time, not evaluation time, so one is not needed to evaluate an expression
- * using this class. However, the {@link ELContext} is needed at evaluation time.
- * </p>
- *
- * <p>
- * The {@link #getMethodInfo} and {@link #invoke} methods will evaluate the expression each time they are called. The
- * {@link ELResolver} in the <code>ELContext</code> is used to resolve the top-level variables and to determine the
- * behavior of the <code>.</code> and <code>[]</code> operators. For any of the two methods, the
- * {@link ELResolver#getValue} method is used to resolve all properties up to but excluding the last one. This provides
- * the <code>base</code> object on which the method appears. If the <code>base</code> object is null, a
- * <code>NullPointerException</code> must be thrown. At the last resolution, the final <code>property</code> is then
- * coerced to a <code>String</code>, which provides the name of the method to be found. A method matching the name and
- * expected parameters provided at parse time is found and it is either queried or invoked (depending on the method
- * called on this <code>MethodExpression</code>).
- * </p>
- *
- * <p>
- * See the notes about comparison, serialization and immutability in the {@link Expression} javadocs.
- *
- * @see javax.el.ELResolver
- * @see javax.el.Expression
- * @see javax.el.ExpressionFactory
- * @see javax.el.MethodExpression
- *
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class MethodExpressionImpl extends MethodExpression implements Externalizable {
-
-    private Class<?> expectedType;
-    private String expr;
-    private FunctionMapper fnMapper;
-    private VariableMapper varMapper;
-    private Class<?>[] paramTypes;
-
-    private transient Node node;
-
-    public MethodExpressionImpl() {
-        super();
-    }
-
-    /**
-     * @param expr the expression
-     * @param node the node
-     * @param fnMapper the function mapper
-     * @param varMapper the variable mapper
-     * @param expectedType expected return type of method
-     * @param paramTypes the method parameters
-     */
-    public MethodExpressionImpl(String expr, Node node, FunctionMapper fnMapper, VariableMapper varMapper, Class<?> expectedType, Class<?>[] paramTypes) {
-        super();
-        this.expr = expr;
-        this.node = node;
-        this.fnMapper = fnMapper;
-        this.varMapper = varMapper;
-        this.expectedType = expectedType;
-        this.paramTypes = paramTypes;
-    }
-
-    /**
-     * Determines whether the specified object is equal to this <code>Expression</code>.
-     *
-     * <p>
-     * The result is <code>true</code> if and only if the argument is not <code>null</code>, is an <code>Expression</code>
-     * object that is the of the same type (<code>ValueExpression</code> or <code>MethodExpression</code>), and has an
-     * identical parsed representation.
-     * </p>
-     *
-     * <p>
-     * Note that two expressions can be equal if their expression Strings are different. For example,
-     * <code>${fn1:foo()}</code> and <code>${fn2:foo()}</code> are equal if their corresponding <code>FunctionMapper</code>s
-     * mapped <code>fn1:foo</code> and <code>fn2:foo</code> to the same method.
-     * </p>
-     *
-     * @param obj the <code>Object</code> to test for equality.
-     * @return <code>true</code> if <code>obj</code> equals this <code>Expression</code>; <code>false</code> otherwise.
-     * @see java.util.Hashtable
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof MethodExpressionImpl) {
-            MethodExpressionImpl methodExpressionImpl = (MethodExpressionImpl) obj;
-            return getNode().equals(methodExpressionImpl.getNode());
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns the original String used to create this <code>Expression</code>, unmodified.
-     *
-     * <p>
-     * 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).
-     * </p>
-     *
-     * <p>
-     * 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 <code>Expression</code>.
-     * </p>
-     *
-     * @return The original expression String.
-     *
-     * @see javax.el.Expression#getExpressionString()
-     */
-    @Override
-    public String getExpressionString() {
-        return expr;
-    }
-
-    /**
-     * Evaluates the expression relative to the provided context, and returns information about the actual referenced
-     * method.
-     *
-     * @param context The context of this evaluation
-     * @return an instance of <code>MethodInfo</code> containing information about the method the expression evaluated to.
-     * @throws NullPointerException if context is <code>null</code> or the base object is <code>null</code> on the last
-     * resolution.
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws MethodNotFoundException if no suitable method can be found.
-     * @throws ELException 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.
-     * @see javax.el.MethodExpression#getMethodInfo(javax.el.ELContext)
-     */
-    @Override
-    public MethodInfo getMethodInfo(ELContext context) throws PropertyNotFoundException, MethodNotFoundException, ELException {
-        return getNode().getMethodInfo(new EvaluationContext(context, fnMapper, varMapper), paramTypes);
-    }
-
-    /**
-     * @return The Node for the expression
-     * @throws ELException
-     */
-    private Node getNode() throws ELException {
-        if (node == null) {
-            node = ExpressionBuilder.createNode(expr);
-        }
-
-        return node;
-    }
-
-    /**
-     * Returns the hash code for this <code>Expression</code>.
-     *
-     * <p>
-     * See the note in the {@link #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 <code>equals(Object)</code> method, then calling the
-     * <code>hashCode</code> method on each of the two objects must produce the same integer result. Implementations must
-     * take special note and implement <code>hashCode</code> correctly.
-     * </p>
-     *
-     * @return The hash code for this <code>Expression</code>.
-     * @see #equals
-     * @see java.util.Hashtable
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        return getNode().hashCode();
-    }
-
-    /**
-     * 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.
-     *
-     * @param context The context of this evaluation.
-     * @param params The parameters to pass to the method, or <code>null</code> if no parameters.
-     * @return the result of the method invocation (<code>null</code> if the method has a <code>void</code> return type).
-     * @throws NullPointerException if context is <code>null</code> or the base object is <code>null</code> on the last
-     * resolution.
-     * @throws PropertyNotFoundException if one of the property resolutions failed because a specified variable or property
-     * does not exist or is not readable.
-     * @throws MethodNotFoundException if no suitable method can be found.
-     * @throws ELException 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
-     * <code>InvocationTargetException</code>, extract its <code>cause</code> and pass it to the <code>ELException</code>
-     * constructor.
-     * @see javax.el.MethodExpression#invoke(javax.el.ELContext, java.lang.Object[])
-     */
-    @Override
-    public Object invoke(ELContext context, Object[] params) throws PropertyNotFoundException, MethodNotFoundException, ELException {
-        EvaluationContext ctx = new EvaluationContext(context, fnMapper, varMapper);
-        ctx.notifyBeforeEvaluation(expr);
-
-        Object obj = getNode().invoke(ctx, paramTypes, params);
-
-        ctx.notifyAfterEvaluation(expr);
-        return obj;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
-     */
-    @Override
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        expr = in.readUTF();
-        String type = in.readUTF();
-
-        if (!"".equals(type)) {
-            expectedType = forName(type);
-        }
-
-        paramTypes = toTypeArray(((String[]) in.readObject()));
-        fnMapper = (FunctionMapper) in.readObject();
-        varMapper = (VariableMapper) in.readObject();
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
-     */
-    @Override
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeUTF(expr);
-        out.writeUTF(expectedType != null ? expectedType.getName() : "");
-        out.writeObject(toTypeNameArray(paramTypes));
-        out.writeObject(fnMapper);
-        out.writeObject(varMapper);
-    }
-
-    @Override
-    public boolean isLiteralText() {
-        return false;
-    }
-
-    @Override
-    public boolean isParametersProvided() {
-        return getNode().isParametersProvided();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/MethodExpressionLiteral.java b/impl/src/main/java/com/sun/el/MethodExpressionLiteral.java
deleted file mode 100644
index ae2b5b6..0000000
--- a/impl/src/main/java/com/sun/el/MethodExpressionLiteral.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el;
-
-import static com.sun.el.util.ReflectionUtil.toTypeArray;
-import static com.sun.el.util.ReflectionUtil.toTypeNameArray;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.MethodExpression;
-import javax.el.MethodInfo;
-
-import com.sun.el.util.ReflectionUtil;
-
-public class MethodExpressionLiteral extends MethodExpression implements Externalizable {
-
-    private Class<?> expectedType;
-    private String expr;
-    private Class<?>[] paramTypes;
-
-    public MethodExpressionLiteral() {
-        // do nothing
-    }
-
-    public MethodExpressionLiteral(String expr, Class<?> expectedType, Class<?>[] paramTypes) {
-        this.expr = expr;
-        this.expectedType = expectedType;
-        this.paramTypes = paramTypes;
-    }
-
-    @Override
-    public MethodInfo getMethodInfo(ELContext context) throws ELException {
-        return new MethodInfo(expr, expectedType, paramTypes);
-    }
-
-    @Override
-    public Object invoke(ELContext context, Object[] params) throws ELException {
-        if (expectedType == null) {
-            return expr;
-        }
-
-        try {
-            return context.convertToType(expr, expectedType);
-        } catch (Exception ex) {
-            throw new ELException(ex);
-        }
-    }
-
-    @Override
-    public String getExpressionString() {
-        return expr;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return obj instanceof MethodExpressionLiteral && this.hashCode() == obj.hashCode();
-    }
-
-    @Override
-    public int hashCode() {
-        return expr.hashCode();
-    }
-
-    @Override
-    public boolean isLiteralText() {
-        return true;
-    }
-
-    @Override
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        expr = in.readUTF();
-        String type = in.readUTF();
-
-        if (!"".equals(type)) {
-            expectedType = ReflectionUtil.forName(type);
-        }
-
-        paramTypes = toTypeArray(((String[]) in.readObject()));
-    }
-
-    @Override
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeUTF(expr);
-        out.writeUTF(expectedType != null ? expectedType.getName() : "");
-        out.writeObject(toTypeNameArray(paramTypes));
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/ValueExpressionImpl.java b/impl/src/main/java/com/sun/el/ValueExpressionImpl.java
deleted file mode 100644
index 7f476eb..0000000
--- a/impl/src/main/java/com/sun/el/ValueExpressionImpl.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el;
-
-import static com.sun.el.util.ReflectionUtil.forName;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.ELResolver;
-import javax.el.Expression;
-import javax.el.ExpressionFactory;
-import javax.el.FunctionMapper;
-import javax.el.PropertyNotFoundException;
-import javax.el.PropertyNotWritableException;
-import javax.el.ValueExpression;
-import javax.el.ValueReference;
-import javax.el.VariableMapper;
-
-import com.sun.el.lang.EvaluationContext;
-import com.sun.el.lang.ExpressionBuilder;
-import com.sun.el.parser.AstLiteralExpression;
-import com.sun.el.parser.Node;
-
-/**
- * An <code>Expression</code> that can get or set a value.
- *
- * <p>
- * In previous incarnations of this API, expressions could only be read. <code>ValueExpression</code> objects can now be
- * used both to retrieve a value and to set a value. Expressions that can have a value set on them are referred to as
- * l-value expressions. Those that cannot are referred to as r-value expressions. Not all r-value expressions can be
- * used as l-value expressions (e.g. <code>"${1+1}"</code> or <code>"${firstName} ${lastName}"</code>). See the EL
- * Specification for details. Expressions that cannot be used as l-values must always return <code>true</code> from
- * <code>isReadOnly()</code>.
- * </p>
- *
- * <p>
- * The {@link ExpressionFactory#createValueExpression} method can be used to parse an expression string and return a
- * concrete instance of <code>ValueExpression</code> that encapsulates the parsed expression. The {@link FunctionMapper}
- * is used at parse time, not evaluation time, so one is not needed to evaluate an expression using this class. However,
- * the {@link ELContext} is needed at evaluation time.
- * </p>
- *
- * <p>
- * The {@link #getValue}, {@link #setValue}, {@link #isReadOnly} and {@link #getType} methods will evaluate the
- * expression each time they are called. The {@link ELResolver} in the <code>ELContext</code> is used to resolve the
- * top-level variables and to determine the behavior of the <code>.</code> and <code>[]</code> operators. For any of the
- * four methods, the {@link ELResolver#getValue} method is used to resolve all properties up to but excluding the last
- * one. This provides the <code>base</code> object. At the last resolution, the <code>ValueExpression</code> will call
- * the corresponding {@link ELResolver#getValue}, {@link ELResolver#setValue}, {@link ELResolver#isReadOnly} or
- * {@link ELResolver#getType} method, depending on which was called on the <code>ValueExpression</code>.
- * </p>
- *
- * <p>
- * See the notes about comparison, serialization and immutability in the {@link Expression} javadocs.
- *
- * @see javax.el.ELResolver
- * @see javax.el.Expression
- * @see javax.el.ExpressionFactory
- * @see javax.el.ValueExpression
- *
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: dochez $
- */
-public final class ValueExpressionImpl extends ValueExpression implements Externalizable {
-
-    private Class<?> expectedType;
-    private String expr;
-    private FunctionMapper fnMapper;
-    private VariableMapper varMapper;
-    private transient Node node;
-
-    public ValueExpressionImpl() {
-
-    }
-
-    public ValueExpressionImpl(String expr, Node node, FunctionMapper fnMapper, VariableMapper varMapper, Class<?> expectedType) {
-        this.expr = expr;
-        this.node = node;
-        this.fnMapper = fnMapper;
-        this.varMapper = varMapper;
-        this.expectedType = expectedType;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof ValueExpressionImpl) {
-            ValueExpressionImpl valueExpressionImpl = (ValueExpressionImpl) obj;
-            return getNode().equals(valueExpressionImpl.getNode());
-        }
-
-        return false;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.ValueExpression#getExpectedType()
-     */
-    @Override
-    public Class<?> getExpectedType() {
-        return expectedType;
-    }
-
-    /**
-     * Returns the type the result of the expression will be coerced to after evaluation.
-     *
-     * @return the <code>expectedType</code> passed to the <code>ExpressionFactory.createValueExpression</code> method that
-     * created this <code>ValueExpression</code>.
-     *
-     * @see javax.el.Expression#getExpressionString()
-     */
-    @Override
-    public String getExpressionString() {
-        return expr;
-    }
-
-    /**
-     * @return The Node for the expression
-     * @throws ELException
-     */
-    private Node getNode() throws ELException {
-        if (node == null) {
-            node = ExpressionBuilder.createNode(expr);
-        }
-
-        return this.node;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.ValueExpression#getType(javax.el.ELContext)
-     */
-    @Override
-    public Class<?> getType(ELContext context) throws PropertyNotFoundException, ELException {
-        return getNode().getType(new EvaluationContext(context, fnMapper, varMapper));
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.ValueExpression#getValueReference(javax.el.ELContext)
-     */
-    @Override
-    public ValueReference getValueReference(ELContext context) throws PropertyNotFoundException, ELException {
-        return getNode().getValueReference(new EvaluationContext(context, fnMapper, varMapper));
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.ValueExpression#getValue(javax.el.ELContext)
-     */
-    @Override
-    public Object getValue(ELContext context) throws PropertyNotFoundException, ELException {
-        EvaluationContext ctx = new EvaluationContext(context, fnMapper, varMapper);
-        ctx.notifyBeforeEvaluation(expr);
-
-        Object value = getNode().getValue(ctx);
-
-        if (expectedType != null) {
-            try {
-                value = ctx.convertToType(value, expectedType);
-            } catch (IllegalArgumentException ex) {
-                throw new ELException(ex);
-            }
-        }
-        ctx.notifyAfterEvaluation(expr);
-        return value;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        return getNode().hashCode();
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.ValueExpression#isLiteralText()
-     */
-    @Override
-    public boolean isLiteralText() {
-        try {
-            return getNode() instanceof AstLiteralExpression;
-        } catch (ELException ele) {
-            return false;
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.ValueExpression#isReadOnly(javax.el.ELContext)
-     */
-    @Override
-    public boolean isReadOnly(ELContext context) throws PropertyNotFoundException, ELException {
-        return getNode().isReadOnly(new EvaluationContext(context, fnMapper, varMapper));
-    }
-
-    @Override
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        expr = in.readUTF();
-        String type = in.readUTF();
-        if (!"".equals(type)) {
-            expectedType = forName(type);
-        }
-        fnMapper = (FunctionMapper) in.readObject();
-        varMapper = (VariableMapper) in.readObject();
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.ValueExpression#setValue(javax.el.ELContext, java.lang.Object)
-     */
-    @Override
-    public void setValue(ELContext context, Object value) throws PropertyNotFoundException, PropertyNotWritableException, ELException {
-        getNode().setValue(new EvaluationContext(context, fnMapper, varMapper), value);
-    }
-
-    @Override
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeUTF(expr);
-        out.writeUTF(expectedType != null ? expectedType.getName() : "");
-        out.writeObject(fnMapper);
-        out.writeObject(varMapper);
-    }
-
-    @Override
-    public String toString() {
-        return "ValueExpression[" + expr + "]";
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/ValueExpressionLiteral.java b/impl/src/main/java/com/sun/el/ValueExpressionLiteral.java
deleted file mode 100644
index 7dc21e9..0000000
--- a/impl/src/main/java/com/sun/el/ValueExpressionLiteral.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el;
-
-import static com.sun.el.util.ReflectionUtil.forName;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.PropertyNotWritableException;
-import javax.el.ValueExpression;
-
-import com.sun.el.util.MessageFactory;
-
-public final class ValueExpressionLiteral extends ValueExpression implements Externalizable {
-
-    private static final long serialVersionUID = 1L;
-
-    private Object value;
-    private Class<?> expectedType;
-
-    public ValueExpressionLiteral() {
-        super();
-    }
-
-    public ValueExpressionLiteral(Object value, Class<?> expectedType) {
-        this.value = value;
-        this.expectedType = expectedType;
-    }
-
-    @Override
-    public Object getValue(ELContext context) {
-        if (expectedType != null) {
-            try {
-                return context.convertToType(value, expectedType);
-            } catch (IllegalArgumentException ex) {
-                throw new ELException(ex);
-            }
-        }
-
-        return value;
-    }
-
-    @Override
-    public void setValue(ELContext context, Object value) {
-        throw new PropertyNotWritableException(MessageFactory.get("error.value.literal.write", value));
-    }
-
-    @Override
-    public boolean isReadOnly(ELContext context) {
-        return true;
-    }
-
-    @Override
-    public Class<?> getType(ELContext context) {
-        return value != null ? value.getClass() : null;
-    }
-
-    @Override
-    public Class<?> getExpectedType() {
-        return expectedType;
-    }
-
-    @Override
-    public String getExpressionString() {
-        return value != null ? value.toString() : null;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        return obj instanceof ValueExpressionLiteral && this.equals((ValueExpressionLiteral) obj);
-    }
-
-    public boolean equals(ValueExpressionLiteral ve) {
-        return (ve != null && (this.value != null && ve.value != null && (this.value == ve.value || this.value.equals(ve.value))));
-    }
-
-    @Override
-    public int hashCode() {
-        return value != null ? value.hashCode() : 0;
-    }
-
-    @Override
-    public boolean isLiteralText() {
-        return true;
-    }
-
-    @Override
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(value);
-        out.writeUTF(expectedType != null ? expectedType.getName() : "");
-    }
-
-    @Override
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        value = in.readObject();
-        String type = in.readUTF();
-        if (!"".equals(type)) {
-            expectedType = forName(type);
-        }
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/lang/ELArithmetic.java b/impl/src/main/java/com/sun/el/lang/ELArithmetic.java
deleted file mode 100644
index 37092d4..0000000
--- a/impl/src/main/java/com/sun/el/lang/ELArithmetic.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.lang;
-
-import static java.math.BigDecimal.ROUND_HALF_UP;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import com.sun.el.util.MessageFactory;
-
-/**
- * A helper class of Arithmetic defined by the Jakarta Expression Specification
- *
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public abstract class ELArithmetic {
-
-    public final static class BigDecimalDelegate extends ELArithmetic {
-
-        @Override
-        protected Number add(Number num0, Number num1) {
-            return ((BigDecimal) num0).add((BigDecimal) num1);
-        }
-
-        @Override
-        protected Number coerce(Number num) {
-            if (num instanceof BigDecimal) {
-                return num;
-            }
-            if (num instanceof BigInteger) {
-                return new BigDecimal((BigInteger) num);
-            }
-
-            return new BigDecimal(num.doubleValue());
-        }
-
-        @Override
-        protected Number coerce(String str) {
-            return new BigDecimal(str);
-        }
-
-        @Override
-        protected Number divide(Number num0, Number num1) {
-            return ((BigDecimal) num0).divide((BigDecimal) num1, ROUND_HALF_UP);
-        }
-
-        @Override
-        protected Number subtract(Number num0, Number num1) {
-            return ((BigDecimal) num0).subtract((BigDecimal) num1);
-        }
-
-        @Override
-        protected Number mod(Number num0, Number num1) {
-            return Double.valueOf(num0.doubleValue() % num1.doubleValue());
-        }
-
-        @Override
-        protected Number multiply(Number num0, Number num1) {
-            return ((BigDecimal) num0).multiply((BigDecimal) num1);
-        }
-
-        @Override
-        public boolean matches(Object obj0, Object obj1) {
-            return (obj0 instanceof BigDecimal || obj1 instanceof BigDecimal);
-        }
-    }
-
-    public final static class BigIntegerDelegate extends ELArithmetic {
-
-        @Override
-        protected Number add(Number num0, Number num1) {
-            return ((BigInteger) num0).add((BigInteger) num1);
-        }
-
-        @Override
-        protected Number coerce(Number num) {
-            if (num instanceof BigInteger) {
-                return num;
-            }
-
-            return new BigInteger(num.toString());
-        }
-
-        @Override
-        protected Number coerce(String str) {
-            return new BigInteger(str);
-        }
-
-        @Override
-        protected Number divide(Number num0, Number num1) {
-            return (new BigDecimal((BigInteger) num0)).divide(new BigDecimal((BigInteger) num1), ROUND_HALF_UP);
-        }
-
-        @Override
-        protected Number multiply(Number num0, Number num1) {
-            return ((BigInteger) num0).multiply((BigInteger) num1);
-        }
-
-        @Override
-        protected Number mod(Number num0, Number num1) {
-            return ((BigInteger) num0).mod((BigInteger) num1);
-        }
-
-        @Override
-        protected Number subtract(Number num0, Number num1) {
-            return ((BigInteger) num0).subtract((BigInteger) num1);
-        }
-
-        @Override
-        public boolean matches(Object obj0, Object obj1) {
-            return obj0 instanceof BigInteger || obj1 instanceof BigInteger;
-        }
-    }
-
-    public final static class DoubleDelegate extends ELArithmetic {
-
-        @Override
-        protected Number add(Number num0, Number num1) {
-            // could only be one of these
-            if (num0 instanceof BigDecimal) {
-                return ((BigDecimal) num0).add(new BigDecimal(num1.doubleValue()));
-            }
-            if (num1 instanceof BigDecimal) {
-                return ((new BigDecimal(num0.doubleValue()).add((BigDecimal) num1)));
-            }
-
-            return Double.valueOf(num0.doubleValue() + num1.doubleValue());
-        }
-
-        @Override
-        protected Number coerce(Number num) {
-            if (num instanceof Double) {
-                return num;
-            }
-            if (num instanceof BigInteger) {
-                return new BigDecimal((BigInteger) num);
-            }
-
-            return Double.valueOf(num.doubleValue());
-        }
-
-        @Override
-        protected Number coerce(String str) {
-            return Double.valueOf(str);
-        }
-
-        @Override
-        protected Number divide(Number num0, Number num1) {
-            return Double.valueOf(num0.doubleValue() / num1.doubleValue());
-        }
-
-        @Override
-        protected Number mod(Number num0, Number num1) {
-            return Double.valueOf(num0.doubleValue() % num1.doubleValue());
-        }
-
-        @Override
-        protected Number subtract(Number num0, Number num1) {
-            // could only be one of these
-            if (num0 instanceof BigDecimal) {
-                return ((BigDecimal) num0).subtract(new BigDecimal(num1.doubleValue()));
-            }
-
-            if (num1 instanceof BigDecimal) {
-                return ((new BigDecimal(num0.doubleValue()).subtract((BigDecimal) num1)));
-            }
-
-            return Double.valueOf(num0.doubleValue() - num1.doubleValue());
-        }
-
-        @Override
-        protected Number multiply(Number num0, Number num1) {
-            // could only be one of these
-            if (num0 instanceof BigDecimal) {
-                return ((BigDecimal) num0).multiply(new BigDecimal(num1.doubleValue()));
-            }
-            if (num1 instanceof BigDecimal) {
-                return ((new BigDecimal(num0.doubleValue()).multiply((BigDecimal) num1)));
-            }
-
-            return Double.valueOf(num0.doubleValue() * num1.doubleValue());
-        }
-
-        @Override
-        public boolean matches(Object obj0, Object obj1) {
-            return (obj0 instanceof Double || obj1 instanceof Double || obj0 instanceof Float || obj1 instanceof Float
-                    || (obj0 != null && (Double.TYPE == obj0.getClass() || Float.TYPE == obj0.getClass()))
-                    || (obj1 != null && (Double.TYPE == obj1.getClass() || Float.TYPE == obj1.getClass()))
-                    || (obj0 instanceof String && ELSupport.isStringFloat((String) obj0))
-                    || (obj1 instanceof String && ELSupport.isStringFloat((String) obj1)));
-        }
-    }
-
-    public final static class LongDelegate extends ELArithmetic {
-
-        @Override
-        protected Number add(Number num0, Number num1) {
-            return Long.valueOf(num0.longValue() + num1.longValue());
-        }
-
-        @Override
-        protected Number coerce(Number num) {
-            if (num instanceof Long) {
-                return num;
-            }
-
-            return Long.valueOf(num.longValue());
-        }
-
-        @Override
-        protected Number coerce(String str) {
-            return Long.valueOf(str);
-        }
-
-        @Override
-        protected Number divide(Number num0, Number num1) {
-            return Long.valueOf(num0.longValue() / num1.longValue());
-        }
-
-        @Override
-        protected Number mod(Number num0, Number num1) {
-            return Long.valueOf(num0.longValue() % num1.longValue());
-        }
-
-        @Override
-        protected Number subtract(Number num0, Number num1) {
-            return Long.valueOf(num0.longValue() - num1.longValue());
-        }
-
-        @Override
-        protected Number multiply(Number num0, Number num1) {
-            return Long.valueOf(num0.longValue() * num1.longValue());
-        }
-
-        @Override
-        public boolean matches(Object obj0, Object obj1) {
-            return obj0 instanceof Long || obj1 instanceof Long;
-        }
-    }
-
-    public static final BigDecimalDelegate BIGDECIMAL = new BigDecimalDelegate();
-    public static final BigIntegerDelegate BIGINTEGER = new BigIntegerDelegate();
-    public static final DoubleDelegate DOUBLE = new DoubleDelegate();
-    public static final LongDelegate LONG = new LongDelegate();
-    private static final Long ZERO = Long.valueOf(0);
-
-    public final static Number add(final Object obj0, final Object obj1) {
-        if (obj0 == null && obj1 == null) {
-            return Long.valueOf(0);
-        }
-
-        final ELArithmetic delegate;
-        if (BIGDECIMAL.matches(obj0, obj1)) {
-            delegate = BIGDECIMAL;
-        } else if (DOUBLE.matches(obj0, obj1)) {
-            delegate = DOUBLE;
-        } else if (BIGINTEGER.matches(obj0, obj1)) {
-            delegate = BIGINTEGER;
-        } else {
-            delegate = LONG;
-        }
-
-        Number num0 = delegate.coerce(obj0);
-        Number num1 = delegate.coerce(obj1);
-
-        return delegate.add(num0, num1);
-    }
-
-    public final static Number mod(final Object obj0, final Object obj1) {
-        if (obj0 == null && obj1 == null) {
-            return Long.valueOf(0);
-        }
-
-        final ELArithmetic delegate;
-        if (BIGDECIMAL.matches(obj0, obj1)) {
-            delegate = BIGDECIMAL;
-        } else if (DOUBLE.matches(obj0, obj1)) {
-            delegate = DOUBLE;
-        } else if (BIGINTEGER.matches(obj0, obj1)) {
-            delegate = BIGINTEGER;
-        } else {
-            delegate = LONG;
-        }
-
-        Number num0 = delegate.coerce(obj0);
-        Number num1 = delegate.coerce(obj1);
-
-        return delegate.mod(num0, num1);
-    }
-
-    public final static Number subtract(final Object obj0, final Object obj1) {
-        if (obj0 == null && obj1 == null) {
-            return Long.valueOf(0);
-        }
-
-        final ELArithmetic delegate;
-        if (BIGDECIMAL.matches(obj0, obj1)) {
-            delegate = BIGDECIMAL;
-        } else if (DOUBLE.matches(obj0, obj1)) {
-            delegate = DOUBLE;
-        } else if (BIGINTEGER.matches(obj0, obj1)) {
-            delegate = BIGINTEGER;
-        } else {
-            delegate = LONG;
-        }
-
-        Number num0 = delegate.coerce(obj0);
-        Number num1 = delegate.coerce(obj1);
-
-        return delegate.subtract(num0, num1);
-    }
-
-    public final static Number divide(final Object obj0, final Object obj1) {
-        if (obj0 == null && obj1 == null) {
-            return ZERO;
-        }
-
-        final ELArithmetic delegate;
-        if (BIGDECIMAL.matches(obj0, obj1)) {
-            delegate = BIGDECIMAL;
-        } else if (BIGINTEGER.matches(obj0, obj1)) {
-            delegate = BIGDECIMAL;
-        } else {
-            delegate = DOUBLE;
-        }
-
-        Number num0 = delegate.coerce(obj0);
-        Number num1 = delegate.coerce(obj1);
-
-        return delegate.divide(num0, num1);
-    }
-
-    public final static Number multiply(final Object obj0, final Object obj1) {
-        if (obj0 == null && obj1 == null) {
-            return Long.valueOf(0);
-        }
-
-        final ELArithmetic delegate;
-        if (BIGDECIMAL.matches(obj0, obj1)) {
-            delegate = BIGDECIMAL;
-        } else if (DOUBLE.matches(obj0, obj1)) {
-            delegate = DOUBLE;
-        } else if (BIGINTEGER.matches(obj0, obj1)) {
-            delegate = BIGINTEGER;
-        } else {
-            delegate = LONG;
-        }
-
-        Number num0 = delegate.coerce(obj0);
-        Number num1 = delegate.coerce(obj1);
-
-        return delegate.multiply(num0, num1);
-    }
-
-    public final static boolean isNumber(final Object obj) {
-        return (obj != null && isNumberType(obj.getClass()));
-    }
-
-    public final static boolean isNumberType(final Class type) {
-        return type == Long.TYPE || type == Double.TYPE || type == Byte.TYPE || type == Short.TYPE || type == Integer.TYPE || type == Float.TYPE
-                || Number.class.isAssignableFrom(type);
-    }
-
-    /**
-     *
-     */
-    protected ELArithmetic() {
-        super();
-    }
-
-    protected abstract Number add(final Number num0, final Number num1);
-
-    protected abstract Number multiply(final Number num0, final Number num1);
-
-    protected abstract Number subtract(final Number num0, final Number num1);
-
-    protected abstract Number mod(final Number num0, final Number num1);
-
-    protected abstract Number coerce(final Number num);
-
-    protected final Number coerce(final Object obj) {
-
-        if (isNumber(obj)) {
-            return coerce((Number) obj);
-        }
-        if (obj instanceof String) {
-            return coerce((String) obj);
-        }
-        if (obj == null || "".equals(obj)) {
-            return coerce(ZERO);
-        }
-
-        Class objType = obj.getClass();
-        if (Character.class.equals(objType) || Character.TYPE == objType) {
-            return coerce(Short.valueOf((short) ((Character) obj).charValue()));
-        }
-
-        throw new IllegalArgumentException(MessageFactory.get("el.convert", obj, objType));
-    }
-
-    protected abstract Number coerce(final String str);
-
-    protected abstract Number divide(final Number num0, final Number num1);
-
-    protected abstract boolean matches(final Object obj0, final Object obj1);
-
-}
diff --git a/impl/src/main/java/com/sun/el/lang/ELSupport.java b/impl/src/main/java/com/sun/el/lang/ELSupport.java
deleted file mode 100644
index f0a8368..0000000
--- a/impl/src/main/java/com/sun/el/lang/ELSupport.java
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.lang;
-
-import java.beans.PropertyEditor;
-import java.beans.PropertyEditorManager;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import javax.el.ELException;
-import javax.el.PropertyNotFoundException;
-
-import com.sun.el.util.MessageFactory;
-
-/**
- * A helper class that implements the Jakarta Expression Specification
- *
- * @author Jacob Hookom [jacob@hookom.net]
- * @author Kin-man Chung
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public class ELSupport {
-
-    private final static Long ZERO = Long.valueOf(0L);
-
-    public final static void throwUnhandled(Object base, Object property) throws ELException {
-        if (base == null) {
-            throw new PropertyNotFoundException(MessageFactory.get("error.resolver.unhandled.null", property));
-        } else {
-            throw new PropertyNotFoundException(MessageFactory.get("error.resolver.unhandled", base.getClass(), property));
-        }
-    }
-
-    /**
-     * @param obj0 First object to be compared
-     * @param obj1 Second object to be compared
-     * @return The result (an int with values -1, 0, or 1) of the comparison
-     * @throws ELException when something goes wrong
-     */
-    public final static int compare(final Object obj0, final Object obj1) throws ELException {
-        if (obj0 == obj1 || equals(obj0, obj1)) {
-            return 0;
-        }
-        if (isBigDecimalOp(obj0, obj1)) {
-            BigDecimal bd0 = (BigDecimal) coerceToNumber(obj0, BigDecimal.class);
-            BigDecimal bd1 = (BigDecimal) coerceToNumber(obj1, BigDecimal.class);
-            return bd0.compareTo(bd1);
-        }
-        if (isDoubleOp(obj0, obj1)) {
-            Double d0 = (Double) coerceToNumber(obj0, Double.class);
-            Double d1 = (Double) coerceToNumber(obj1, Double.class);
-            return d0.compareTo(d1);
-        }
-        if (isBigIntegerOp(obj0, obj1)) {
-            BigInteger bi0 = (BigInteger) coerceToNumber(obj0, BigInteger.class);
-            BigInteger bi1 = (BigInteger) coerceToNumber(obj1, BigInteger.class);
-            return bi0.compareTo(bi1);
-        }
-        if (isLongOp(obj0, obj1)) {
-            Long l0 = (Long) coerceToNumber(obj0, Long.class);
-            Long l1 = (Long) coerceToNumber(obj1, Long.class);
-            return l0.compareTo(l1);
-        }
-        if (obj0 instanceof String || obj1 instanceof String) {
-            return coerceToString(obj0).compareTo(coerceToString(obj1));
-        }
-        if (obj0 instanceof Comparable) {
-            // Safe cast
-            @SuppressWarnings("unchecked")
-            Comparable<Object> cobj0 = (Comparable) obj0;
-            return (obj1 != null) ? cobj0.compareTo(obj1) : 1;
-        }
-        if (obj1 instanceof Comparable) {
-            // Safe cast
-            @SuppressWarnings("unchecked")
-            Comparable<Object> cobj1 = (Comparable) obj1;
-            return (obj0 != null) ? -(cobj1.compareTo(obj0)) : -1;
-        }
-        throw new ELException(MessageFactory.get("error.compare", obj0, obj1));
-    }
-
-    /**
-     * @param obj0 Fisrt object to be compared
-     * @param obj1 Second object to be compared
-     * @return true if the objects compared equal
-     * @throws ELException when something goes wrong
-     */
-    public final static boolean equals(final Object obj0, final Object obj1) throws ELException {
-        if (obj0 == obj1) {
-            return true;
-        }
-        if (obj0 == null || obj1 == null) {
-            return false;
-        }
-        if (obj0 instanceof Boolean || obj1 instanceof Boolean) {
-            return coerceToBoolean(obj0).equals(coerceToBoolean(obj1));
-        }
-        if (obj0.getClass().isEnum()) {
-            return obj0.equals(coerceToEnum(obj1, obj0.getClass()));
-        }
-        if (obj1.getClass().isEnum()) {
-            return obj1.equals(coerceToEnum(obj0, obj1.getClass()));
-        }
-        if (obj0 instanceof String || obj1 instanceof String) {
-            return coerceToString(obj0).equals(coerceToString(obj1));
-        }
-        if (isBigDecimalOp(obj0, obj1)) {
-            BigDecimal bd0 = (BigDecimal) coerceToNumber(obj0, BigDecimal.class);
-            BigDecimal bd1 = (BigDecimal) coerceToNumber(obj1, BigDecimal.class);
-            return bd0.equals(bd1);
-        }
-        if (isDoubleOp(obj0, obj1)) {
-            Double d0 = (Double) coerceToNumber(obj0, Double.class);
-            Double d1 = (Double) coerceToNumber(obj1, Double.class);
-            return d0.equals(d1);
-        }
-        if (isBigIntegerOp(obj0, obj1)) {
-            BigInteger bi0 = (BigInteger) coerceToNumber(obj0, BigInteger.class);
-            BigInteger bi1 = (BigInteger) coerceToNumber(obj1, BigInteger.class);
-            return bi0.equals(bi1);
-        }
-        if (isLongOp(obj0, obj1)) {
-            Long l0 = (Long) coerceToNumber(obj0, Long.class);
-            Long l1 = (Long) coerceToNumber(obj1, Long.class);
-            return l0.equals(l1);
-        } else {
-            return obj0.equals(obj1);
-        }
-    }
-
-    /**
-     * @param obj Object to be coerced
-     * @return The result of coercion
-     */
-    public final static Boolean coerceToBoolean(final Object obj) throws IllegalArgumentException {
-        if (obj == null || "".equals(obj)) {
-            return Boolean.FALSE;
-        }
-        if (obj instanceof Boolean) {
-            return (Boolean) obj;
-        }
-        if (obj instanceof String) {
-            return Boolean.valueOf((String) obj);
-        }
-
-        throw new IllegalArgumentException(MessageFactory.get("error.convert", obj, obj.getClass(), Boolean.class));
-    }
-
-    // Enum types are hard construct. We can declare this as
-    // <T extends Enum<T>> T coerceToEnum(Object, Class<T> type)
-    // but this makes it harder to get the calls right.
-    @SuppressWarnings("unchecked")
-    public final static Enum coerceToEnum(final Object obj, Class type) {
-        if (obj == null || "".equals(obj)) {
-            return null;
-        }
-        if (obj.getClass().isEnum()) {
-            return (Enum) obj;
-        }
-        return Enum.valueOf(type, obj.toString());
-    }
-
-    public final static Character coerceToCharacter(final Object obj) throws IllegalArgumentException {
-        if (obj == null || "".equals(obj)) {
-            return Character.valueOf((char) 0);
-        }
-        if (obj instanceof String) {
-            return Character.valueOf(((String) obj).charAt(0));
-        }
-        if (ELArithmetic.isNumber(obj)) {
-            return Character.valueOf((char) ((Number) obj).shortValue());
-        }
-        Class objType = obj.getClass();
-        if (obj instanceof Character) {
-            return (Character) obj;
-        }
-
-        throw new IllegalArgumentException(MessageFactory.get("error.convert", obj, objType, Character.class));
-    }
-
-    public final static Number coerceToNumber(final Object obj) {
-        if (obj == null) {
-            return ZERO;
-        } else if (obj instanceof Number) {
-            return (Number) obj;
-        } else {
-            String str = coerceToString(obj);
-            if (isStringFloat(str)) {
-                return toFloat(str);
-            } else {
-                return toNumber(str);
-            }
-        }
-    }
-
-    protected final static Number coerceToNumber(final Number number, final Class type) throws IllegalArgumentException {
-        if (Long.TYPE == type || Long.class.equals(type)) {
-            return Long.valueOf(number.longValue());
-        }
-        if (Double.TYPE == type || Double.class.equals(type)) {
-            return Double.valueOf(number.doubleValue());
-        }
-        if (Integer.TYPE == type || Integer.class.equals(type)) {
-            return Integer.valueOf(number.intValue());
-        }
-        if (BigInteger.class.equals(type)) {
-            if (number instanceof BigDecimal) {
-                return ((BigDecimal) number).toBigInteger();
-            }
-            if (number instanceof BigInteger) {
-                return number;
-            }
-            return BigInteger.valueOf(number.longValue());
-        }
-        if (BigDecimal.class.equals(type)) {
-            if (number instanceof BigDecimal) {
-                return number;
-            }
-            if (number instanceof BigInteger) {
-                return new BigDecimal((BigInteger) number);
-            }
-            if (number instanceof Long) {
-                return new BigDecimal((Long) number);
-            }
-            return new BigDecimal(number.doubleValue());
-        }
-        if (Byte.TYPE == type || Byte.class.equals(type)) {
-            return Byte.valueOf(number.byteValue());
-        }
-        if (Short.TYPE == type || Short.class.equals(type)) {
-            return Short.valueOf(number.shortValue());
-        }
-        if (Float.TYPE == type || Float.class.equals(type)) {
-            return Float.valueOf(number.floatValue());
-        }
-
-        throw new IllegalArgumentException(MessageFactory.get("error.convert", number, number.getClass(), type));
-    }
-
-    public final static Number coerceToNumber(final Object obj, final Class type) throws IllegalArgumentException {
-        if (obj == null || "".equals(obj)) {
-            return coerceToNumber(ZERO, type);
-        }
-        if (obj instanceof String) {
-            return coerceToNumber((String) obj, type);
-        }
-        if (ELArithmetic.isNumber(obj)) {
-            if (obj.getClass().equals(type)) {
-                return (Number) obj;
-            }
-            return coerceToNumber((Number) obj, type);
-        }
-
-        if (obj instanceof Character) {
-            return coerceToNumber(Short.valueOf((short) ((Character) obj).charValue()), type);
-        }
-
-        throw new IllegalArgumentException(MessageFactory.get("error.convert", obj, obj.getClass(), type));
-    }
-
-    protected final static Number coerceToNumber(final String val, final Class type) throws IllegalArgumentException {
-        if (Long.TYPE == type || Long.class.equals(type)) {
-            return Long.valueOf(val);
-        }
-        if (Integer.TYPE == type || Integer.class.equals(type)) {
-            return Integer.valueOf(val);
-        }
-        if (Double.TYPE == type || Double.class.equals(type)) {
-            return Double.valueOf(val);
-        }
-        if (BigInteger.class.equals(type)) {
-            return new BigInteger(val);
-        }
-        if (BigDecimal.class.equals(type)) {
-            return new BigDecimal(val);
-        }
-        if (Byte.TYPE == type || Byte.class.equals(type)) {
-            return Byte.valueOf(val);
-        }
-        if (Short.TYPE == type || Short.class.equals(type)) {
-            return Short.valueOf(val);
-        }
-        if (Float.TYPE == type || Float.class.equals(type)) {
-            return Float.valueOf(val);
-        }
-
-        throw new IllegalArgumentException(MessageFactory.get("error.convert", val, String.class, type));
-    }
-
-    /**
-     * @param obj Object to be coerced
-     * @return The result of coercion
-     */
-    public final static String coerceToString(final Object obj) {
-        if (obj == null) {
-            return "";
-        } else if (obj instanceof String) {
-            return (String) obj;
-        } else if (obj instanceof Enum) {
-            return ((Enum) obj).name();
-        } else {
-            return obj.toString();
-        }
-    }
-
-    public final static void checkType(final Object obj, final Class<?> type) throws IllegalArgumentException {
-        if (String.class.equals(type)) {
-            coerceToString(obj);
-        }
-        if (ELArithmetic.isNumberType(type)) {
-            coerceToNumber(obj, type);
-        }
-        if (Character.class.equals(type) || Character.TYPE == type) {
-            coerceToCharacter(obj);
-        }
-        if (Boolean.class.equals(type) || Boolean.TYPE == type) {
-            coerceToBoolean(obj);
-        }
-        if (type.isEnum()) {
-            coerceToEnum(obj, type);
-        }
-    }
-
-    public final static Object coerceToType(final Object obj, final Class<?> type) throws IllegalArgumentException {
-        return coerceToType(obj, type, false);
-    }
-
-    public final static Object coerceToType(final Object obj, final Class<?> type, boolean isEL22Compatible) throws IllegalArgumentException {
-
-        if (type == null || Object.class.equals(type) || (obj != null && type.isAssignableFrom(obj.getClass()))) {
-            return obj;
-        }
-
-        // New in 3.0
-        if (!isEL22Compatible && obj == null && !type.isPrimitive() && !String.class.equals(type)) {
-            return null;
-        }
-
-        if (String.class.equals(type)) {
-            return coerceToString(obj);
-        }
-        if (ELArithmetic.isNumberType(type)) {
-            return coerceToNumber(obj, type);
-        }
-        if (Character.class.equals(type) || Character.TYPE == type) {
-            return coerceToCharacter(obj);
-        }
-        if (Boolean.class.equals(type) || Boolean.TYPE == type) {
-            return coerceToBoolean(obj);
-        }
-        if (type.isEnum()) {
-            return coerceToEnum(obj, type);
-        }
-
-        if (obj == null) {
-            return null;
-        }
-
-        if (obj instanceof String) {
-            if ("".equals(obj)) {
-                return null;
-            }
-            PropertyEditor editor = PropertyEditorManager.findEditor(type);
-            if (editor != null) {
-                editor.setAsText((String) obj);
-                return editor.getValue();
-            }
-        }
-        throw new IllegalArgumentException(MessageFactory.get("error.convert", obj, obj.getClass(), type));
-    }
-
-    /**
-     * @param obj An array of objects
-     * @return true if the array contains a null, false otherwise
-     */
-    public final static boolean containsNulls(final Object[] obj) {
-        for (int i = 0; i < obj.length; i++) {
-            if (obj[0] == null) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public final static boolean isBigDecimalOp(final Object obj0, final Object obj1) {
-        return (obj0 instanceof BigDecimal || obj1 instanceof BigDecimal);
-    }
-
-    public final static boolean isBigIntegerOp(final Object obj0, final Object obj1) {
-        return (obj0 instanceof BigInteger || obj1 instanceof BigInteger);
-    }
-
-    public final static boolean isDoubleOp(final Object obj0, final Object obj1) {
-        return (obj0 instanceof Double || obj1 instanceof Double || obj0 instanceof Float || obj1 instanceof Float);
-    }
-
-    public final static boolean isDoubleStringOp(final Object obj0, final Object obj1) {
-        return (isDoubleOp(obj0, obj1) || (obj0 instanceof String && isStringFloat((String) obj0)) || (obj1 instanceof String && isStringFloat((String) obj1)));
-    }
-
-    public final static boolean isLongOp(final Object obj0, final Object obj1) {
-        return (obj0 instanceof Long || obj1 instanceof Long || obj0 instanceof Integer || obj1 instanceof Integer || obj0 instanceof Character
-                || obj1 instanceof Character || obj0 instanceof Short || obj1 instanceof Short || obj0 instanceof Byte || obj1 instanceof Byte);
-    }
-
-    public final static boolean isStringFloat(final String str) {
-        int len = str.length();
-        if (len > 1) {
-            for (int i = 0; i < len; i++) {
-                switch (str.charAt(i)) {
-                case 'E':
-                    return true;
-                case 'e':
-                    return true;
-                case '.':
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public final static Number toFloat(final String value) {
-        try {
-            if (Double.parseDouble(value) > Double.MAX_VALUE) {
-                return new BigDecimal(value);
-            } else {
-                return Double.valueOf(value);
-            }
-        } catch (NumberFormatException e0) {
-            return new BigDecimal(value);
-        }
-    }
-
-    public final static Number toNumber(final String value) {
-        try {
-            return Integer.valueOf(Integer.parseInt(value));
-        } catch (NumberFormatException e0) {
-            try {
-                return Long.valueOf(Long.parseLong(value));
-            } catch (NumberFormatException e1) {
-                return new BigInteger(value);
-            }
-        }
-    }
-
-    /**
-     *
-     */
-    public ELSupport() {
-        super();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/lang/EvaluationContext.java b/impl/src/main/java/com/sun/el/lang/EvaluationContext.java
deleted file mode 100644
index 4b07a60..0000000
--- a/impl/src/main/java/com/sun/el/lang/EvaluationContext.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.lang;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.el.ELContext;
-import javax.el.ELResolver;
-import javax.el.EvaluationListener;
-import javax.el.FunctionMapper;
-import javax.el.ImportHandler;
-import javax.el.VariableMapper;
-
-/**
- * The context for Jakarta Expression expression evaluation. This wrapper ELContext captures the function mapper and the
- * variable mapper at the point when the expression is parsed, and only for those functions and variable used in the
- * expression.
- */
-public final class EvaluationContext extends ELContext {
-
-    private final ELContext elContext;
-    private final FunctionMapper fnMapper;
-    private final VariableMapper varMapper;
-
-    public EvaluationContext(ELContext elContext, FunctionMapper fnMapper, VariableMapper varMapper) {
-        this.elContext = elContext;
-        this.fnMapper = fnMapper;
-        this.varMapper = varMapper;
-    }
-
-    public ELContext getELContext() {
-        return elContext;
-    }
-
-    @Override
-    public FunctionMapper getFunctionMapper() {
-        return fnMapper;
-    }
-
-    @Override
-    public VariableMapper getVariableMapper() {
-        return varMapper;
-    }
-
-    @Override
-    public Object getContext(Class key) {
-        return elContext.getContext(key);
-    }
-
-    @Override
-    public ELResolver getELResolver() {
-        return elContext.getELResolver();
-    }
-
-    @Override
-    public boolean isPropertyResolved() {
-        return elContext.isPropertyResolved();
-    }
-
-    @Override
-    public void putContext(Class key, Object contextObject) {
-        elContext.putContext(key, contextObject);
-    }
-
-    @Override
-    public void setPropertyResolved(boolean resolved) {
-        elContext.setPropertyResolved(resolved);
-    }
-
-    @Override
-    public void setPropertyResolved(Object base, Object property) {
-        elContext.setPropertyResolved(base, property);
-    }
-
-    @Override
-    public void addEvaluationListener(EvaluationListener listener) {
-        elContext.addEvaluationListener(listener);
-    }
-
-    @Override
-    public List<EvaluationListener> getEvaluationListeners() {
-        return elContext.getEvaluationListeners();
-    }
-
-    @Override
-    public void notifyBeforeEvaluation(String expr) {
-        elContext.notifyBeforeEvaluation(expr);
-    }
-
-    @Override
-    public void notifyAfterEvaluation(String expr) {
-        elContext.notifyAfterEvaluation(expr);
-    }
-
-    @Override
-    public void notifyPropertyResolved(Object base, Object property) {
-        elContext.notifyPropertyResolved(base, property);
-    }
-
-    @Override
-    public boolean isLambdaArgument(String arg) {
-        return elContext.isLambdaArgument(arg);
-    }
-
-    @Override
-    public Object getLambdaArgument(String arg) {
-        return elContext.getLambdaArgument(arg);
-    }
-
-    @Override
-    public void enterLambdaScope(Map<String, Object> args) {
-        elContext.enterLambdaScope(args);
-    }
-
-    @Override
-    public void exitLambdaScope() {
-        elContext.exitLambdaScope();
-    }
-
-    @Override
-    public Object convertToType(Object obj, Class<?> targetType) {
-        return elContext.convertToType(obj, targetType);
-    }
-
-    @Override
-    public ImportHandler getImportHandler() {
-        return elContext.getImportHandler();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/lang/ExpressionBuilder.java b/impl/src/main/java/com/sun/el/lang/ExpressionBuilder.java
deleted file mode 100644
index e1de322..0000000
--- a/impl/src/main/java/com/sun/el/lang/ExpressionBuilder.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.lang;
-
-import java.io.StringReader;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Method;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.FunctionMapper;
-import javax.el.MethodExpression;
-import javax.el.ValueExpression;
-import javax.el.VariableMapper;
-
-import com.sun.el.MethodExpressionImpl;
-import com.sun.el.MethodExpressionLiteral;
-import com.sun.el.ValueExpressionImpl;
-import com.sun.el.parser.AstCompositeExpression;
-import com.sun.el.parser.AstDeferredExpression;
-import com.sun.el.parser.AstDynamicExpression;
-import com.sun.el.parser.AstFunction;
-import com.sun.el.parser.AstIdentifier;
-import com.sun.el.parser.AstLiteralExpression;
-import com.sun.el.parser.AstMethodArguments;
-import com.sun.el.parser.AstValue;
-import com.sun.el.parser.ELParser;
-import com.sun.el.parser.Node;
-import com.sun.el.parser.NodeVisitor;
-import com.sun.el.parser.ParseException;
-import com.sun.el.util.MessageFactory;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @author Kin-man Chung // EL cache
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class ExpressionBuilder implements NodeVisitor {
-
-    static private class NodeSoftReference extends SoftReference<Node> {
-        final String key;
-
-        NodeSoftReference(String key, Node node, ReferenceQueue<Node> refQ) {
-            super(node, refQ);
-            this.key = key;
-        }
-    }
-
-    static private class SoftConcurrentHashMap extends ConcurrentHashMap<String, Node> {
-
-        private static final int CACHE_INIT_SIZE = 256;
-        private ConcurrentHashMap<String, NodeSoftReference> map = new ConcurrentHashMap<String, NodeSoftReference>(CACHE_INIT_SIZE);
-        private ReferenceQueue<Node> refQ = new ReferenceQueue<Node>();
-
-        // Remove map entries that have been placed on the queue by GC.
-        private void cleanup() {
-            NodeSoftReference nodeRef = null;
-            while ((nodeRef = (NodeSoftReference) refQ.poll()) != null) {
-                map.remove(nodeRef.key);
-            }
-        }
-
-        @Override
-        public Node put(String key, Node value) {
-            cleanup();
-            NodeSoftReference prev = map.put(key, new NodeSoftReference(key, value, refQ));
-            return prev == null ? null : prev.get();
-        }
-
-        @Override
-        public Node putIfAbsent(String key, Node value) {
-            cleanup();
-            NodeSoftReference prev = map.putIfAbsent(key, new NodeSoftReference(key, value, refQ));
-            return prev == null ? null : prev.get();
-        }
-
-        @Override
-        public Node get(Object key) {
-            cleanup();
-            NodeSoftReference nodeRef = map.get(key);
-            if (nodeRef == null) {
-                return null;
-            }
-            if (nodeRef.get() == null) {
-                // value has been garbage collected, remove entry in map
-                map.remove(key);
-                return null;
-            }
-            return nodeRef.get();
-        }
-    }
-
-    private static final SoftConcurrentHashMap cache = new SoftConcurrentHashMap();
-    private FunctionMapper fnMapper;
-    private VariableMapper varMapper;
-    private String expression;
-
-    /**
-     *
-     */
-    public ExpressionBuilder(String expression, ELContext ctx) throws ELException {
-        this.expression = expression;
-
-        FunctionMapper ctxFn = ctx.getFunctionMapper();
-        VariableMapper ctxVar = ctx.getVariableMapper();
-
-        if (ctxFn != null) {
-            this.fnMapper = new FunctionMapperFactory(ctxFn);
-        }
-        if (ctxVar != null) {
-            this.varMapper = new VariableMapperFactory(ctxVar);
-        }
-    }
-
-    public static Node createNode(String expr) throws ELException {
-        Node n = createNodeInternal(expr);
-        return n;
-    }
-
-    private static Node createNodeInternal(String expr) throws ELException {
-        if (expr == null) {
-            throw new ELException(MessageFactory.get("error.null"));
-        }
-
-        Node n = cache.get(expr);
-        if (n == null) {
-            try {
-                n = (new ELParser(
-                        new com.sun.el.parser.ELParserTokenManager(new com.sun.el.parser.SimpleCharStream(new StringReader(expr), 1, 1, expr.length() + 1))))
-                                .CompositeExpression();
-
-                // validate composite expression
-                if (n instanceof AstCompositeExpression) {
-                    int numChildren = n.jjtGetNumChildren();
-                    if (numChildren == 1) {
-                        n = n.jjtGetChild(0);
-                    } else {
-                        Class type = null;
-                        Node child = null;
-                        for (int i = 0; i < numChildren; i++) {
-                            child = n.jjtGetChild(i);
-                            if (child instanceof AstLiteralExpression) {
-                                continue;
-                            }
-                            if (type == null) {
-                                type = child.getClass();
-                            } else {
-                                if (!type.equals(child.getClass())) {
-                                    throw new ELException(MessageFactory.get("error.mixed", expr));
-                                }
-                            }
-                        }
-                    }
-                }
-                if (n instanceof AstDeferredExpression || n instanceof AstDynamicExpression) {
-                    n = n.jjtGetChild(0);
-                }
-                cache.putIfAbsent(expr, n);
-            } catch (ParseException pe) {
-                throw new ELException("Error Parsing: " + expr, pe);
-            }
-        }
-        return n;
-    }
-
-    /**
-     * Scan the expression nodes and captures the functions and variables used in this expression. This ensures that any
-     * changes to the functions or variables mappings during the expression will not affect the evaluation of this
-     * expression, as the functions and variables are bound and resolved at parse time, as specified in the spec.
-     */
-    private void prepare(Node node) throws ELException {
-        node.accept(this);
-        if (this.fnMapper instanceof FunctionMapperFactory) {
-            this.fnMapper = ((FunctionMapperFactory) this.fnMapper).create();
-        }
-        if (this.varMapper instanceof VariableMapperFactory) {
-            this.varMapper = ((VariableMapperFactory) this.varMapper).create();
-        }
-    }
-
-    private Node build() throws ELException {
-        Node n = createNodeInternal(this.expression);
-        this.prepare(n);
-        if (n instanceof AstDeferredExpression || n instanceof AstDynamicExpression) {
-            n = n.jjtGetChild(0);
-        }
-        return n;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see com.sun.el.parser.NodeVisitor#visit(com.sun.el.parser.Node)
-     */
-    @Override
-    public void visit(Node node) throws ELException {
-        if (node instanceof AstFunction) {
-            AstFunction funcNode = (AstFunction) node;
-            if ((funcNode.getPrefix().length() == 0)
-                    && (this.fnMapper == null || fnMapper.resolveFunction(funcNode.getPrefix(), funcNode.getLocalName()) == null)) {
-                // This can be a call to a LambdaExpression. The target
-                // of the call is a bean or an Jakarta Expression variable. Capture
-                // the variable name in the variable mapper if it is an
-                // variable. The decision to invoke the static method or
-                // the LambdaExpression will be made at runtime.
-                if (this.varMapper != null) {
-                    this.varMapper.resolveVariable(funcNode.getLocalName());
-                }
-                return;
-            }
-
-            if (this.fnMapper == null) {
-                throw new ELException(MessageFactory.get("error.fnMapper.null"));
-            }
-            Method m = fnMapper.resolveFunction(funcNode.getPrefix(), funcNode.getLocalName());
-            if (m == null) {
-                throw new ELException(MessageFactory.get("error.fnMapper.method", funcNode.getOutputName()));
-            }
-            int pcnt = m.getParameterTypes().length;
-            int acnt = ((AstMethodArguments) node.jjtGetChild(0)).getParameterCount();
-            if (acnt != pcnt) {
-                throw new ELException(MessageFactory.get("error.fnMapper.paramcount", funcNode.getOutputName(), "" + pcnt, "" + acnt));
-            }
-        } else if (node instanceof AstIdentifier && this.varMapper != null) {
-            String variable = ((AstIdentifier) node).getImage();
-
-            // simply capture it
-            this.varMapper.resolveVariable(variable);
-        }
-    }
-
-    public ValueExpression createValueExpression(Class expectedType) throws ELException {
-        Node n = this.build();
-        return new ValueExpressionImpl(this.expression, n, this.fnMapper, this.varMapper, expectedType);
-    }
-
-    public MethodExpression createMethodExpression(Class expectedReturnType, Class[] expectedParamTypes) throws ELException {
-        Node n = this.build();
-        if (n instanceof AstValue || n instanceof AstIdentifier) {
-            return new MethodExpressionImpl(expression, n, this.fnMapper, this.varMapper, expectedReturnType, expectedParamTypes);
-        } else if (n instanceof AstLiteralExpression) {
-            return new MethodExpressionLiteral(expression, expectedReturnType, expectedParamTypes);
-        } else {
-            throw new ELException("Not a Valid Method Expression: " + expression);
-        }
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/lang/FunctionMapperFactory.java b/impl/src/main/java/com/sun/el/lang/FunctionMapperFactory.java
deleted file mode 100644
index 3bb0157..0000000
--- a/impl/src/main/java/com/sun/el/lang/FunctionMapperFactory.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.lang;
-
-import java.lang.reflect.Method;
-
-import javax.el.FunctionMapper;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public class FunctionMapperFactory extends FunctionMapper {
-
-    protected FunctionMapperImpl memento = null;
-    protected FunctionMapper target;
-
-    public FunctionMapperFactory(FunctionMapper mapper) {
-        if (mapper == null) {
-            throw new NullPointerException("FunctionMapper target cannot be null");
-        }
-        this.target = mapper;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.FunctionMapper#resolveFunction(java.lang.String, java.lang.String)
-     */
-    @Override
-    public Method resolveFunction(String prefix, String localName) {
-        if (this.memento == null) {
-            this.memento = new FunctionMapperImpl();
-        }
-        Method m = this.target.resolveFunction(prefix, localName);
-        if (m != null) {
-            this.memento.addFunction(prefix, localName, m);
-        }
-        return m;
-    }
-
-    public FunctionMapper create() {
-        return this.memento;
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/lang/FunctionMapperImpl.java b/impl/src/main/java/com/sun/el/lang/FunctionMapperImpl.java
deleted file mode 100644
index 970bc0e..0000000
--- a/impl/src/main/java/com/sun/el/lang/FunctionMapperImpl.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.lang;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.el.FunctionMapper;
-
-import com.sun.el.util.ReflectionUtil;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public class FunctionMapperImpl extends FunctionMapper implements Externalizable {
-
-    private static final long serialVersionUID = 1L;
-
-    protected Map<String, Function> functions = null;
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.el.FunctionMapper#resolveFunction(java.lang.String, java.lang.String)
-     */
-    @Override
-    public Method resolveFunction(String prefix, String localName) {
-        if (this.functions != null) {
-            Function f = this.functions.get(prefix + ":" + localName);
-            return f.getMethod();
-        }
-        return null;
-    }
-
-    public void addFunction(String prefix, String localName, Method m) {
-        if (this.functions == null) {
-            this.functions = new HashMap<String, Function>();
-        }
-        Function f = new Function(prefix, localName, m);
-        synchronized (this) {
-            this.functions.put(prefix + ":" + localName, f);
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
-     */
-    @Override
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(this.functions);
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
-     */
-    // Safe cast
-    @Override
-    @SuppressWarnings("unchecked")
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        this.functions = (Map<String, Function>) in.readObject();
-    }
-
-    public static class Function implements Externalizable {
-
-        protected transient Method m;
-        protected String owner;
-        protected String name;
-        protected String[] types;
-        protected String prefix;
-        protected String localName;
-
-        /**
-         *
-         */
-        public Function(String prefix, String localName, Method m) {
-            if (localName == null) {
-                throw new NullPointerException("LocalName cannot be null");
-            }
-            if (m == null) {
-                throw new NullPointerException("Method cannot be null");
-            }
-            this.prefix = prefix;
-            this.localName = localName;
-            this.m = m;
-        }
-
-        public Function() {
-            // for serialization
-        }
-
-        /*
-         * (non-Javadoc)
-         *
-         * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
-         */
-        @Override
-        public void writeExternal(ObjectOutput out) throws IOException {
-
-            out.writeUTF((this.prefix != null) ? this.prefix : "");
-            out.writeUTF(this.localName);
-
-            if (this.owner != null) {
-                out.writeUTF(this.owner);
-            } else {
-                out.writeUTF(this.m.getDeclaringClass().getName());
-            }
-            if (this.name != null) {
-                out.writeUTF(this.name);
-            } else {
-                out.writeUTF(this.m.getName());
-            }
-            if (this.types != null) {
-                out.writeObject(this.types);
-            } else {
-                out.writeObject(ReflectionUtil.toTypeNameArray(this.m.getParameterTypes()));
-            }
-        }
-
-        /*
-         * (non-Javadoc)
-         *
-         * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
-         */
-        @Override
-        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-
-            this.prefix = in.readUTF();
-            if ("".equals(this.prefix)) {
-                this.prefix = null;
-            }
-            this.localName = in.readUTF();
-            this.owner = in.readUTF();
-            this.name = in.readUTF();
-            this.types = (String[]) in.readObject();
-        }
-
-        public Method getMethod() {
-            if (this.m == null) {
-                try {
-                    Class<?> t = Class.forName(this.owner, false, Thread.currentThread().getContextClassLoader());
-                    Class[] p = ReflectionUtil.toTypeArray(this.types);
-                    this.m = t.getMethod(this.name, p);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-            return this.m;
-        }
-
-        public boolean matches(String prefix, String localName) {
-            if (this.prefix != null) {
-                if (prefix == null) {
-                    return false;
-                }
-                if (!this.prefix.equals(prefix)) {
-                    return false;
-                }
-            }
-            return this.localName.equals(localName);
-        }
-
-        /*
-         * (non-Javadoc)
-         *
-         * @see java.lang.Object#equals(java.lang.Object)
-         */
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof Function) {
-                return this.hashCode() == obj.hashCode();
-            }
-            return false;
-        }
-
-        /*
-         * (non-Javadoc)
-         *
-         * @see java.lang.Object#hashCode()
-         */
-        @Override
-        public int hashCode() {
-            return (this.prefix + this.localName).hashCode();
-        }
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/lang/VariableMapperFactory.java b/impl/src/main/java/com/sun/el/lang/VariableMapperFactory.java
deleted file mode 100644
index b67aade..0000000
--- a/impl/src/main/java/com/sun/el/lang/VariableMapperFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.lang;
-
-import javax.el.ValueExpression;
-import javax.el.VariableMapper;
-
-/**
- * Creates a VariableMapper for the variables used in the expression.
- */
-public class VariableMapperFactory extends VariableMapper {
-
-    private final VariableMapper target;
-    private VariableMapper momento;
-
-    public VariableMapperFactory(VariableMapper target) {
-        if (target == null) {
-            throw new NullPointerException("Target VariableMapper cannot be null");
-        }
-        this.target = target;
-    }
-
-    public VariableMapper create() {
-        return this.momento;
-    }
-
-    @Override
-    public ValueExpression resolveVariable(String variable) {
-        ValueExpression expr = this.target.resolveVariable(variable);
-        if (expr != null) {
-            if (this.momento == null) {
-                this.momento = new VariableMapperImpl();
-            }
-            this.momento.setVariable(variable, expr);
-        }
-        return expr;
-    }
-
-    @Override
-    public ValueExpression setVariable(String variable, ValueExpression expression) {
-        throw new UnsupportedOperationException("Cannot Set Variables on Factory");
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/lang/VariableMapperImpl.java b/impl/src/main/java/com/sun/el/lang/VariableMapperImpl.java
deleted file mode 100644
index 027bbe6..0000000
--- a/impl/src/main/java/com/sun/el/lang/VariableMapperImpl.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.lang;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.el.ValueExpression;
-import javax.el.VariableMapper;
-
-public class VariableMapperImpl extends VariableMapper implements Externalizable {
-
-    private static final long serialVersionUID = 1L;
-
-    private Map<String, ValueExpression> vars = new HashMap<String, ValueExpression>();
-
-    public VariableMapperImpl() {
-        super();
-    }
-
-    @Override
-    public ValueExpression resolveVariable(String variable) {
-        return this.vars.get(variable);
-    }
-
-    @Override
-    public ValueExpression setVariable(String variable, ValueExpression expression) {
-        return this.vars.put(variable, expression);
-    }
-
-    // Safe cast.
-    @Override
-    @SuppressWarnings("unchecked")
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
-        this.vars = (Map<String, ValueExpression>) in.readObject();
-    }
-
-    @Override
-    public void writeExternal(ObjectOutput out) throws IOException {
-        out.writeObject(this.vars);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/ArithmeticNode.java b/impl/src/main/java/com/sun/el/parser/ArithmeticNode.java
deleted file mode 100644
index 36fce35..0000000
--- a/impl/src/main/java/com/sun/el/parser/ArithmeticNode.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public class ArithmeticNode extends SimpleNode {
-
-    /**
-     * @param i
-     */
-    public ArithmeticNode(int i) {
-        super(i);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return Number.class;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstAnd.java b/impl/src/main/java/com/sun/el/parser/AstAnd.java
deleted file mode 100644
index 6e30086..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstAnd.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstAnd extends BooleanNode {
-    public AstAnd(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj = children[0].getValue(ctx);
-        Boolean b = coerceToBoolean(obj);
-        if (!b.booleanValue()) {
-            return b;
-        }
-        obj = children[1].getValue(ctx);
-        b = coerceToBoolean(obj);
-        return b;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstAssign.java b/impl/src/main/java/com/sun/el/parser/AstAssign.java
deleted file mode 100644
index 6ef715a..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstAssign.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-public class AstAssign extends SimpleNode {
-    public AstAssign(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-
-        Object value = children[1].getValue(ctx);
-        children[0].setValue(ctx, value);
-        return value;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstBracketSuffix.java b/impl/src/main/java/com/sun/el/parser/AstBracketSuffix.java
deleted file mode 100644
index 03454ab..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstBracketSuffix.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @author Kin-man Chung
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstBracketSuffix extends SimpleNode {
-    public AstBracketSuffix(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return this.children[0].getValue(ctx);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstChoice.java b/impl/src/main/java/com/sun/el/parser/AstChoice.java
deleted file mode 100644
index 78f3fb4..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstChoice.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstChoice extends SimpleNode {
-    public AstChoice(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Boolean b0 = coerceToBoolean(obj0);
-        return this.children[((b0.booleanValue() ? 1 : 2))].getType(ctx);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Boolean b0 = coerceToBoolean(obj0);
-        return this.children[((b0.booleanValue() ? 1 : 2))].getValue(ctx);
-    }
-
-    @Override
-    public boolean isReadOnly(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Boolean b0 = coerceToBoolean(obj0);
-        return this.children[((b0.booleanValue() ? 1 : 2))].isReadOnly(ctx);
-    }
-
-    @Override
-    public void setValue(EvaluationContext ctx, Object value) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Boolean b0 = coerceToBoolean(obj0);
-        this.children[((b0.booleanValue() ? 1 : 2))].setValue(ctx, value);
-    }
-
-    @Override
-    public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Boolean b0 = coerceToBoolean(obj0);
-        return this.children[((b0.booleanValue() ? 1 : 2))].invoke(ctx, paramTypes, paramValues);
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstCompositeExpression.java b/impl/src/main/java/com/sun/el/parser/AstCompositeExpression.java
deleted file mode 100644
index b9f4a18..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstCompositeExpression.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstCompositeExpression extends SimpleNode {
-
-    public AstCompositeExpression(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return String.class;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        StringBuffer sb = new StringBuffer(16);
-        Object obj = null;
-        if (this.children != null) {
-            for (int i = 0; i < this.children.length; i++) {
-                obj = this.children[i].getValue(ctx);
-                if (obj != null) {
-                    sb.append(obj);
-                }
-            }
-        }
-        return sb.toString();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstConcat.java b/impl/src/main/java/com/sun/el/parser/AstConcat.java
deleted file mode 100644
index e0957f8..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstConcat.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Kin-man Chung
- */
-public final class AstConcat extends SimpleNode {
-    public AstConcat(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return children[0].getValue(ctx).toString() + children[1].getValue(ctx).toString();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstDeferredExpression.java b/impl/src/main/java/com/sun/el/parser/AstDeferredExpression.java
deleted file mode 100644
index 9992b44..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstDeferredExpression.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstDeferredExpression extends SimpleNode {
-    public AstDeferredExpression(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return this.children[0].getType(ctx);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return this.children[0].getValue(ctx);
-    }
-
-    @Override
-    public boolean isReadOnly(EvaluationContext ctx) throws ELException {
-        return this.children[0].isReadOnly(ctx);
-    }
-
-    @Override
-    public void setValue(EvaluationContext ctx, Object value) throws ELException {
-        this.children[0].setValue(ctx, value);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstDiv.java b/impl/src/main/java/com/sun/el/parser/AstDiv.java
deleted file mode 100644
index 2979ac7..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstDiv.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.ELArithmetic;
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstDiv extends ArithmeticNode {
-    public AstDiv(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        return ELArithmetic.divide(obj0, obj1);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstDotSuffix.java b/impl/src/main/java/com/sun/el/parser/AstDotSuffix.java
deleted file mode 100644
index 17083cc..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstDotSuffix.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstDotSuffix extends SimpleNode {
-    public AstDotSuffix(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return this.image;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstDynamicExpression.java b/impl/src/main/java/com/sun/el/parser/AstDynamicExpression.java
deleted file mode 100644
index a9d5f8f..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstDynamicExpression.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstDynamicExpression extends SimpleNode {
-    public AstDynamicExpression(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return this.children[0].getType(ctx);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return this.children[0].getValue(ctx);
-    }
-
-    @Override
-    public boolean isReadOnly(EvaluationContext ctx) throws ELException {
-        return this.children[0].isReadOnly(ctx);
-    }
-
-    @Override
-    public void setValue(EvaluationContext ctx, Object value) throws ELException {
-        this.children[0].setValue(ctx, value);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstEmpty.java b/impl/src/main/java/com/sun/el/parser/AstEmpty.java
deleted file mode 100644
index 847300a..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstEmpty.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import java.util.Collection;
-import java.util.Map;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstEmpty extends SimpleNode {
-    public AstEmpty(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return Boolean.class;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj = this.children[0].getValue(ctx);
-        if (obj == null) {
-            return Boolean.TRUE;
-        } else if (obj instanceof String) {
-            return Boolean.valueOf(((String) obj).length() == 0);
-        } else if (obj instanceof Object[]) {
-            return Boolean.valueOf(((Object[]) obj).length == 0);
-        } else if (obj instanceof Collection) {
-            return Boolean.valueOf(((Collection) obj).isEmpty());
-        } else if (obj instanceof Map) {
-            return Boolean.valueOf(((Map) obj).isEmpty());
-        }
-        return Boolean.FALSE;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstEqual.java b/impl/src/main/java/com/sun/el/parser/AstEqual.java
deleted file mode 100644
index ae26ef8..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstEqual.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstEqual extends BooleanNode {
-    public AstEqual(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        return Boolean.valueOf(equals(obj0, obj1));
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstFalse.java b/impl/src/main/java/com/sun/el/parser/AstFalse.java
deleted file mode 100644
index 2c7ac5c..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstFalse.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstFalse extends BooleanNode {
-    public AstFalse(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return Boolean.FALSE;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstFloatingPoint.java b/impl/src/main/java/com/sun/el/parser/AstFloatingPoint.java
deleted file mode 100644
index bf3d003..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstFloatingPoint.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import java.math.BigDecimal;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstFloatingPoint extends SimpleNode {
-    public AstFloatingPoint(int id) {
-        super(id);
-    }
-
-    private Number number;
-
-    public Number getFloatingPoint() {
-        if (this.number == null) {
-            try {
-                this.number = Double.valueOf(this.image);
-            } catch (ArithmeticException e0) {
-                this.number = new BigDecimal(this.image);
-            }
-        }
-        return this.number;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return this.getFloatingPoint();
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return this.getFloatingPoint().getClass();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstFunction.java b/impl/src/main/java/com/sun/el/parser/AstFunction.java
deleted file mode 100644
index 15fb1af..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstFunction.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javax.el.ELClass;
-import javax.el.ELException;
-import javax.el.FunctionMapper;
-import javax.el.LambdaExpression;
-import javax.el.ValueExpression;
-import javax.el.VariableMapper;
-
-import com.sun.el.lang.EvaluationContext;
-import com.sun.el.util.MessageFactory;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstFunction extends SimpleNode {
-
-    protected String localName = "";
-
-    protected String prefix = "";
-
-    public AstFunction(int id) {
-        super(id);
-    }
-
-    public String getLocalName() {
-        return localName;
-    }
-
-    public String getOutputName() {
-        if (this.prefix.length() == 0) {
-            return this.localName;
-        } else {
-            return this.prefix + ":" + this.localName;
-        }
-    }
-
-    public String getPrefix() {
-        return prefix;
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-
-        FunctionMapper fnMapper = ctx.getFunctionMapper();
-
-        // quickly validate again for this request
-        if (fnMapper == null) {
-            throw new ELException(MessageFactory.get("error.fnMapper.null"));
-        }
-        Method m = fnMapper.resolveFunction(this.prefix, this.localName);
-        if (m == null) {
-            throw new ELException(MessageFactory.get("error.fnMapper.method", this.getOutputName()));
-        }
-        return m.getReturnType();
-    }
-
-    /*
-     * Find the object associated with the given name. Return null if the there is no such object.
-     */
-    private Object findValue(EvaluationContext ctx, String name) {
-        Object value;
-        // First check if this is a Lambda argument
-        if (ctx.isLambdaArgument(name)) {
-            return ctx.getLambdaArgument(name);
-        }
-
-        // Next check if this an Jakarta Expression variable
-        VariableMapper varMapper = ctx.getVariableMapper();
-        if (varMapper != null) {
-            ValueExpression expr = varMapper.resolveVariable(name);
-            if (expr != null) {
-                return expr.getValue(ctx.getELContext());
-            }
-        }
-        // Check if this is resolvable by an ELResolver
-        ctx.setPropertyResolved(false);
-        Object ret = ctx.getELResolver().getValue(ctx, null, name);
-        if (ctx.isPropertyResolved()) {
-            return ret;
-        }
-        return null;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-
-        // Check to see if a function is a bean that is a Lambdaexpression.
-        // If so, invoke it. Also allow for the case that a Lambda expression
-        // can return another Lambda expression.
-        if (prefix.length() == 0) {
-            Object val = findValue(ctx, this.localName);
-            // Check the case of repeated lambda invocation, such as f()()()
-
-            if ((val != null) && (val instanceof LambdaExpression)) {
-                for (int i = 0; i < this.children.length; i++) {
-                    Object[] params = ((AstMethodArguments) this.children[i]).getParameters(ctx);
-                    if (!(val instanceof LambdaExpression)) {
-                        throw new ELException(MessageFactory.get("error.function.syntax", getOutputName()));
-                    }
-                    val = ((LambdaExpression) val).invoke(ctx, params);
-                }
-                return val;
-            }
-        }
-
-        FunctionMapper fnMapper = ctx.getFunctionMapper();
-
-        Method m = null;
-        if (fnMapper != null) {
-            m = fnMapper.resolveFunction(this.prefix, this.localName);
-        }
-        if (m == null) {
-            if (this.prefix.length() == 0 && ctx.getImportHandler() != null) {
-                Class<?> c = null;
-                ;
-                // Check if this is a constructor call for an imported class
-                c = ctx.getImportHandler().resolveClass(this.localName);
-                String methodName = null;
-                if (c != null) {
-                    methodName = "<init>";
-                } else {
-                    // Check if this is a imported static method
-                    c = ctx.getImportHandler().resolveStatic(this.localName);
-                    methodName = this.localName;
-                    ;
-                }
-                if (c != null) {
-                    // Use StaticFieldELResolver to invoke the constructor or the
-                    // static method.
-                    Object[] params = ((AstMethodArguments) this.children[0]).getParameters(ctx);
-                    return ctx.getELResolver().invoke(ctx, new ELClass(c), methodName, null, params);
-                }
-            }
-            // quickly validate for this request
-            if (fnMapper == null) {
-                throw new ELException(MessageFactory.get("error.fnMapper.null"));
-            }
-            throw new ELException(MessageFactory.get("error.fnMapper.method", this.getOutputName()));
-        }
-
-        Class[] paramTypes = m.getParameterTypes();
-        Object[] params = ((AstMethodArguments) this.children[0]).getParameters(ctx);
-        Object result = null;
-        for (int i = 0; i < params.length; i++) {
-            try {
-                params[i] = ctx.convertToType(params[i], paramTypes[i]);
-            } catch (ELException ele) {
-                throw new ELException(MessageFactory.get("error.function", this.getOutputName()), ele);
-            }
-        }
-        try {
-            result = m.invoke(null, params);
-        } catch (IllegalAccessException iae) {
-            throw new ELException(MessageFactory.get("error.function", this.getOutputName()), iae);
-        } catch (InvocationTargetException ite) {
-            throw new ELException(MessageFactory.get("error.function", this.getOutputName()), ite.getCause());
-        }
-        return result;
-    }
-
-    public void setLocalName(String localName) {
-        this.localName = localName;
-    }
-
-    public void setPrefix(String prefix) {
-        this.prefix = prefix;
-    }
-
-    @Override
-    public String toString() {
-        return ELParserTreeConstants.jjtNodeName[id] + "[" + this.getOutputName() + "]";
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstGreaterThan.java b/impl/src/main/java/com/sun/el/parser/AstGreaterThan.java
deleted file mode 100644
index 2de0bd9..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstGreaterThan.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstGreaterThan extends BooleanNode {
-    public AstGreaterThan(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        if (obj0 == null) {
-            return Boolean.FALSE;
-        }
-        Object obj1 = this.children[1].getValue(ctx);
-        if (obj1 == null) {
-            return Boolean.FALSE;
-        }
-        return (compare(obj0, obj1) > 0) ? Boolean.TRUE : Boolean.FALSE;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstGreaterThanEqual.java b/impl/src/main/java/com/sun/el/parser/AstGreaterThanEqual.java
deleted file mode 100644
index 06252c0..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstGreaterThanEqual.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstGreaterThanEqual extends BooleanNode {
-    public AstGreaterThanEqual(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        if (obj0 == obj1) {
-            return Boolean.TRUE;
-        }
-        if (obj0 == null || obj1 == null) {
-            return Boolean.FALSE;
-        }
-        return (compare(obj0, obj1) >= 0) ? Boolean.TRUE : Boolean.FALSE;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstIdentifier.java b/impl/src/main/java/com/sun/el/parser/AstIdentifier.java
deleted file mode 100644
index a5a149b..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstIdentifier.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELClass;
-import javax.el.ELException;
-import javax.el.ELResolver;
-import javax.el.MethodExpression;
-import javax.el.MethodInfo;
-import javax.el.MethodNotFoundException;
-import javax.el.PropertyNotWritableException;
-import javax.el.ValueExpression;
-import javax.el.ValueReference;
-import javax.el.VariableMapper;
-
-import com.sun.el.lang.ELSupport;
-import com.sun.el.lang.EvaluationContext;
-import com.sun.el.util.MessageFactory;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @author Kin-man Chung
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstIdentifier extends SimpleNode {
-    public AstIdentifier(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        // First check if this is a lambda argument
-        if (ctx.isLambdaArgument(this.image)) {
-            return Object.class;
-        }
-        VariableMapper varMapper = ctx.getVariableMapper();
-        if (varMapper != null) {
-            ValueExpression expr = varMapper.resolveVariable(this.image);
-            if (expr != null) {
-                return expr.getType(ctx.getELContext());
-            }
-        }
-        ctx.setPropertyResolved(false);
-        Class ret = ctx.getELResolver().getType(ctx, null, this.image);
-        if (!ctx.isPropertyResolved()) {
-            ELSupport.throwUnhandled(null, this.image);
-        }
-        return ret;
-    }
-
-    @Override
-    public ValueReference getValueReference(EvaluationContext ctx) throws ELException {
-        VariableMapper varMapper = ctx.getVariableMapper();
-        if (varMapper != null) {
-            ValueExpression expr = varMapper.resolveVariable(this.image);
-            if (expr != null) {
-                return expr.getValueReference(ctx.getELContext());
-            }
-        }
-        return new ValueReference(null, this.image);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        // First check if this is a lambda argument
-        if (ctx.isLambdaArgument(this.image)) {
-            return ctx.getLambdaArgument(this.image);
-        }
-        VariableMapper varMapper = ctx.getVariableMapper();
-        if (varMapper != null) {
-            ValueExpression expr = varMapper.resolveVariable(this.image);
-            if (expr != null) {
-                return expr.getValue(ctx.getELContext());
-            }
-        }
-        ctx.setPropertyResolved(false);
-        Object ret = ctx.getELResolver().getValue(ctx, null, this.image);
-        if (!ctx.isPropertyResolved()) {
-            // Check if this is an imported static field
-            if (ctx.getImportHandler() != null) {
-                Class<?> c = ctx.getImportHandler().resolveStatic(this.image);
-                if (c != null) {
-                    return ctx.getELResolver().getValue(ctx, new ELClass(c), this.image);
-                }
-            }
-            ELSupport.throwUnhandled(null, this.image);
-        }
-        return ret;
-    }
-
-    @Override
-    public boolean isReadOnly(EvaluationContext ctx) throws ELException {
-        // Lambda arguments are read only.
-        if (ctx.isLambdaArgument(this.image)) {
-            return true;
-        }
-        VariableMapper varMapper = ctx.getVariableMapper();
-        if (varMapper != null) {
-            ValueExpression expr = varMapper.resolveVariable(this.image);
-            if (expr != null) {
-                return expr.isReadOnly(ctx.getELContext());
-            }
-        }
-        ctx.setPropertyResolved(false);
-        boolean ret = ctx.getELResolver().isReadOnly(ctx, null, this.image);
-        if (!ctx.isPropertyResolved()) {
-            ELSupport.throwUnhandled(null, this.image);
-        }
-        return ret;
-    }
-
-    @Override
-    public void setValue(EvaluationContext ctx, Object value) throws ELException {
-        // First check if this is a lambda argument
-        if (ctx.isLambdaArgument(this.image)) {
-            throw new PropertyNotWritableException(MessageFactory.get("error.lambda.parameter.readonly", this.image));
-        }
-        VariableMapper varMapper = ctx.getVariableMapper();
-        if (varMapper != null) {
-            ValueExpression expr = varMapper.resolveVariable(this.image);
-            if (expr != null) {
-                expr.setValue(ctx.getELContext(), value);
-                return;
-            }
-        }
-        ctx.setPropertyResolved(false);
-        ELResolver elResolver = ctx.getELResolver();
-        elResolver.setValue(ctx, null, this.image, value);
-        if (!ctx.isPropertyResolved()) {
-            ELSupport.throwUnhandled(null, this.image);
-        }
-    }
-
-    private Object invokeTarget(EvaluationContext ctx, Object target, Object[] paramValues) throws ELException {
-        if (target instanceof MethodExpression) {
-            MethodExpression me = (MethodExpression) target;
-            return me.invoke(ctx.getELContext(), paramValues);
-        } else if (target == null) {
-            throw new MethodNotFoundException("Identity '" + this.image + "' was null and was unable to invoke");
-        } else {
-            throw new ELException(
-                    "Identity '" + this.image + "' does not reference a MethodExpression instance, returned type: " + target.getClass().getName());
-        }
-    }
-
-    @Override
-    public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException {
-        return this.getMethodExpression(ctx).invoke(ctx.getELContext(), paramValues);
-    }
-
-    @Override
-    public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes) throws ELException {
-        return this.getMethodExpression(ctx).getMethodInfo(ctx.getELContext());
-    }
-
-    private MethodExpression getMethodExpression(EvaluationContext ctx) throws ELException {
-        Object obj = null;
-
-        // case A: ValueExpression exists, getValue which must
-        // be a MethodExpression
-        VariableMapper varMapper = ctx.getVariableMapper();
-        ValueExpression ve = null;
-        if (varMapper != null) {
-            ve = varMapper.resolveVariable(this.image);
-            if (ve != null) {
-                obj = ve.getValue(ctx);
-            }
-        }
-
-        // case B: evaluate the identity against the ELResolver, again, must be
-        // a MethodExpression to be able to invoke
-        if (ve == null) {
-            ctx.setPropertyResolved(false);
-            obj = ctx.getELResolver().getValue(ctx, null, this.image);
-        }
-
-        // finally provide helpful hints
-        if (obj instanceof MethodExpression) {
-            return (MethodExpression) obj;
-        } else if (obj == null) {
-            throw new MethodNotFoundException("Identity '" + this.image + "' was null and was unable to invoke");
-        } else {
-            throw new ELException("Identity '" + this.image + "' does not reference a MethodExpression instance, returned type: " + obj.getClass().getName());
-        }
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstInteger.java b/impl/src/main/java/com/sun/el/parser/AstInteger.java
deleted file mode 100644
index 8c6d7c7..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstInteger.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import java.math.BigInteger;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstInteger extends SimpleNode {
-    public AstInteger(int id) {
-        super(id);
-    }
-
-    private Number number;
-
-    protected Number getInteger() {
-        if (this.number == null) {
-            try {
-                this.number = Long.valueOf(this.image);
-            } catch (ArithmeticException e1) {
-                this.number = new BigInteger(this.image);
-            }
-        }
-        return number;
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return this.getInteger().getClass();
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return this.getInteger();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstLambdaExpression.java b/impl/src/main/java/com/sun/el/parser/AstLambdaExpression.java
deleted file mode 100644
index 1349899..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstLambdaExpression.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.parser;
-
-import java.util.List;
-
-import javax.el.ELException;
-import javax.el.LambdaExpression;
-import javax.el.ValueExpression;
-
-import com.sun.el.ValueExpressionImpl;
-import com.sun.el.lang.EvaluationContext;
-import com.sun.el.util.MessageFactory;
-
-/**
- * @author Kin-man Chung
- */
-public class AstLambdaExpression extends SimpleNode {
-
-    public AstLambdaExpression(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        // Create a lambda expression
-        ValueExpression expr = new ValueExpressionImpl("#{Lambda Expression}", this.children[1], ctx.getFunctionMapper(), ctx.getVariableMapper(), null);
-        List<String> parameters = ((AstLambdaParameters) this.children[0]).getParameters();
-        LambdaExpression lambda = new LambdaExpression(parameters, expr);
-        if (this.children.length <= 2) {
-            return lambda;
-        }
-
-        // There are arguments following the lambda exprn, invoke it now.
-        Object ret = null;
-        for (int i = 2; i < this.children.length; i++) {
-            if (ret != null) {
-                if (!(ret instanceof LambdaExpression)) {
-                    throw new ELException(MessageFactory.get("error.lambda.call"));
-                }
-                lambda = (LambdaExpression) ret;
-            }
-            AstMethodArguments args = (AstMethodArguments) this.children[i];
-            ret = lambda.invoke(ctx, args.getParameters(ctx));
-        }
-        return ret;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstLambdaParameters.java b/impl/src/main/java/com/sun/el/parser/AstLambdaParameters.java
deleted file mode 100644
index ee5875c..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstLambdaParameters.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.parser;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Kin-man Chung
- */
-
-public class AstLambdaParameters extends SimpleNode {
-    public AstLambdaParameters(int id) {
-        super(id);
-    }
-
-    List<String> getParameters() {
-        List<String> parameters = new ArrayList<String>();
-        if (children != null) {
-            for (Node child : children) {
-                parameters.add(child.getImage());
-            }
-        }
-        return parameters;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstLessThan.java b/impl/src/main/java/com/sun/el/parser/AstLessThan.java
deleted file mode 100644
index c1bd471..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstLessThan.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstLessThan extends BooleanNode {
-    public AstLessThan(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        if (obj0 == null) {
-            return Boolean.FALSE;
-        }
-        Object obj1 = this.children[1].getValue(ctx);
-        if (obj1 == null) {
-            return Boolean.FALSE;
-        }
-        return (compare(obj0, obj1) < 0) ? Boolean.TRUE : Boolean.FALSE;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstLessThanEqual.java b/impl/src/main/java/com/sun/el/parser/AstLessThanEqual.java
deleted file mode 100644
index 8f2c837..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstLessThanEqual.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstLessThanEqual extends BooleanNode {
-    public AstLessThanEqual(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        if (obj0 == obj1) {
-            return Boolean.TRUE;
-        }
-        if (obj0 == null || obj1 == null) {
-            return Boolean.FALSE;
-        }
-        return (compare(obj0, obj1) <= 0) ? Boolean.TRUE : Boolean.FALSE;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstListData.java b/impl/src/main/java/com/sun/el/parser/AstListData.java
deleted file mode 100644
index 7dc2952..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstListData.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.parser;
-
-import java.util.ArrayList;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Kin-man Chung
- */
-public class AstListData extends SimpleNode {
-    public AstListData(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) {
-        ArrayList<Object> list = new ArrayList<Object>();
-        int paramCount = this.jjtGetNumChildren();
-        for (int i = 0; i < paramCount; i++) {
-            list.add(this.children[i].getValue(ctx));
-        }
-        return list;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstLiteralExpression.java b/impl/src/main/java/com/sun/el/parser/AstLiteralExpression.java
deleted file mode 100644
index 9672246..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstLiteralExpression.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstLiteralExpression extends SimpleNode {
-    public AstLiteralExpression(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return String.class;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return this.image;
-    }
-
-    @Override
-    public void setImage(String image) {
-        if (image.indexOf('\\') == -1) {
-            this.image = image;
-            return;
-        }
-        int size = image.length();
-        StringBuffer buf = new StringBuffer(size);
-        for (int i = 0; i < size; i++) {
-            char c = image.charAt(i);
-            if (c == '\\' && i + 1 < size) {
-                char c1 = image.charAt(i + 1);
-                if (c1 == '\\' || c1 == '"' || c1 == '\'' || c1 == '#' || c1 == '$') {
-                    c = c1;
-                    i++;
-                }
-            }
-            buf.append(c);
-        }
-        this.image = buf.toString();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstMapData.java b/impl/src/main/java/com/sun/el/parser/AstMapData.java
deleted file mode 100644
index 41435c8..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstMapData.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.parser;
-
-import java.util.HashMap;
-import java.util.HashSet;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Kin-man Chung
- */
-public class AstMapData extends SimpleNode {
-    public AstMapData(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) {
-        HashSet<Object> set = new HashSet<Object>();
-        HashMap<Object, Object> map = new HashMap<Object, Object>();
-
-        int paramCount = this.jjtGetNumChildren();
-        for (int i = 0; i < paramCount; i++) {
-            Node entry = this.children[i];
-            Object v1 = entry.jjtGetChild(0).getValue(ctx);
-            if (entry.jjtGetNumChildren() > 1) {
-                // expr: expr
-                map.put(v1, entry.jjtGetChild(1).getValue(ctx));
-            } else {
-                set.add(v1);
-            }
-        }
-        // It is error to have mixed set/map entries
-        if (set.size() > 0 && map.size() > 0) {
-            throw new ELException("Cannot mix set entry with map entry.");
-        }
-        if (map.size() > 0) {
-            return map;
-        }
-        return set;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstMapEntry.java b/impl/src/main/java/com/sun/el/parser/AstMapEntry.java
deleted file mode 100644
index c55caa6..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstMapEntry.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.parser;
-
-/**
- * @author Kin-man Chung
- */
-public class AstMapEntry extends SimpleNode {
-    public AstMapEntry(int id) {
-        super(id);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstMethodArguments.java b/impl/src/main/java/com/sun/el/parser/AstMethodArguments.java
deleted file mode 100644
index 24ef021..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstMethodArguments.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Kin-man Chung
- */
-public class AstMethodArguments extends SimpleNode {
-    public AstMethodArguments(int id) {
-        super(id);
-    }
-
-    Class<?>[] getParamTypes() {
-        return null;
-    }
-
-    public Object[] getParameters(EvaluationContext ctx) throws ELException {
-
-        if (this.children == null) {
-            return new Object[] {};
-        }
-
-        Object[] obj = new Object[this.children.length];
-        for (int i = 0; i < obj.length; i++) {
-            obj[i] = this.children[i].getValue(ctx);
-        }
-        return obj;
-    }
-
-    public int getParameterCount() {
-        return this.children == null ? 0 : this.children.length;
-    }
-
-    @Override
-    public boolean isParametersProvided() {
-        return true;
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstMinus.java b/impl/src/main/java/com/sun/el/parser/AstMinus.java
deleted file mode 100644
index 11fdf84..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstMinus.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.ELArithmetic;
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstMinus extends ArithmeticNode {
-    public AstMinus(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        return ELArithmetic.subtract(obj0, obj1);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstMod.java b/impl/src/main/java/com/sun/el/parser/AstMod.java
deleted file mode 100644
index d69b928..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstMod.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.ELArithmetic;
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstMod extends ArithmeticNode {
-    public AstMod(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        return ELArithmetic.mod(obj0, obj1);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstMult.java b/impl/src/main/java/com/sun/el/parser/AstMult.java
deleted file mode 100644
index 8ee4751..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstMult.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.ELArithmetic;
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstMult extends ArithmeticNode {
-    public AstMult(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        return ELArithmetic.multiply(obj0, obj1);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstNegative.java b/impl/src/main/java/com/sun/el/parser/AstNegative.java
deleted file mode 100644
index e4b4465..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstNegative.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstNegative extends SimpleNode {
-    public AstNegative(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return Number.class;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj = this.children[0].getValue(ctx);
-
-        if (obj == null) {
-            return Long.valueOf(0);
-        }
-        if (obj instanceof BigDecimal) {
-            return ((BigDecimal) obj).negate();
-        }
-        if (obj instanceof BigInteger) {
-            return ((BigInteger) obj).negate();
-        }
-        if (obj instanceof String) {
-            if (isStringFloat((String) obj)) {
-                return Double.valueOf(-Double.parseDouble((String) obj));
-            }
-            return Long.valueOf(-Long.parseLong((String) obj));
-        }
-        Class type = obj.getClass();
-        if (obj instanceof Long || Long.TYPE == type) {
-            return Long.valueOf(-((Long) obj).longValue());
-        }
-        if (obj instanceof Double || Double.TYPE == type) {
-            return Double.valueOf(-((Double) obj).doubleValue());
-        }
-        if (obj instanceof Integer || Integer.TYPE == type) {
-            return Integer.valueOf(-((Integer) obj).intValue());
-        }
-        if (obj instanceof Float || Float.TYPE == type) {
-            return Float.valueOf(-((Float) obj).floatValue());
-        }
-        if (obj instanceof Short || Short.TYPE == type) {
-            return Short.valueOf((short) -((Short) obj).shortValue());
-        }
-        if (obj instanceof Byte || Byte.TYPE == type) {
-            return Byte.valueOf((byte) -((Byte) obj).byteValue());
-        }
-        Long num = (Long) coerceToNumber(obj, Long.class);
-        return Long.valueOf(-num.longValue());
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstNot.java b/impl/src/main/java/com/sun/el/parser/AstNot.java
deleted file mode 100644
index 5f0886b..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstNot.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstNot extends SimpleNode {
-    public AstNot(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return Boolean.class;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj = this.children[0].getValue(ctx);
-        Boolean b = coerceToBoolean(obj);
-        return Boolean.valueOf(!b.booleanValue());
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstNotEqual.java b/impl/src/main/java/com/sun/el/parser/AstNotEqual.java
deleted file mode 100644
index 359f479..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstNotEqual.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstNotEqual extends BooleanNode {
-    public AstNotEqual(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        return Boolean.valueOf(!equals(obj0, obj1));
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstNull.java b/impl/src/main/java/com/sun/el/parser/AstNull.java
deleted file mode 100644
index 548a387..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstNull.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstNull extends SimpleNode {
-    public AstNull(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return null;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return null;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstOr.java b/impl/src/main/java/com/sun/el/parser/AstOr.java
deleted file mode 100644
index 2fc12d4..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstOr.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstOr extends BooleanNode {
-    public AstOr(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj = this.children[0].getValue(ctx);
-        Boolean b = coerceToBoolean(obj);
-        if (b.booleanValue()) {
-            return b;
-        }
-        obj = this.children[1].getValue(ctx);
-        b = coerceToBoolean(obj);
-        return b;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstPlus.java b/impl/src/main/java/com/sun/el/parser/AstPlus.java
deleted file mode 100644
index 2592188..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstPlus.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.ELArithmetic;
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @author Kin-man Chung
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstPlus extends ArithmeticNode {
-    public AstPlus(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object obj0 = this.children[0].getValue(ctx);
-        Object obj1 = this.children[1].getValue(ctx);
-        return ELArithmetic.add(obj0, obj1);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstSemiColon.java b/impl/src/main/java/com/sun/el/parser/AstSemiColon.java
deleted file mode 100644
index 275aaba..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstSemiColon.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Kin-man Chung
- */
-public class AstSemiColon extends SimpleNode {
-    public AstSemiColon(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        this.children[0].getValue(ctx);
-        return this.children[1].getValue(ctx);
-    }
-
-    @Override
-    public void setValue(EvaluationContext ctx, Object value) throws ELException {
-        this.children[0].getValue(ctx);
-        this.children[1].setValue(ctx, value);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstString.java b/impl/src/main/java/com/sun/el/parser/AstString.java
deleted file mode 100644
index 77a7ad1..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstString.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstString extends SimpleNode {
-    public AstString(int id) {
-        super(id);
-    }
-
-    private String string;
-
-    public String getString() {
-        if (this.string == null) {
-            this.string = this.image.substring(1, this.image.length() - 1);
-        }
-        return this.string;
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return String.class;
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return this.getString();
-    }
-
-    @Override
-    public void setImage(String image) {
-        if (image.indexOf('\\') == -1) {
-            this.image = image;
-            return;
-        }
-        int size = image.length();
-        StringBuffer buf = new StringBuffer(size);
-        for (int i = 0; i < size; i++) {
-            char c = image.charAt(i);
-            if (c == '\\' && i + 1 < size) {
-                char c1 = image.charAt(i + 1);
-                if (c1 == '\\' || c1 == '"' || c1 == '\'' || c1 == '#' || c1 == '$') {
-                    c = c1;
-                    i++;
-                }
-            }
-            buf.append(c);
-        }
-        this.image = buf.toString();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstTrue.java b/impl/src/main/java/com/sun/el/parser/AstTrue.java
deleted file mode 100644
index 607e6bd..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstTrue.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstTrue extends BooleanNode {
-    public AstTrue(int id) {
-        super(id);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        return Boolean.TRUE;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/AstValue.java b/impl/src/main/java/com/sun/el/parser/AstValue.java
deleted file mode 100644
index dfe0f82..0000000
--- a/impl/src/main/java/com/sun/el/parser/AstValue.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import java.lang.reflect.Method;
-
-import javax.el.ELClass;
-import javax.el.ELException;
-import javax.el.ELResolver;
-import javax.el.ImportHandler;
-import javax.el.MethodInfo;
-import javax.el.PropertyNotFoundException;
-import javax.el.PropertyNotWritableException;
-import javax.el.ValueReference;
-
-import com.sun.el.lang.ELSupport;
-import com.sun.el.lang.EvaluationContext;
-import com.sun.el.util.MessageFactory;
-import com.sun.el.util.ReflectionUtil;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @author Kin-man Chung
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class AstValue extends SimpleNode {
-
-    protected static class Target {
-        protected Object base;
-        protected Node suffixNode;
-
-        Target(Object base, Node suffixNode) {
-            this.base = base;
-            this.suffixNode = suffixNode;
-        }
-
-        boolean isMethodCall() {
-            return getArguments(suffixNode) != null;
-        }
-    }
-
-    public AstValue(int id) {
-        super(id);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        Target t = getTarget(ctx);
-        if (t.isMethodCall()) {
-            return null;
-        }
-        Object property = t.suffixNode.getValue(ctx);
-        ctx.setPropertyResolved(false);
-        Class ret = ctx.getELResolver().getType(ctx, t.base, property);
-        if (!ctx.isPropertyResolved()) {
-            ELSupport.throwUnhandled(t.base, property);
-        }
-        return ret;
-    }
-
-    @Override
-    public ValueReference getValueReference(EvaluationContext ctx) throws ELException {
-        Target t = getTarget(ctx);
-        if (t.isMethodCall()) {
-            return null;
-        }
-        Object property = t.suffixNode.getValue(ctx);
-        return new ValueReference(t.base, property);
-    }
-
-    private static AstMethodArguments getArguments(Node n) {
-        if (n instanceof AstDotSuffix && n.jjtGetNumChildren() > 0) {
-            return (AstMethodArguments) n.jjtGetChild(0);
-        }
-        if (n instanceof AstBracketSuffix && n.jjtGetNumChildren() > 1) {
-            return (AstMethodArguments) n.jjtGetChild(1);
-        }
-        return null;
-    }
-
-    private Object getValue(Object base, Node child, EvaluationContext ctx) throws ELException {
-
-        Object value = null;
-        ELResolver resolver = ctx.getELResolver();
-        Object property = child.getValue(ctx);
-        AstMethodArguments args = getArguments(child);
-        if (args != null) {
-            // This is a method call
-            if (!(property instanceof String)) {
-                throw new ELException(MessageFactory.get("error.method.name", property));
-            }
-            Class<?>[] paramTypes = args.getParamTypes();
-            Object[] params = args.getParameters(ctx);
-
-            ctx.setPropertyResolved(false);
-            value = resolver.invoke(ctx, base, property, paramTypes, params);
-        } else {
-            if (property != null) {
-                ctx.setPropertyResolved(false);
-                value = resolver.getValue(ctx, base, property);
-                if (!ctx.isPropertyResolved()) {
-                    ELSupport.throwUnhandled(base, property);
-                }
-            }
-        }
-        return value;
-    }
-
-    private Object getBase(EvaluationContext ctx) {
-        try {
-            return this.children[0].getValue(ctx);
-        } catch (PropertyNotFoundException ex) {
-            // Next check if the base is an imported class
-            if (this.children[0] instanceof AstIdentifier) {
-                String name = ((AstIdentifier) this.children[0]).image;
-                ImportHandler importHandler = ctx.getImportHandler();
-                if (importHandler != null) {
-                    Class<?> c = importHandler.resolveClass(name);
-                    if (c != null) {
-                        return new ELClass(c);
-                    }
-                }
-            }
-            throw ex;
-        }
-    }
-
-    private Target getTarget(EvaluationContext ctx) throws ELException {
-        // evaluate expr-a to value-a
-        Object base = getBase(ctx);
-
-        // if our base is null (we know there are more properites to evaluate)
-        if (base == null) {
-            throw new PropertyNotFoundException(MessageFactory.get("error.unreachable.base", this.children[0].getImage()));
-        }
-
-        // set up our start/end
-        Object property = null;
-        int propCount = this.jjtGetNumChildren() - 1;
-        int i = 1;
-
-        // evaluate any properties before our target
-        if (propCount > 1) {
-            while (base != null && i < propCount) {
-                base = getValue(base, this.children[i], ctx);
-                i++;
-            }
-            // if we are in this block, we have more properties to resolve,
-            // but our base was null
-            if (base == null) {
-                throw new PropertyNotFoundException(MessageFactory.get("error.unreachable.property", property));
-            }
-        }
-        return new Target(base, this.children[propCount]);
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        Object base = getBase(ctx);
-        int propCount = this.jjtGetNumChildren();
-        int i = 1;
-        while (base != null && i < propCount) {
-            base = getValue(base, this.children[i], ctx);
-            i++;
-        }
-        return base;
-    }
-
-    @Override
-    public boolean isReadOnly(EvaluationContext ctx) throws ELException {
-        Target t = getTarget(ctx);
-        if (t.isMethodCall()) {
-            return true;
-        }
-        Object property = t.suffixNode.getValue(ctx);
-        ctx.setPropertyResolved(false);
-        boolean ret = ctx.getELResolver().isReadOnly(ctx, t.base, property);
-        if (!ctx.isPropertyResolved()) {
-            ELSupport.throwUnhandled(t.base, property);
-        }
-        return ret;
-    }
-
-    @Override
-    public void setValue(EvaluationContext ctx, Object value) throws ELException {
-        Target t = getTarget(ctx);
-        if (t.isMethodCall()) {
-            throw new PropertyNotWritableException(MessageFactory.get("error.syntax.set"));
-        }
-        Object property = t.suffixNode.getValue(ctx);
-        ELResolver elResolver = ctx.getELResolver();
-
-        /*
-         * Note by kchung 10/2013 The spec does not say if the value should be cocerced to the target type before setting the
-         * value to the target. The conversion is kept here to be backward compatible.
-         */
-        ctx.setPropertyResolved(false);
-        Class<?> targetType = elResolver.getType(ctx, t.base, property);
-        if (ctx.isPropertyResolved()) {
-            ctx.setPropertyResolved(false);
-            Object targetValue = elResolver.convertToType(ctx, value, targetType);
-
-            if (ctx.isPropertyResolved()) {
-                value = targetValue;
-            } else {
-                if (value != null || targetType.isPrimitive()) {
-                    value = ELSupport.coerceToType(value, targetType);
-                }
-            }
-        }
-
-        ctx.setPropertyResolved(false);
-        elResolver.setValue(ctx, t.base, property, value);
-        if (!ctx.isPropertyResolved()) {
-            ELSupport.throwUnhandled(t.base, property);
-        }
-    }
-
-    @Override
-    public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes) throws ELException {
-        Target t = getTarget(ctx);
-        if (t.isMethodCall()) {
-            return null;
-        }
-        Object property = t.suffixNode.getValue(ctx);
-        Method m = ReflectionUtil.findMethod(t.base.getClass(), property.toString(), paramTypes, null);
-        return new MethodInfo(m.getName(), m.getReturnType(), m.getParameterTypes());
-    }
-
-    @Override
-    public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException {
-        Target t = getTarget(ctx);
-        if (t.isMethodCall()) {
-            AstMethodArguments args = getArguments(t.suffixNode);
-            // Always use the param types in the expression, and ignore those
-            // specified elsewhere, such as TLD
-            paramTypes = args.getParamTypes();
-            Object[] params = args.getParameters(ctx);
-            String method = (String) t.suffixNode.getValue(ctx);
-
-            ctx.setPropertyResolved(false);
-            ELResolver resolver = ctx.getELResolver();
-            return resolver.invoke(ctx, t.base, method, paramTypes, params);
-        }
-        Object property = t.suffixNode.getValue(ctx);
-        Method m = ReflectionUtil.findMethod(t.base.getClass(), property.toString(), paramTypes, paramValues);
-        return ReflectionUtil.invokeMethod(ctx, m, t.base, paramValues);
-    }
-
-    @Override
-    public boolean isParametersProvided() {
-        return getArguments(this.children[this.jjtGetNumChildren() - 1]) != null;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/BooleanNode.java b/impl/src/main/java/com/sun/el/parser/BooleanNode.java
deleted file mode 100644
index 5f4dec1..0000000
--- a/impl/src/main/java/com/sun/el/parser/BooleanNode.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-import com.sun.el.lang.EvaluationContext;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public class BooleanNode extends SimpleNode {
-    /**
-     * @param i
-     */
-    public BooleanNode(int i) {
-        super(i);
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        return Boolean.class;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/ELParser.java b/impl/src/main/java/com/sun/el/parser/ELParser.java
deleted file mode 100644
index 4d76641..0000000
--- a/impl/src/main/java/com/sun/el/parser/ELParser.java
+++ /dev/null
@@ -1,3782 +0,0 @@
-/*
- * 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
- */
-
-/* Generated By:JJTree&JavaCC: Do not edit this line. ELParser.java */
-package com.sun.el.parser;
-
-import java.io.StringReader;
-
-import javax.el.ELException;
-
-public class ELParser/* @bgen(jjtree) */ implements ELParserTreeConstants, ELParserConstants {/* @bgen(jjtree) */
-    protected JJTELParserState jjtree = new JJTELParserState();
-
-    public static Node parse(String ref) throws ELException {
-        try {
-            return (new ELParser(new StringReader(ref))).CompositeExpression();
-        } catch (ParseException pe) {
-            throw new ELException(pe.getMessage());
-        }
-    }
-
-    /*
-     * CompositeExpression Allow most flexible parsing, restrict by examining type of returned node
-     */
-    final public AstCompositeExpression CompositeExpression() throws ParseException {
-        /* @bgen(jjtree) CompositeExpression */
-        AstCompositeExpression jjtn000 = new AstCompositeExpression(JJTCOMPOSITEEXPRESSION);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            label_1: while (true) {
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case LITERAL_EXPRESSION:
-                case START_DYNAMIC_EXPRESSION:
-                case START_DEFERRED_EXPRESSION:
-                    ;
-                    break;
-                default:
-                    jj_la1[0] = jj_gen;
-                    break label_1;
-                }
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case START_DEFERRED_EXPRESSION:
-                    DeferredExpression();
-                    break;
-                case START_DYNAMIC_EXPRESSION:
-                    DynamicExpression();
-                    break;
-                case LITERAL_EXPRESSION:
-                    LiteralExpression();
-                    break;
-                default:
-                    jj_la1[1] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-            }
-            jj_consume_token(0);
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtc000 = false;
-            {
-                if (true) {
-                    return jjtn000;
-                }
-            }
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-        throw new Error("Missing return statement in function");
-    }
-
-    /*
-     * LiteralExpression Non-EL Expression blocks
-     */
-    final public void LiteralExpression() throws ParseException {
-        /* @bgen(jjtree) LiteralExpression */
-        AstLiteralExpression jjtn000 = new AstLiteralExpression(JJTLITERALEXPRESSION);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        Token t = null;
-        try {
-            t = jj_consume_token(LITERAL_EXPRESSION);
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtc000 = false;
-            jjtn000.setImage(t.image);
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * DeferredExpression #{..} Expressions
-     */
-    final public void DeferredExpression() throws ParseException {
-        /* @bgen(jjtree) DeferredExpression */
-        AstDeferredExpression jjtn000 = new AstDeferredExpression(JJTDEFERREDEXPRESSION);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            jj_consume_token(START_DEFERRED_EXPRESSION);
-            Expression();
-            jj_consume_token(RCURL);
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * DynamicExpression ${..} Expressions
-     */
-    final public void DynamicExpression() throws ParseException {
-        /* @bgen(jjtree) DynamicExpression */
-        AstDynamicExpression jjtn000 = new AstDynamicExpression(JJTDYNAMICEXPRESSION);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            jj_consume_token(START_DYNAMIC_EXPRESSION);
-            Expression();
-            jj_consume_token(RCURL);
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * Jakarta Expression Root
-     */
-    final public void Expression() throws ParseException {
-        SemiColon();
-    }
-
-    /*
-     * SemiColon
-     */
-    final public void SemiColon() throws ParseException {
-        Assignment();
-        label_2: while (true) {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case SEMICOLON:
-                ;
-                break;
-            default:
-                jj_la1[2] = jj_gen;
-                break label_2;
-            }
-            jj_consume_token(SEMICOLON);
-            AstSemiColon jjtn001 = new AstSemiColon(JJTSEMICOLON);
-            boolean jjtc001 = true;
-            jjtree.openNodeScope(jjtn001);
-            try {
-                Assignment();
-            } catch (Throwable jjte001) {
-                if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                } else {
-                    jjtree.popNode();
-                }
-                if (jjte001 instanceof RuntimeException) {
-                    {
-                        if (true) {
-                            throw (RuntimeException) jjte001;
-                        }
-                    }
-                }
-                if (jjte001 instanceof ParseException) {
-                    {
-                        if (true) {
-                            throw (ParseException) jjte001;
-                        }
-                    }
-                }
-                {
-                    if (true) {
-                        throw (Error) jjte001;
-                    }
-                }
-            } finally {
-                if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001, 2);
-                }
-            }
-        }
-    }
-
-    /*
-     * Assignment For '=', right associatve, then LambdaExpression or Choice or Assignment
-     */
-    final public void Assignment() throws ParseException {
-        if (jj_2_1(3)) {
-            LambdaExpression();
-        } else {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case START_MAP:
-            case INTEGER_LITERAL:
-            case FLOATING_POINT_LITERAL:
-            case STRING_LITERAL:
-            case TRUE:
-            case FALSE:
-            case NULL:
-            case LPAREN:
-            case LBRACK:
-            case NOT0:
-            case NOT1:
-            case EMPTY:
-            case MINUS:
-            case IDENTIFIER:
-                Choice();
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case ASSIGN:
-                    jj_consume_token(ASSIGN);
-                    AstAssign jjtn001 = new AstAssign(JJTASSIGN);
-                    boolean jjtc001 = true;
-                    jjtree.openNodeScope(jjtn001);
-                    try {
-                        Assignment();
-                    } catch (Throwable jjte001) {
-                        if (jjtc001) {
-                            jjtree.clearNodeScope(jjtn001);
-                            jjtc001 = false;
-                        } else {
-                            jjtree.popNode();
-                        }
-                        if (jjte001 instanceof RuntimeException) {
-                            {
-                                if (true) {
-                                    throw (RuntimeException) jjte001;
-                                }
-                            }
-                        }
-                        if (jjte001 instanceof ParseException) {
-                            {
-                                if (true) {
-                                    throw (ParseException) jjte001;
-                                }
-                            }
-                        }
-                        {
-                            if (true) {
-                                throw (Error) jjte001;
-                            }
-                        }
-                    } finally {
-                        if (jjtc001) {
-                            jjtree.closeNodeScope(jjtn001, 2);
-                        }
-                    }
-                    break;
-                default:
-                    jj_la1[3] = jj_gen;
-                    ;
-                }
-                break;
-            default:
-                jj_la1[4] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-        }
-    }
-
-    /*
-     * LambdaExpression
-     */
-    final public void LambdaExpression() throws ParseException {
-        /* @bgen(jjtree) LambdaExpression */
-        AstLambdaExpression jjtn000 = new AstLambdaExpression(JJTLAMBDAEXPRESSION);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            LambdaParameters();
-            jj_consume_token(ARROW);
-            if (jj_2_2(3)) {
-                LambdaExpression();
-            } else {
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case START_MAP:
-                case INTEGER_LITERAL:
-                case FLOATING_POINT_LITERAL:
-                case STRING_LITERAL:
-                case TRUE:
-                case FALSE:
-                case NULL:
-                case LPAREN:
-                case LBRACK:
-                case NOT0:
-                case NOT1:
-                case EMPTY:
-                case MINUS:
-                case IDENTIFIER:
-                    Choice();
-                    break;
-                default:
-                    jj_la1[5] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-            }
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    final public void LambdaParameters() throws ParseException {
-        /* @bgen(jjtree) LambdaParameters */
-        AstLambdaParameters jjtn000 = new AstLambdaParameters(JJTLAMBDAPARAMETERS);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case IDENTIFIER:
-                Identifier();
-                break;
-            case LPAREN:
-                jj_consume_token(LPAREN);
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case IDENTIFIER:
-                    Identifier();
-                    label_3: while (true) {
-                        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                        case COMMA:
-                            ;
-                            break;
-                        default:
-                            jj_la1[6] = jj_gen;
-                            break label_3;
-                        }
-                        jj_consume_token(COMMA);
-                        Identifier();
-                    }
-                    break;
-                default:
-                    jj_la1[7] = jj_gen;
-                    ;
-                }
-                jj_consume_token(RPAREN);
-                break;
-            default:
-                jj_la1[8] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * Choice For Choice markup a ? b : c, right associative
-     */
-    final public void Choice() throws ParseException {
-        Or();
-        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-        case QUESTIONMARK:
-            jj_consume_token(QUESTIONMARK);
-            Choice();
-            jj_consume_token(COLON);
-            AstChoice jjtn001 = new AstChoice(JJTCHOICE);
-            boolean jjtc001 = true;
-            jjtree.openNodeScope(jjtn001);
-            try {
-                Choice();
-            } catch (Throwable jjte001) {
-                if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                } else {
-                    jjtree.popNode();
-                }
-                if (jjte001 instanceof RuntimeException) {
-                    {
-                        if (true) {
-                            throw (RuntimeException) jjte001;
-                        }
-                    }
-                }
-                if (jjte001 instanceof ParseException) {
-                    {
-                        if (true) {
-                            throw (ParseException) jjte001;
-                        }
-                    }
-                }
-                {
-                    if (true) {
-                        throw (Error) jjte001;
-                    }
-                }
-            } finally {
-                if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001, 3);
-                }
-            }
-            break;
-        default:
-            jj_la1[9] = jj_gen;
-            ;
-        }
-    }
-
-    /*
-     * Or For 'or' '||', then And
-     */
-    final public void Or() throws ParseException {
-        And();
-        label_4: while (true) {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case OR0:
-            case OR1:
-                ;
-                break;
-            default:
-                jj_la1[10] = jj_gen;
-                break label_4;
-            }
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case OR0:
-                jj_consume_token(OR0);
-                break;
-            case OR1:
-                jj_consume_token(OR1);
-                break;
-            default:
-                jj_la1[11] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-            AstOr jjtn001 = new AstOr(JJTOR);
-            boolean jjtc001 = true;
-            jjtree.openNodeScope(jjtn001);
-            try {
-                And();
-            } catch (Throwable jjte001) {
-                if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                } else {
-                    jjtree.popNode();
-                }
-                if (jjte001 instanceof RuntimeException) {
-                    {
-                        if (true) {
-                            throw (RuntimeException) jjte001;
-                        }
-                    }
-                }
-                if (jjte001 instanceof ParseException) {
-                    {
-                        if (true) {
-                            throw (ParseException) jjte001;
-                        }
-                    }
-                }
-                {
-                    if (true) {
-                        throw (Error) jjte001;
-                    }
-                }
-            } finally {
-                if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001, 2);
-                }
-            }
-        }
-    }
-
-    /*
-     * And For 'and' '&&', then Equality
-     */
-    final public void And() throws ParseException {
-        Equality();
-        label_5: while (true) {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case AND0:
-            case AND1:
-                ;
-                break;
-            default:
-                jj_la1[12] = jj_gen;
-                break label_5;
-            }
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case AND0:
-                jj_consume_token(AND0);
-                break;
-            case AND1:
-                jj_consume_token(AND1);
-                break;
-            default:
-                jj_la1[13] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-            AstAnd jjtn001 = new AstAnd(JJTAND);
-            boolean jjtc001 = true;
-            jjtree.openNodeScope(jjtn001);
-            try {
-                Equality();
-            } catch (Throwable jjte001) {
-                if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                } else {
-                    jjtree.popNode();
-                }
-                if (jjte001 instanceof RuntimeException) {
-                    {
-                        if (true) {
-                            throw (RuntimeException) jjte001;
-                        }
-                    }
-                }
-                if (jjte001 instanceof ParseException) {
-                    {
-                        if (true) {
-                            throw (ParseException) jjte001;
-                        }
-                    }
-                }
-                {
-                    if (true) {
-                        throw (Error) jjte001;
-                    }
-                }
-            } finally {
-                if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001, 2);
-                }
-            }
-        }
-    }
-
-    /*
-     * Equality For '==' 'eq' '!=' 'ne', then Compare
-     */
-    final public void Equality() throws ParseException {
-        Compare();
-        label_6: while (true) {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case EQ0:
-            case EQ1:
-            case NE0:
-            case NE1:
-                ;
-                break;
-            default:
-                jj_la1[14] = jj_gen;
-                break label_6;
-            }
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case EQ0:
-            case EQ1:
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case EQ0:
-                    jj_consume_token(EQ0);
-                    break;
-                case EQ1:
-                    jj_consume_token(EQ1);
-                    break;
-                default:
-                    jj_la1[15] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-                AstEqual jjtn001 = new AstEqual(JJTEQUAL);
-                boolean jjtc001 = true;
-                jjtree.openNodeScope(jjtn001);
-                try {
-                    Compare();
-                } catch (Throwable jjte001) {
-                    if (jjtc001) {
-                        jjtree.clearNodeScope(jjtn001);
-                        jjtc001 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte001 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte001;
-                            }
-                        }
-                    }
-                    if (jjte001 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte001;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte001;
-                        }
-                    }
-                } finally {
-                    if (jjtc001) {
-                        jjtree.closeNodeScope(jjtn001, 2);
-                    }
-                }
-                break;
-            case NE0:
-            case NE1:
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case NE0:
-                    jj_consume_token(NE0);
-                    break;
-                case NE1:
-                    jj_consume_token(NE1);
-                    break;
-                default:
-                    jj_la1[16] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-                AstNotEqual jjtn002 = new AstNotEqual(JJTNOTEQUAL);
-                boolean jjtc002 = true;
-                jjtree.openNodeScope(jjtn002);
-                try {
-                    Compare();
-                } catch (Throwable jjte002) {
-                    if (jjtc002) {
-                        jjtree.clearNodeScope(jjtn002);
-                        jjtc002 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte002 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte002;
-                            }
-                        }
-                    }
-                    if (jjte002 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte002;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte002;
-                        }
-                    }
-                } finally {
-                    if (jjtc002) {
-                        jjtree.closeNodeScope(jjtn002, 2);
-                    }
-                }
-                break;
-            default:
-                jj_la1[17] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-        }
-    }
-
-    /*
-     * Compare For a bunch of them, then Math
-     */
-    final public void Compare() throws ParseException {
-        Concatenation();
-        label_7: while (true) {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case GT0:
-            case GT1:
-            case LT0:
-            case LT1:
-            case GE0:
-            case GE1:
-            case LE0:
-            case LE1:
-                ;
-                break;
-            default:
-                jj_la1[18] = jj_gen;
-                break label_7;
-            }
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case LT0:
-            case LT1:
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case LT0:
-                    jj_consume_token(LT0);
-                    break;
-                case LT1:
-                    jj_consume_token(LT1);
-                    break;
-                default:
-                    jj_la1[19] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-                AstLessThan jjtn001 = new AstLessThan(JJTLESSTHAN);
-                boolean jjtc001 = true;
-                jjtree.openNodeScope(jjtn001);
-                try {
-                    Concatenation();
-                } catch (Throwable jjte001) {
-                    if (jjtc001) {
-                        jjtree.clearNodeScope(jjtn001);
-                        jjtc001 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte001 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte001;
-                            }
-                        }
-                    }
-                    if (jjte001 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte001;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte001;
-                        }
-                    }
-                } finally {
-                    if (jjtc001) {
-                        jjtree.closeNodeScope(jjtn001, 2);
-                    }
-                }
-                break;
-            case GT0:
-            case GT1:
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case GT0:
-                    jj_consume_token(GT0);
-                    break;
-                case GT1:
-                    jj_consume_token(GT1);
-                    break;
-                default:
-                    jj_la1[20] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-                AstGreaterThan jjtn002 = new AstGreaterThan(JJTGREATERTHAN);
-                boolean jjtc002 = true;
-                jjtree.openNodeScope(jjtn002);
-                try {
-                    Concatenation();
-                } catch (Throwable jjte002) {
-                    if (jjtc002) {
-                        jjtree.clearNodeScope(jjtn002);
-                        jjtc002 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte002 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte002;
-                            }
-                        }
-                    }
-                    if (jjte002 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte002;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte002;
-                        }
-                    }
-                } finally {
-                    if (jjtc002) {
-                        jjtree.closeNodeScope(jjtn002, 2);
-                    }
-                }
-                break;
-            case LE0:
-            case LE1:
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case LE0:
-                    jj_consume_token(LE0);
-                    break;
-                case LE1:
-                    jj_consume_token(LE1);
-                    break;
-                default:
-                    jj_la1[21] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-                AstLessThanEqual jjtn003 = new AstLessThanEqual(JJTLESSTHANEQUAL);
-                boolean jjtc003 = true;
-                jjtree.openNodeScope(jjtn003);
-                try {
-                    Concatenation();
-                } catch (Throwable jjte003) {
-                    if (jjtc003) {
-                        jjtree.clearNodeScope(jjtn003);
-                        jjtc003 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte003 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte003;
-                            }
-                        }
-                    }
-                    if (jjte003 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte003;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte003;
-                        }
-                    }
-                } finally {
-                    if (jjtc003) {
-                        jjtree.closeNodeScope(jjtn003, 2);
-                    }
-                }
-                break;
-            case GE0:
-            case GE1:
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case GE0:
-                    jj_consume_token(GE0);
-                    break;
-                case GE1:
-                    jj_consume_token(GE1);
-                    break;
-                default:
-                    jj_la1[22] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-                AstGreaterThanEqual jjtn004 = new AstGreaterThanEqual(JJTGREATERTHANEQUAL);
-                boolean jjtc004 = true;
-                jjtree.openNodeScope(jjtn004);
-                try {
-                    Concatenation();
-                } catch (Throwable jjte004) {
-                    if (jjtc004) {
-                        jjtree.clearNodeScope(jjtn004);
-                        jjtc004 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte004 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte004;
-                            }
-                        }
-                    }
-                    if (jjte004 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte004;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte004;
-                        }
-                    }
-                } finally {
-                    if (jjtc004) {
-                        jjtree.closeNodeScope(jjtn004, 2);
-                    }
-                }
-                break;
-            default:
-                jj_la1[23] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-        }
-    }
-
-    /*
-     * Concatenation For '&', then Math()
-     */
-    final public void Concatenation() throws ParseException {
-        Math();
-        label_8: while (true) {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case CONCAT:
-                ;
-                break;
-            default:
-                jj_la1[24] = jj_gen;
-                break label_8;
-            }
-            jj_consume_token(CONCAT);
-            AstConcat jjtn001 = new AstConcat(JJTCONCAT);
-            boolean jjtc001 = true;
-            jjtree.openNodeScope(jjtn001);
-            try {
-                Math();
-            } catch (Throwable jjte001) {
-                if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                } else {
-                    jjtree.popNode();
-                }
-                if (jjte001 instanceof RuntimeException) {
-                    {
-                        if (true) {
-                            throw (RuntimeException) jjte001;
-                        }
-                    }
-                }
-                if (jjte001 instanceof ParseException) {
-                    {
-                        if (true) {
-                            throw (ParseException) jjte001;
-                        }
-                    }
-                }
-                {
-                    if (true) {
-                        throw (Error) jjte001;
-                    }
-                }
-            } finally {
-                if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001, 2);
-                }
-            }
-        }
-    }
-
-    /*
-     * Math For '+' '-', then Multiplication
-     */
-    final public void Math() throws ParseException {
-        Multiplication();
-        label_9: while (true) {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case PLUS:
-            case MINUS:
-                ;
-                break;
-            default:
-                jj_la1[25] = jj_gen;
-                break label_9;
-            }
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case PLUS:
-                jj_consume_token(PLUS);
-                AstPlus jjtn001 = new AstPlus(JJTPLUS);
-                boolean jjtc001 = true;
-                jjtree.openNodeScope(jjtn001);
-                try {
-                    Multiplication();
-                } catch (Throwable jjte001) {
-                    if (jjtc001) {
-                        jjtree.clearNodeScope(jjtn001);
-                        jjtc001 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte001 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte001;
-                            }
-                        }
-                    }
-                    if (jjte001 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte001;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte001;
-                        }
-                    }
-                } finally {
-                    if (jjtc001) {
-                        jjtree.closeNodeScope(jjtn001, 2);
-                    }
-                }
-                break;
-            case MINUS:
-                jj_consume_token(MINUS);
-                AstMinus jjtn002 = new AstMinus(JJTMINUS);
-                boolean jjtc002 = true;
-                jjtree.openNodeScope(jjtn002);
-                try {
-                    Multiplication();
-                } catch (Throwable jjte002) {
-                    if (jjtc002) {
-                        jjtree.clearNodeScope(jjtn002);
-                        jjtc002 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte002 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte002;
-                            }
-                        }
-                    }
-                    if (jjte002 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte002;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte002;
-                        }
-                    }
-                } finally {
-                    if (jjtc002) {
-                        jjtree.closeNodeScope(jjtn002, 2);
-                    }
-                }
-                break;
-            default:
-                jj_la1[26] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-        }
-    }
-
-    /*
-     * Multiplication For a bunch of them, then Unary
-     */
-    final public void Multiplication() throws ParseException {
-        Unary();
-        label_10: while (true) {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case MULT:
-            case DIV0:
-            case DIV1:
-            case MOD0:
-            case MOD1:
-                ;
-                break;
-            default:
-                jj_la1[27] = jj_gen;
-                break label_10;
-            }
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case MULT:
-                jj_consume_token(MULT);
-                AstMult jjtn001 = new AstMult(JJTMULT);
-                boolean jjtc001 = true;
-                jjtree.openNodeScope(jjtn001);
-                try {
-                    Unary();
-                } catch (Throwable jjte001) {
-                    if (jjtc001) {
-                        jjtree.clearNodeScope(jjtn001);
-                        jjtc001 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte001 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte001;
-                            }
-                        }
-                    }
-                    if (jjte001 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte001;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte001;
-                        }
-                    }
-                } finally {
-                    if (jjtc001) {
-                        jjtree.closeNodeScope(jjtn001, 2);
-                    }
-                }
-                break;
-            case DIV0:
-            case DIV1:
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case DIV0:
-                    jj_consume_token(DIV0);
-                    break;
-                case DIV1:
-                    jj_consume_token(DIV1);
-                    break;
-                default:
-                    jj_la1[28] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-                AstDiv jjtn002 = new AstDiv(JJTDIV);
-                boolean jjtc002 = true;
-                jjtree.openNodeScope(jjtn002);
-                try {
-                    Unary();
-                } catch (Throwable jjte002) {
-                    if (jjtc002) {
-                        jjtree.clearNodeScope(jjtn002);
-                        jjtc002 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte002 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte002;
-                            }
-                        }
-                    }
-                    if (jjte002 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte002;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte002;
-                        }
-                    }
-                } finally {
-                    if (jjtc002) {
-                        jjtree.closeNodeScope(jjtn002, 2);
-                    }
-                }
-                break;
-            case MOD0:
-            case MOD1:
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case MOD0:
-                    jj_consume_token(MOD0);
-                    break;
-                case MOD1:
-                    jj_consume_token(MOD1);
-                    break;
-                default:
-                    jj_la1[29] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-                AstMod jjtn003 = new AstMod(JJTMOD);
-                boolean jjtc003 = true;
-                jjtree.openNodeScope(jjtn003);
-                try {
-                    Unary();
-                } catch (Throwable jjte003) {
-                    if (jjtc003) {
-                        jjtree.clearNodeScope(jjtn003);
-                        jjtc003 = false;
-                    } else {
-                        jjtree.popNode();
-                    }
-                    if (jjte003 instanceof RuntimeException) {
-                        {
-                            if (true) {
-                                throw (RuntimeException) jjte003;
-                            }
-                        }
-                    }
-                    if (jjte003 instanceof ParseException) {
-                        {
-                            if (true) {
-                                throw (ParseException) jjte003;
-                            }
-                        }
-                    }
-                    {
-                        if (true) {
-                            throw (Error) jjte003;
-                        }
-                    }
-                } finally {
-                    if (jjtc003) {
-                        jjtree.closeNodeScope(jjtn003, 2);
-                    }
-                }
-                break;
-            default:
-                jj_la1[30] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-        }
-    }
-
-    /*
-     * Unary For '-' '!' 'not' 'empty', then Value
-     */
-    final public void Unary() throws ParseException {
-        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-        case MINUS:
-            jj_consume_token(MINUS);
-            AstNegative jjtn001 = new AstNegative(JJTNEGATIVE);
-            boolean jjtc001 = true;
-            jjtree.openNodeScope(jjtn001);
-            try {
-                Unary();
-            } catch (Throwable jjte001) {
-                if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                } else {
-                    jjtree.popNode();
-                }
-                if (jjte001 instanceof RuntimeException) {
-                    {
-                        if (true) {
-                            throw (RuntimeException) jjte001;
-                        }
-                    }
-                }
-                if (jjte001 instanceof ParseException) {
-                    {
-                        if (true) {
-                            throw (ParseException) jjte001;
-                        }
-                    }
-                }
-                {
-                    if (true) {
-                        throw (Error) jjte001;
-                    }
-                }
-            } finally {
-                if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001, true);
-                }
-            }
-            break;
-        case NOT0:
-        case NOT1:
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case NOT0:
-                jj_consume_token(NOT0);
-                break;
-            case NOT1:
-                jj_consume_token(NOT1);
-                break;
-            default:
-                jj_la1[31] = jj_gen;
-                jj_consume_token(-1);
-                throw new ParseException();
-            }
-            AstNot jjtn002 = new AstNot(JJTNOT);
-            boolean jjtc002 = true;
-            jjtree.openNodeScope(jjtn002);
-            try {
-                Unary();
-            } catch (Throwable jjte002) {
-                if (jjtc002) {
-                    jjtree.clearNodeScope(jjtn002);
-                    jjtc002 = false;
-                } else {
-                    jjtree.popNode();
-                }
-                if (jjte002 instanceof RuntimeException) {
-                    {
-                        if (true) {
-                            throw (RuntimeException) jjte002;
-                        }
-                    }
-                }
-                if (jjte002 instanceof ParseException) {
-                    {
-                        if (true) {
-                            throw (ParseException) jjte002;
-                        }
-                    }
-                }
-                {
-                    if (true) {
-                        throw (Error) jjte002;
-                    }
-                }
-            } finally {
-                if (jjtc002) {
-                    jjtree.closeNodeScope(jjtn002, true);
-                }
-            }
-            break;
-        case EMPTY:
-            jj_consume_token(EMPTY);
-            AstEmpty jjtn003 = new AstEmpty(JJTEMPTY);
-            boolean jjtc003 = true;
-            jjtree.openNodeScope(jjtn003);
-            try {
-                Unary();
-            } catch (Throwable jjte003) {
-                if (jjtc003) {
-                    jjtree.clearNodeScope(jjtn003);
-                    jjtc003 = false;
-                } else {
-                    jjtree.popNode();
-                }
-                if (jjte003 instanceof RuntimeException) {
-                    {
-                        if (true) {
-                            throw (RuntimeException) jjte003;
-                        }
-                    }
-                }
-                if (jjte003 instanceof ParseException) {
-                    {
-                        if (true) {
-                            throw (ParseException) jjte003;
-                        }
-                    }
-                }
-                {
-                    if (true) {
-                        throw (Error) jjte003;
-                    }
-                }
-            } finally {
-                if (jjtc003) {
-                    jjtree.closeNodeScope(jjtn003, true);
-                }
-            }
-            break;
-        case START_MAP:
-        case INTEGER_LITERAL:
-        case FLOATING_POINT_LITERAL:
-        case STRING_LITERAL:
-        case TRUE:
-        case FALSE:
-        case NULL:
-        case LPAREN:
-        case LBRACK:
-        case IDENTIFIER:
-            Value();
-            break;
-        default:
-            jj_la1[32] = jj_gen;
-            jj_consume_token(-1);
-            throw new ParseException();
-        }
-    }
-
-    /*
-     * Value Defines Prefix plus zero or more Suffixes
-     */
-    final public void Value() throws ParseException {
-        AstValue jjtn001 = new AstValue(JJTVALUE);
-        boolean jjtc001 = true;
-        jjtree.openNodeScope(jjtn001);
-        try {
-            ValuePrefix();
-            label_11: while (true) {
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case DOT:
-                case LBRACK:
-                    ;
-                    break;
-                default:
-                    jj_la1[33] = jj_gen;
-                    break label_11;
-                }
-                ValueSuffix();
-            }
-        } catch (Throwable jjte001) {
-            if (jjtc001) {
-                jjtree.clearNodeScope(jjtn001);
-                jjtc001 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte001 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte001;
-                    }
-                }
-            }
-            if (jjte001 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte001;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte001;
-                }
-            }
-        } finally {
-            if (jjtc001) {
-                jjtree.closeNodeScope(jjtn001, jjtree.nodeArity() > 1);
-            }
-        }
-    }
-
-    /*
-     * ValuePrefix For Literals, Variables, and Functions
-     */
-    final public void ValuePrefix() throws ParseException {
-        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-        case INTEGER_LITERAL:
-        case FLOATING_POINT_LITERAL:
-        case STRING_LITERAL:
-        case TRUE:
-        case FALSE:
-        case NULL:
-            Literal();
-            break;
-        case START_MAP:
-        case LPAREN:
-        case LBRACK:
-        case IDENTIFIER:
-            NonLiteral();
-            break;
-        default:
-            jj_la1[34] = jj_gen;
-            jj_consume_token(-1);
-            throw new ParseException();
-        }
-    }
-
-    /*
-     * ValueSuffix Either dot or bracket notation
-     */
-    final public void ValueSuffix() throws ParseException {
-        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-        case DOT:
-            DotSuffix();
-            break;
-        case LBRACK:
-            BracketSuffix();
-            break;
-        default:
-            jj_la1[35] = jj_gen;
-            jj_consume_token(-1);
-            throw new ParseException();
-        }
-    }
-
-    /*
-     * DotSuffix Dot Property and Dot Method
-     */
-    final public void DotSuffix() throws ParseException {
-        /* @bgen(jjtree) DotSuffix */
-        AstDotSuffix jjtn000 = new AstDotSuffix(JJTDOTSUFFIX);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        Token t = null;
-        try {
-            jj_consume_token(DOT);
-            t = jj_consume_token(IDENTIFIER);
-            jjtn000.setImage(t.image);
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case LPAREN:
-                MethodArguments();
-                break;
-            default:
-                jj_la1[36] = jj_gen;
-                ;
-            }
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * BracketSuffix Sub Expression Suffix
-     */
-    final public void BracketSuffix() throws ParseException {
-        /* @bgen(jjtree) BracketSuffix */
-        AstBracketSuffix jjtn000 = new AstBracketSuffix(JJTBRACKETSUFFIX);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            jj_consume_token(LBRACK);
-            Expression();
-            jj_consume_token(RBRACK);
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case LPAREN:
-                MethodArguments();
-                break;
-            default:
-                jj_la1[37] = jj_gen;
-                ;
-            }
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * MethodArguments
-     */
-    final public void MethodArguments() throws ParseException {
-        /* @bgen(jjtree) MethodArguments */
-        AstMethodArguments jjtn000 = new AstMethodArguments(JJTMETHODARGUMENTS);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            jj_consume_token(LPAREN);
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case START_MAP:
-            case INTEGER_LITERAL:
-            case FLOATING_POINT_LITERAL:
-            case STRING_LITERAL:
-            case TRUE:
-            case FALSE:
-            case NULL:
-            case LPAREN:
-            case LBRACK:
-            case NOT0:
-            case NOT1:
-            case EMPTY:
-            case MINUS:
-            case IDENTIFIER:
-                Expression();
-                label_12: while (true) {
-                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                    case COMMA:
-                        ;
-                        break;
-                    default:
-                        jj_la1[38] = jj_gen;
-                        break label_12;
-                    }
-                    jj_consume_token(COMMA);
-                    Expression();
-                }
-                break;
-            default:
-                jj_la1[39] = jj_gen;
-                ;
-            }
-            jj_consume_token(RPAREN);
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * Parenthesized Lambda Expression, with optional invokation
-     */
-    final public void LambdaExpressionOrCall() throws ParseException {
-        /* @bgen(jjtree) LambdaExpression */
-        AstLambdaExpression jjtn000 = new AstLambdaExpression(JJTLAMBDAEXPRESSION);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            jj_consume_token(LPAREN);
-            LambdaParameters();
-            jj_consume_token(ARROW);
-            if (jj_2_3(3)) {
-                LambdaExpression();
-            } else {
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case START_MAP:
-                case INTEGER_LITERAL:
-                case FLOATING_POINT_LITERAL:
-                case STRING_LITERAL:
-                case TRUE:
-                case FALSE:
-                case NULL:
-                case LPAREN:
-                case LBRACK:
-                case NOT0:
-                case NOT1:
-                case EMPTY:
-                case MINUS:
-                case IDENTIFIER:
-                    Choice();
-                    break;
-                default:
-                    jj_la1[40] = jj_gen;
-                    jj_consume_token(-1);
-                    throw new ParseException();
-                }
-            }
-            jj_consume_token(RPAREN);
-            label_13: while (true) {
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case LPAREN:
-                    ;
-                    break;
-                default:
-                    jj_la1[41] = jj_gen;
-                    break label_13;
-                }
-                MethodArguments();
-            }
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * NonLiteral For Grouped Operations, Identifiers, and Functions
-     */
-    final public void NonLiteral() throws ParseException {
-        if (jj_2_4(4)) {
-            LambdaExpressionOrCall();
-        } else {
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case LPAREN:
-                jj_consume_token(LPAREN);
-                Expression();
-                jj_consume_token(RPAREN);
-                break;
-            default:
-                jj_la1[42] = jj_gen;
-                if (jj_2_5(4)) {
-                    Function();
-                } else {
-                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                    case IDENTIFIER:
-                        Identifier();
-                        break;
-                    case START_MAP:
-                        MapData();
-                        break;
-                    case LBRACK:
-                        ListData();
-                        break;
-                    default:
-                        jj_la1[43] = jj_gen;
-                        jj_consume_token(-1);
-                        throw new ParseException();
-                    }
-                }
-            }
-        }
-    }
-
-    final public void MapData() throws ParseException {
-        /* @bgen(jjtree) MapData */
-        AstMapData jjtn000 = new AstMapData(JJTMAPDATA);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            jj_consume_token(START_MAP);
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case START_MAP:
-            case INTEGER_LITERAL:
-            case FLOATING_POINT_LITERAL:
-            case STRING_LITERAL:
-            case TRUE:
-            case FALSE:
-            case NULL:
-            case LPAREN:
-            case LBRACK:
-            case NOT0:
-            case NOT1:
-            case EMPTY:
-            case MINUS:
-            case IDENTIFIER:
-                MapEntry();
-                label_14: while (true) {
-                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                    case COMMA:
-                        ;
-                        break;
-                    default:
-                        jj_la1[44] = jj_gen;
-                        break label_14;
-                    }
-                    jj_consume_token(COMMA);
-                    MapEntry();
-                }
-                break;
-            default:
-                jj_la1[45] = jj_gen;
-                ;
-            }
-            jj_consume_token(RCURL);
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    final public void MapEntry() throws ParseException {
-        /* @bgen(jjtree) MapEntry */
-        AstMapEntry jjtn000 = new AstMapEntry(JJTMAPENTRY);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            Expression();
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case COLON:
-                jj_consume_token(COLON);
-                Expression();
-                break;
-            default:
-                jj_la1[46] = jj_gen;
-                ;
-            }
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    final public void ListData() throws ParseException {
-        /* @bgen(jjtree) ListData */
-        AstListData jjtn000 = new AstListData(JJTLISTDATA);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            jj_consume_token(LBRACK);
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case START_MAP:
-            case INTEGER_LITERAL:
-            case FLOATING_POINT_LITERAL:
-            case STRING_LITERAL:
-            case TRUE:
-            case FALSE:
-            case NULL:
-            case LPAREN:
-            case LBRACK:
-            case NOT0:
-            case NOT1:
-            case EMPTY:
-            case MINUS:
-            case IDENTIFIER:
-                Expression();
-                label_15: while (true) {
-                    switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                    case COMMA:
-                        ;
-                        break;
-                    default:
-                        jj_la1[47] = jj_gen;
-                        break label_15;
-                    }
-                    jj_consume_token(COMMA);
-                    Expression();
-                }
-                break;
-            default:
-                jj_la1[48] = jj_gen;
-                ;
-            }
-            jj_consume_token(RBRACK);
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * Identifier Java Language Identifier
-     */
-    final public void Identifier() throws ParseException {
-        /* @bgen(jjtree) Identifier */
-        AstIdentifier jjtn000 = new AstIdentifier(JJTIDENTIFIER);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        Token t = null;
-        try {
-            t = jj_consume_token(IDENTIFIER);
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtc000 = false;
-            jjtn000.setImage(t.image);
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * Function Namespace:Name(a,b,c)
-     */
-    final public void Function() throws ParseException {
-        /* @bgen(jjtree) Function */
-        AstFunction jjtn000 = new AstFunction(JJTFUNCTION);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        Token t0 = null;
-        Token t1 = null;
-        try {
-            t0 = jj_consume_token(IDENTIFIER);
-            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-            case COLON:
-                jj_consume_token(COLON);
-                t1 = jj_consume_token(IDENTIFIER);
-                break;
-            default:
-                jj_la1[49] = jj_gen;
-                ;
-            }
-            if (t1 != null) {
-                jjtn000.setPrefix(t0.image);
-                jjtn000.setLocalName(t1.image);
-            } else {
-                jjtn000.setLocalName(t0.image);
-            }
-            label_16: while (true) {
-                MethodArguments();
-                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-                case LPAREN:
-                    ;
-                    break;
-                default:
-                    jj_la1[50] = jj_gen;
-                    break label_16;
-                }
-            }
-        } catch (Throwable jjte000) {
-            if (jjtc000) {
-                jjtree.clearNodeScope(jjtn000);
-                jjtc000 = false;
-            } else {
-                jjtree.popNode();
-            }
-            if (jjte000 instanceof RuntimeException) {
-                {
-                    if (true) {
-                        throw (RuntimeException) jjte000;
-                    }
-                }
-            }
-            if (jjte000 instanceof ParseException) {
-                {
-                    if (true) {
-                        throw (ParseException) jjte000;
-                    }
-                }
-            }
-            {
-                if (true) {
-                    throw (Error) jjte000;
-                }
-            }
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * Literal Reserved Keywords
-     */
-    final public void Literal() throws ParseException {
-        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-        case TRUE:
-        case FALSE:
-            Boolean();
-            break;
-        case FLOATING_POINT_LITERAL:
-            FloatingPoint();
-            break;
-        case INTEGER_LITERAL:
-            Integer();
-            break;
-        case STRING_LITERAL:
-            String();
-            break;
-        case NULL:
-            Null();
-            break;
-        default:
-            jj_la1[51] = jj_gen;
-            jj_consume_token(-1);
-            throw new ParseException();
-        }
-    }
-
-    /*
-     * Boolean For 'true' 'false'
-     */
-    final public void Boolean() throws ParseException {
-        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
-        case TRUE:
-            AstTrue jjtn001 = new AstTrue(JJTTRUE);
-            boolean jjtc001 = true;
-            jjtree.openNodeScope(jjtn001);
-            try {
-                jj_consume_token(TRUE);
-            } finally {
-                if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001, true);
-                }
-            }
-            break;
-        case FALSE:
-            AstFalse jjtn002 = new AstFalse(JJTFALSE);
-            boolean jjtc002 = true;
-            jjtree.openNodeScope(jjtn002);
-            try {
-                jj_consume_token(FALSE);
-            } finally {
-                if (jjtc002) {
-                    jjtree.closeNodeScope(jjtn002, true);
-                }
-            }
-            break;
-        default:
-            jj_la1[52] = jj_gen;
-            jj_consume_token(-1);
-            throw new ParseException();
-        }
-    }
-
-    /*
-     * FloatinPoint For Decimal and Floating Point Literals
-     */
-    final public void FloatingPoint() throws ParseException {
-        /* @bgen(jjtree) FloatingPoint */
-        AstFloatingPoint jjtn000 = new AstFloatingPoint(JJTFLOATINGPOINT);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        Token t = null;
-        try {
-            t = jj_consume_token(FLOATING_POINT_LITERAL);
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtc000 = false;
-            jjtn000.setImage(t.image);
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * Integer For Simple Numeric Literals
-     */
-    final public void Integer() throws ParseException {
-        /* @bgen(jjtree) Integer */
-        AstInteger jjtn000 = new AstInteger(JJTINTEGER);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        Token t = null;
-        try {
-            t = jj_consume_token(INTEGER_LITERAL);
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtc000 = false;
-            jjtn000.setImage(t.image);
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * String For Quoted Literals
-     */
-    final public void String() throws ParseException {
-        /* @bgen(jjtree) String */
-        AstString jjtn000 = new AstString(JJTSTRING);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        Token t = null;
-        try {
-            t = jj_consume_token(STRING_LITERAL);
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtc000 = false;
-            jjtn000.setImage(t.image);
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    /*
-     * Null For 'null'
-     */
-    final public void Null() throws ParseException {
-        /* @bgen(jjtree) Null */
-        AstNull jjtn000 = new AstNull(JJTNULL);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);
-        try {
-            jj_consume_token(NULL);
-        } finally {
-            if (jjtc000) {
-                jjtree.closeNodeScope(jjtn000, true);
-            }
-        }
-    }
-
-    private boolean jj_2_1(int xla) {
-        jj_la = xla;
-        jj_lastpos = jj_scanpos = token;
-        try {
-            return !jj_3_1();
-        } catch (LookaheadSuccess ls) {
-            return true;
-        } finally {
-            jj_save(0, xla);
-        }
-    }
-
-    private boolean jj_2_2(int xla) {
-        jj_la = xla;
-        jj_lastpos = jj_scanpos = token;
-        try {
-            return !jj_3_2();
-        } catch (LookaheadSuccess ls) {
-            return true;
-        } finally {
-            jj_save(1, xla);
-        }
-    }
-
-    private boolean jj_2_3(int xla) {
-        jj_la = xla;
-        jj_lastpos = jj_scanpos = token;
-        try {
-            return !jj_3_3();
-        } catch (LookaheadSuccess ls) {
-            return true;
-        } finally {
-            jj_save(2, xla);
-        }
-    }
-
-    private boolean jj_2_4(int xla) {
-        jj_la = xla;
-        jj_lastpos = jj_scanpos = token;
-        try {
-            return !jj_3_4();
-        } catch (LookaheadSuccess ls) {
-            return true;
-        } finally {
-            jj_save(3, xla);
-        }
-    }
-
-    private boolean jj_2_5(int xla) {
-        jj_la = xla;
-        jj_lastpos = jj_scanpos = token;
-        try {
-            return !jj_3_5();
-        } catch (LookaheadSuccess ls) {
-            return true;
-        } finally {
-            jj_save(4, xla);
-        }
-    }
-
-    private boolean jj_3R_89() {
-        if (jj_scan_token(LBRACK)) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_102()) {
-            jj_scanpos = xsp;
-        }
-        if (jj_scan_token(RBRACK)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_33() {
-        if (jj_scan_token(COMMA)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_31() {
-        if (jj_3R_34()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_49()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_47() {
-        if (jj_scan_token(QUESTIONMARK)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_103() {
-        if (jj_3R_35()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_101() {
-        if (jj_3R_103()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_27() {
-        if (jj_3R_31()) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_47()) {
-            jj_scanpos = xsp;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_79() {
-        if (jj_3R_89()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_88() {
-        if (jj_scan_token(START_MAP)) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_101()) {
-            jj_scanpos = xsp;
-        }
-        if (jj_scan_token(RCURL)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_78() {
-        if (jj_3R_88()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_77() {
-        if (jj_3R_29()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3_5() {
-        if (jj_3R_19()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_30() {
-        if (jj_3R_29()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_33()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_76() {
-        if (jj_scan_token(LPAREN)) {
-            return true;
-        }
-        if (jj_3R_35()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_36() {
-        if (jj_scan_token(COMMA)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3_4() {
-        if (jj_3R_18()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_69() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3_4()) {
-            jj_scanpos = xsp;
-            if (jj_3R_76()) {
-                jj_scanpos = xsp;
-                if (jj_3_5()) {
-                    jj_scanpos = xsp;
-                    if (jj_3R_77()) {
-                        jj_scanpos = xsp;
-                        if (jj_3R_78()) {
-                            jj_scanpos = xsp;
-                            if (jj_3R_79()) {
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_26() {
-        if (jj_scan_token(LPAREN)) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_30()) {
-            jj_scanpos = xsp;
-        }
-        if (jj_scan_token(RPAREN)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_20() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_25()) {
-            jj_scanpos = xsp;
-            if (jj_3R_26()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_25() {
-        if (jj_3R_29()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_45() {
-        if (jj_scan_token(ASSIGN)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3_2() {
-        if (jj_3R_17()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3_3() {
-        if (jj_3R_17()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_17() {
-        if (jj_3R_20()) {
-            return true;
-        }
-        if (jj_scan_token(ARROW)) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3_2()) {
-            jj_scanpos = xsp;
-            if (jj_3R_21()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_32() {
-        if (jj_3R_35()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_36()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_41() {
-        if (jj_scan_token(SEMICOLON)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_18() {
-        if (jj_scan_token(LPAREN)) {
-            return true;
-        }
-        if (jj_3R_20()) {
-            return true;
-        }
-        if (jj_scan_token(ARROW)) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3_3()) {
-            jj_scanpos = xsp;
-            if (jj_3R_22()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_43() {
-        if (jj_3R_27()) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_45()) {
-            jj_scanpos = xsp;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_40() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3_1()) {
-            jj_scanpos = xsp;
-            if (jj_3R_43()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3_1() {
-        if (jj_3R_17()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_28() {
-        if (jj_scan_token(LPAREN)) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_32()) {
-            jj_scanpos = xsp;
-        }
-        if (jj_scan_token(RPAREN)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_38() {
-        if (jj_3R_40()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_41()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_100() {
-        if (jj_scan_token(LBRACK)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_35() {
-        if (jj_3R_38()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_98() {
-        if (jj_3R_100()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_99() {
-        if (jj_scan_token(DOT)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_97() {
-        if (jj_3R_99()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_96() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_97()) {
-            jj_scanpos = xsp;
-            if (jj_3R_98()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_95() {
-        if (jj_3R_96()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_62() {
-        if (jj_3R_69()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_57() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_61()) {
-            jj_scanpos = xsp;
-            if (jj_3R_62()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_61() {
-        if (jj_3R_68()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_55() {
-        if (jj_3R_57()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_95()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_53() {
-        if (jj_3R_55()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_52() {
-        if (jj_scan_token(EMPTY)) {
-            return true;
-        }
-        if (jj_3R_48()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_51() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(39)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(40)) {
-                return true;
-            }
-        }
-        if (jj_3R_48()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_87() {
-        if (jj_scan_token(NULL)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_48() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_50()) {
-            jj_scanpos = xsp;
-            if (jj_3R_51()) {
-                jj_scanpos = xsp;
-                if (jj_3R_52()) {
-                    jj_scanpos = xsp;
-                    if (jj_3R_53()) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_50() {
-        if (jj_scan_token(MINUS)) {
-            return true;
-        }
-        if (jj_3R_48()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_86() {
-        if (jj_scan_token(STRING_LITERAL)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_92() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(53)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(54)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_91() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(51)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(52)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_90() {
-        if (jj_scan_token(MULT)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_80() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_90()) {
-            jj_scanpos = xsp;
-            if (jj_3R_91()) {
-                jj_scanpos = xsp;
-                if (jj_3R_92()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_85() {
-        if (jj_scan_token(INTEGER_LITERAL)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_46() {
-        if (jj_3R_48()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_80()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_84() {
-        if (jj_scan_token(FLOATING_POINT_LITERAL)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_82() {
-        if (jj_scan_token(MINUS)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_70() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_81()) {
-            jj_scanpos = xsp;
-            if (jj_3R_82()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_81() {
-        if (jj_scan_token(PLUS)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_94() {
-        if (jj_scan_token(FALSE)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_93() {
-        if (jj_scan_token(TRUE)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_83() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_93()) {
-            jj_scanpos = xsp;
-            if (jj_3R_94()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_44() {
-        if (jj_3R_46()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_70()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_63() {
-        if (jj_scan_token(CONCAT)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_75() {
-        if (jj_3R_87()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_74() {
-        if (jj_3R_86()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_73() {
-        if (jj_3R_85()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_72() {
-        if (jj_3R_84()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_42() {
-        if (jj_3R_44()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_63()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_67() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(31)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(32)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_68() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_71()) {
-            jj_scanpos = xsp;
-            if (jj_3R_72()) {
-                jj_scanpos = xsp;
-                if (jj_3R_73()) {
-                    jj_scanpos = xsp;
-                    if (jj_3R_74()) {
-                        jj_scanpos = xsp;
-                        if (jj_3R_75()) {
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_71() {
-        if (jj_3R_83()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_66() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(33)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(34)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_23() {
-        if (jj_scan_token(COLON)) {
-            return true;
-        }
-        if (jj_scan_token(IDENTIFIER)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_65() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(27)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(28)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_58() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_64()) {
-            jj_scanpos = xsp;
-            if (jj_3R_65()) {
-                jj_scanpos = xsp;
-                if (jj_3R_66()) {
-                    jj_scanpos = xsp;
-                    if (jj_3R_67()) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_64() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(29)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(30)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_24() {
-        if (jj_3R_28()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_39() {
-        if (jj_3R_42()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_58()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_60() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(37)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(38)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_19() {
-        if (jj_scan_token(IDENTIFIER)) {
-            return true;
-        }
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_23()) {
-            jj_scanpos = xsp;
-        }
-        if (jj_3R_24()) {
-            return true;
-        }
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_24()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_56() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_3R_59()) {
-            jj_scanpos = xsp;
-            if (jj_3R_60()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_59() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(35)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(36)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_54() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(41)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(42)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_37() {
-        if (jj_3R_39()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_56()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_29() {
-        if (jj_scan_token(IDENTIFIER)) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_34() {
-        if (jj_3R_37()) {
-            return true;
-        }
-        Token xsp;
-        while (true) {
-            xsp = jj_scanpos;
-            if (jj_3R_54()) {
-                jj_scanpos = xsp;
-                break;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_102() {
-        if (jj_3R_35()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_21() {
-        if (jj_3R_27()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean jj_3R_49() {
-        Token xsp;
-        xsp = jj_scanpos;
-        if (jj_scan_token(43)) {
-            jj_scanpos = xsp;
-            if (jj_scan_token(44)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean jj_3R_22() {
-        if (jj_3R_27()) {
-            return true;
-        }
-        return false;
-    }
-
-    /** Generated Token Manager. */
-    public ELParserTokenManager token_source;
-    SimpleCharStream jj_input_stream;
-    /** Current token. */
-    public Token token;
-    /** Next token. */
-    public Token jj_nt;
-    private int jj_ntk;
-    private Token jj_scanpos, jj_lastpos;
-    private int jj_la;
-    private int jj_gen;
-    final private int[] jj_la1 = new int[53];
-    static private int[] jj_la1_0;
-    static private int[] jj_la1_1;
-    static {
-        jj_la1_init_0();
-        jj_la1_init_1();
-    }
-
-    private static void jj_la1_init_0() {
-        jj_la1_0 = new int[] { 0xe, 0xe, 0x4000000, 0x0, 0x575a00, 0x575a00, 0x2000000, 0x0, 0x100000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8000000,
-                0x60000000, 0x18000000, 0x0, 0x80000000, 0xf8000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x575a00, 0x480000, 0x575a00, 0x480000, 0x100000,
-                0x100000, 0x2000000, 0x575a00, 0x575a00, 0x100000, 0x100000, 0x400200, 0x2000000, 0x575a00, 0x1000000, 0x2000000, 0x575a00, 0x1000000, 0x100000,
-                0x75800, 0x30000, };
-    }
-
-    private static void jj_la1_init_1() {
-        jj_la1_1 = new int[] { 0x0, 0x0, 0x0, 0x1000000, 0x4022180, 0x4022180, 0x0, 0x4000000, 0x4000000, 0x40000, 0x1800, 0x1800, 0x600, 0x600, 0x78, 0x18,
-                0x60, 0x78, 0x7, 0x0, 0x0, 0x6, 0x1, 0x7, 0x800000, 0x30000, 0x30000, 0x788000, 0x180000, 0x600000, 0x788000, 0x180, 0x4022180, 0x0, 0x4000000,
-                0x0, 0x0, 0x0, 0x0, 0x4022180, 0x4022180, 0x0, 0x0, 0x4000000, 0x0, 0x4022180, 0x0, 0x0, 0x4022180, 0x0, 0x0, 0x0, 0x0, };
-    }
-
-    final private JJCalls[] jj_2_rtns = new JJCalls[5];
-    private boolean jj_rescan = false;
-    private int jj_gc = 0;
-
-    /** Constructor with InputStream. */
-    public ELParser(java.io.InputStream stream) {
-        this(stream, null);
-    }
-
-    /** Constructor with InputStream and supplied encoding */
-    public ELParser(java.io.InputStream stream, String encoding) {
-        try {
-            jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1);
-        } catch (java.io.UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-        token_source = new ELParserTokenManager(jj_input_stream);
-        token = new Token();
-        jj_ntk = -1;
-        jj_gen = 0;
-        for (int i = 0; i < 53; i++) {
-            jj_la1[i] = -1;
-        }
-        for (int i = 0; i < jj_2_rtns.length; i++) {
-            jj_2_rtns[i] = new JJCalls();
-        }
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.InputStream stream) {
-        ReInit(stream, null);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.InputStream stream, String encoding) {
-        try {
-            jj_input_stream.ReInit(stream, encoding, 1, 1);
-        } catch (java.io.UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-        token_source.ReInit(jj_input_stream);
-        token = new Token();
-        jj_ntk = -1;
-        jjtree.reset();
-        jj_gen = 0;
-        for (int i = 0; i < 53; i++) {
-            jj_la1[i] = -1;
-        }
-        for (int i = 0; i < jj_2_rtns.length; i++) {
-            jj_2_rtns[i] = new JJCalls();
-        }
-    }
-
-    /** Constructor. */
-    public ELParser(java.io.Reader stream) {
-        jj_input_stream = new SimpleCharStream(stream, 1, 1);
-        token_source = new ELParserTokenManager(jj_input_stream);
-        token = new Token();
-        jj_ntk = -1;
-        jj_gen = 0;
-        for (int i = 0; i < 53; i++) {
-            jj_la1[i] = -1;
-        }
-        for (int i = 0; i < jj_2_rtns.length; i++) {
-            jj_2_rtns[i] = new JJCalls();
-        }
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.Reader stream) {
-        jj_input_stream.ReInit(stream, 1, 1);
-        token_source.ReInit(jj_input_stream);
-        token = new Token();
-        jj_ntk = -1;
-        jjtree.reset();
-        jj_gen = 0;
-        for (int i = 0; i < 53; i++) {
-            jj_la1[i] = -1;
-        }
-        for (int i = 0; i < jj_2_rtns.length; i++) {
-            jj_2_rtns[i] = new JJCalls();
-        }
-    }
-
-    /** Constructor with generated Token Manager. */
-    public ELParser(ELParserTokenManager tm) {
-        token_source = tm;
-        token = new Token();
-        jj_ntk = -1;
-        jj_gen = 0;
-        for (int i = 0; i < 53; i++) {
-            jj_la1[i] = -1;
-        }
-        for (int i = 0; i < jj_2_rtns.length; i++) {
-            jj_2_rtns[i] = new JJCalls();
-        }
-    }
-
-    /** Reinitialise. */
-    public void ReInit(ELParserTokenManager tm) {
-        token_source = tm;
-        token = new Token();
-        jj_ntk = -1;
-        jjtree.reset();
-        jj_gen = 0;
-        for (int i = 0; i < 53; i++) {
-            jj_la1[i] = -1;
-        }
-        for (int i = 0; i < jj_2_rtns.length; i++) {
-            jj_2_rtns[i] = new JJCalls();
-        }
-    }
-
-    private Token jj_consume_token(int kind) throws ParseException {
-        Token oldToken;
-        if ((oldToken = token).next != null) {
-            token = token.next;
-        } else {
-            token = token.next = token_source.getNextToken();
-        }
-        jj_ntk = -1;
-        if (token.kind == kind) {
-            jj_gen++;
-            if (++jj_gc > 100) {
-                jj_gc = 0;
-                for (int i = 0; i < jj_2_rtns.length; i++) {
-                    JJCalls c = jj_2_rtns[i];
-                    while (c != null) {
-                        if (c.gen < jj_gen) {
-                            c.first = null;
-                        }
-                        c = c.next;
-                    }
-                }
-            }
-            return token;
-        }
-        token = oldToken;
-        jj_kind = kind;
-        throw generateParseException();
-    }
-
-    static private final class LookaheadSuccess extends java.lang.Error {
-    }
-
-    static final private LookaheadSuccess jj_ls = new LookaheadSuccess();
-
-    private boolean jj_scan_token(int kind) {
-        if (jj_scanpos == jj_lastpos) {
-            jj_la--;
-            if (jj_scanpos.next == null) {
-                jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
-            } else {
-                jj_lastpos = jj_scanpos = jj_scanpos.next;
-            }
-        } else {
-            jj_scanpos = jj_scanpos.next;
-        }
-        if (jj_rescan) {
-            int i = 0;
-            Token tok = token;
-            while (tok != null && tok != jj_scanpos) {
-                i++;
-                tok = tok.next;
-            }
-            if (tok != null) {
-                jj_add_error_token(kind, i);
-            }
-        }
-        if (jj_scanpos.kind != kind) {
-            return true;
-        }
-        if (jj_la == 0 && jj_scanpos == jj_lastpos) {
-            throw jj_ls;
-        }
-        return false;
-    }
-
-    /** Get the next Token. */
-    final public Token getNextToken() {
-        if (token.next != null) {
-            token = token.next;
-        } else {
-            token = token.next = token_source.getNextToken();
-        }
-        jj_ntk = -1;
-        jj_gen++;
-        return token;
-    }
-
-    /** Get the specific Token. */
-    final public Token getToken(int index) {
-        Token t = token;
-        for (int i = 0; i < index; i++) {
-            if (t.next != null) {
-                t = t.next;
-            } else {
-                t = t.next = token_source.getNextToken();
-            }
-        }
-        return t;
-    }
-
-    private int jj_ntk() {
-        if ((jj_nt = token.next) == null) {
-            return (jj_ntk = (token.next = token_source.getNextToken()).kind);
-        } else {
-            return (jj_ntk = jj_nt.kind);
-        }
-    }
-
-    private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
-    private int[] jj_expentry;
-    private int jj_kind = -1;
-    private int[] jj_lasttokens = new int[100];
-    private int jj_endpos;
-
-    private void jj_add_error_token(int kind, int pos) {
-        if (pos >= 100) {
-            return;
-        }
-        if (pos == jj_endpos + 1) {
-            jj_lasttokens[jj_endpos++] = kind;
-        } else if (jj_endpos != 0) {
-            jj_expentry = new int[jj_endpos];
-            for (int i = 0; i < jj_endpos; i++) {
-                jj_expentry[i] = jj_lasttokens[i];
-            }
-            jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
-                int[] oldentry = (int[]) (it.next());
-                if (oldentry.length == jj_expentry.length) {
-                    for (int i = 0; i < jj_expentry.length; i++) {
-                        if (oldentry[i] != jj_expentry[i]) {
-                            continue jj_entries_loop;
-                        }
-                    }
-                    jj_expentries.add(jj_expentry);
-                    break jj_entries_loop;
-                }
-            }
-            if (pos != 0) {
-                jj_lasttokens[(jj_endpos = pos) - 1] = kind;
-            }
-        }
-    }
-
-    /** Generate ParseException. */
-    public ParseException generateParseException() {
-        jj_expentries.clear();
-        boolean[] la1tokens = new boolean[63];
-        if (jj_kind >= 0) {
-            la1tokens[jj_kind] = true;
-            jj_kind = -1;
-        }
-        for (int i = 0; i < 53; i++) {
-            if (jj_la1[i] == jj_gen) {
-                for (int j = 0; j < 32; j++) {
-                    if ((jj_la1_0[i] & (1 << j)) != 0) {
-                        la1tokens[j] = true;
-                    }
-                    if ((jj_la1_1[i] & (1 << j)) != 0) {
-                        la1tokens[32 + j] = true;
-                    }
-                }
-            }
-        }
-        for (int i = 0; i < 63; i++) {
-            if (la1tokens[i]) {
-                jj_expentry = new int[1];
-                jj_expentry[0] = i;
-                jj_expentries.add(jj_expentry);
-            }
-        }
-        jj_endpos = 0;
-        jj_rescan_token();
-        jj_add_error_token(0, 0);
-        int[][] exptokseq = new int[jj_expentries.size()][];
-        for (int i = 0; i < jj_expentries.size(); i++) {
-            exptokseq[i] = jj_expentries.get(i);
-        }
-        return new ParseException(token, exptokseq, tokenImage);
-    }
-
-    /** Enable tracing. */
-    final public void enable_tracing() {
-    }
-
-    /** Disable tracing. */
-    final public void disable_tracing() {
-    }
-
-    private void jj_rescan_token() {
-        jj_rescan = true;
-        for (int i = 0; i < 5; i++) {
-            try {
-                JJCalls p = jj_2_rtns[i];
-                do {
-                    if (p.gen > jj_gen) {
-                        jj_la = p.arg;
-                        jj_lastpos = jj_scanpos = p.first;
-                        switch (i) {
-                        case 0:
-                            jj_3_1();
-                            break;
-                        case 1:
-                            jj_3_2();
-                            break;
-                        case 2:
-                            jj_3_3();
-                            break;
-                        case 3:
-                            jj_3_4();
-                            break;
-                        case 4:
-                            jj_3_5();
-                            break;
-                        }
-                    }
-                    p = p.next;
-                } while (p != null);
-            } catch (LookaheadSuccess ls) {
-            }
-        }
-        jj_rescan = false;
-    }
-
-    private void jj_save(int index, int xla) {
-        JJCalls p = jj_2_rtns[index];
-        while (p.gen > jj_gen) {
-            if (p.next == null) {
-                p = p.next = new JJCalls();
-                break;
-            }
-            p = p.next;
-        }
-        p.gen = jj_gen + xla - jj_la;
-        p.first = token;
-        p.arg = xla;
-    }
-
-    static final class JJCalls {
-        int gen;
-        Token first;
-        int arg;
-        JJCalls next;
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/parser/ELParser.jjt b/impl/src/main/java/com/sun/el/parser/ELParser.jjt
deleted file mode 100644
index 703f6ef..0000000
--- a/impl/src/main/java/com/sun/el/parser/ELParser.jjt
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (c) 1997, 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
- */
-
-/*
-	Author:	Jacob Hookom
-	Email:	jacob at hookom.net
-
-        Author: Kin-man Chung (EL 2.2 and EL 3.0)
-*/
-
-/* == Option Declaration == */
-options
-{
-	STATIC=false;
-	NODE_PREFIX="Ast";
-	VISITOR_EXCEPTION="javax.el.ELException";
-	VISITOR=false;
-	MULTI=true;
-	NODE_DEFAULT_VOID=true;
-	JAVA_UNICODE_ESCAPE=false;
-  	UNICODE_INPUT=true;
-	BUILD_NODE_FILES=true;
-}
-
-/* == Parser Declaration == */
-PARSER_BEGIN( ELParser )
-package com.sun.el.parser;
-import java.io.StringReader;
-import javax.el.ELException;
-public class ELParser
-{
-    public static Node parse(String ref) throws ELException
-    {
-        try {
-        	return (new ELParser(new StringReader(ref))).CompositeExpression();
-        } catch (ParseException pe) {
-           	throw new ELException(pe.getMessage());
-        }
-    }
-}
-PARSER_END( ELParser )
-
-/*
- * CompositeExpression
- * Allow most flexible parsing, restrict by examining
- * type of returned node
- */
-AstCompositeExpression CompositeExpression() #CompositeExpression : {}
-{
-	(DeferredExpression() | DynamicExpression() | LiteralExpression())* <EOF> { return jjtThis; }
-}
-
-/*
- * LiteralExpression
- * Non-EL Expression blocks
- */
-void LiteralExpression() #LiteralExpression : { Token t = null; }
-{
-	t=<LITERAL_EXPRESSION> { jjtThis.setImage(t.image); }
-}
-
-/*
- * DeferredExpression
- * #{..} Expressions
- */
-void DeferredExpression() #DeferredExpression : {}
-{
-	<START_DEFERRED_EXPRESSION> Expression() <RCURL> 
-}
-
-/*
- * DynamicExpression
- * ${..} Expressions
- */
-void DynamicExpression() #DynamicExpression : {}
-{
-	<START_DYNAMIC_EXPRESSION> Expression() <RCURL> 
-}
-
-/*
- * Expression
- * EL Expression Language Root
- */
-void Expression() : {}
-{
-        SemiColon()
-}
-
-/*
- * SemiColon
- */
-void SemiColon() : {}
-{
-        Assignment() (<SEMICOLON> Assignment() #SemiColon(2) )*
-}
-
-/*
- * Assignment
- * For '=', right associatve, then LambdaExpression or Choice or Assignment
- */
-void Assignment() : {}
-{
-        LOOKAHEAD(3) LambdaExpression() |
-        Choice() (<ASSIGN> Assignment() #Assign(2) )?
-}
-
-/*
- * LambdaExpression
- */
-void LambdaExpression() #LambdaExpression : {}
-{
-       LambdaParameters() <ARROW>
-       (LOOKAHEAD(3) LambdaExpression() | Choice() )
-}
-
-void LambdaParameters() #LambdaParameters: {}
-{
-       Identifier()
-       | <LPAREN>
-            (Identifier() (<COMMA> Identifier())*)?
-         <RPAREN>
-}
-
-/*
- * Choice
- * For Choice markup a ? b : c, right associative
- */
-void Choice() : {}
-{
-	Or() (<QUESTIONMARK> Choice() <COLON> Choice() #Choice(3))?
-}
-
-/*
- * Or
- * For 'or' '||', then And
- */
-void Or() : {}
-{
-	And() ((<OR0>|<OR1>) And() #Or(2))*
-}
-
-/*
- * And
- * For 'and' '&&', then Equality
- */
-void And() : {}
-{
-	Equality() ((<AND0>|<AND1>) Equality() #And(2))*
-}
-
-/*
- * Equality
- * For '==' 'eq' '!=' 'ne', then Compare
- */
-void Equality() : {}
-{
-	Compare()
-	(
-		((<EQ0>|<EQ1>) Compare() #Equal(2))
-	|
-		((<NE0>|<NE1>) Compare() #NotEqual(2))
-	)*
-}
-
-/*
- * Compare
- * For a bunch of them, then Math
- */
-void Compare() : {}
-{
-	Concatenation()
-	(
-		((<LT0>|<LT1>) Concatenation() #LessThan(2))
-	|
-		((<GT0>|<GT1>) Concatenation() #GreaterThan(2))
-	|
-		((<LE0>|<LE1>) Concatenation() #LessThanEqual(2))
-	|
-		((<GE0>|<GE1>) Concatenation() #GreaterThanEqual(2))
-	)*
-}
-
-/*
- * Concatenation
- * For '&', then Math()
- */
-void Concatenation() : {}
-{
-        Math() ( <CONCAT> Math() #Concat(2) )*
-}
-
-/*
- * Math
- * For '+' '-', then Multiplication
- */
-void Math() : {}
-{
-	Multiplication()
-	(
-		(<PLUS> Multiplication() #Plus(2))
-	|
-		(<MINUS> Multiplication() #Minus(2))
-	)*
-}
-
-/*
- * Multiplication
- * For a bunch of them, then Unary
- */
-void Multiplication() : {}
-{
-	Unary()
-	(
-		(<MULT> Unary() #Mult(2))
-	|
-		((<DIV0>|<DIV1>) Unary() #Div(2))
-	|
-		((<MOD0>|<MOD1>) Unary() #Mod(2))	
-	)*	
-}
-
-/*
- * Unary
- * For '-' '!' 'not' 'empty', then Value
- */
-void Unary() : {}
-{
-		<MINUS> Unary() #Negative 
-	|
-		(<NOT0>|<NOT1>) Unary() #Not 
-	|
-		<EMPTY> Unary() #Empty
-	|	
-		Value()
-}
-
-/*
- * Value
- * Defines Prefix plus zero or more Suffixes
- */
-void Value() : {}
-{
-	(ValuePrefix() (ValueSuffix())*) #Value(>1)
-}
-
-/*
- * ValuePrefix
- * For Literals, Variables, and Functions
- */
-void ValuePrefix() : {}
-{
-	Literal()
-	| NonLiteral()
-}
-
-/*
- * ValueSuffix
- * Either dot or bracket notation
- */
-void ValueSuffix() : {}
-{
-	DotSuffix() | BracketSuffix()
-}
-
-/*
- * DotSuffix
- * Dot Property and Dot Method
- */
-void DotSuffix() #DotSuffix : {  Token t = null; }
-{
-        <DOT> t=<IDENTIFIER> { jjtThis.setImage(t.image); }
-        (MethodArguments())?
-}
-
-/*
- * BracketSuffix
- * Sub Expression Suffix
- */
-void BracketSuffix() #BracketSuffix : {}
-{
-	<LBRACK> Expression() <RBRACK>
-        (MethodArguments())?
-}
-
-
-/*
- * MethodArguments
- */
-void MethodArguments() #MethodArguments : {}
-{
-        <LPAREN> (Expression() (<COMMA> Expression())*)? <RPAREN>
-}
-
-/*
- * Parenthesized Lambda Expression, with optional invokation
- */
-void LambdaExpressionOrCall() #LambdaExpression : {}
-
-{
-    <LPAREN>
-        LambdaParameters() <ARROW>
-        (LOOKAHEAD(3) LambdaExpression() | Choice() )
-    <RPAREN>
-    (MethodArguments())*
-}
-
-/*
- * NonLiteral
- * For Grouped Operations, Identifiers, and Functions
- */
-void NonLiteral() : {}
-{
-        LOOKAHEAD(4) LambdaExpressionOrCall()
- 	| <LPAREN> Expression() <RPAREN>
- 	| LOOKAHEAD(4) Function()
-	| Identifier()
-        | MapData()
-        | ListData()
-}
-
-void MapData() #MapData: {}
-{
-    <START_MAP>
-        ( MapEntry() ( <COMMA> MapEntry() )* )?
-    <RCURL>
-}
-
-void MapEntry() #MapEntry: {}
-{
-    Expression() (<COLON> Expression())?
-}
-
-void ListData() #ListData: {}
-{
-    <LBRACK>
-        ( Expression() ( <COMMA> Expression() )* )?
-    <RBRACK>
-}
-
-/*
- * Identifier
- * Java Language Identifier
- */
-void Identifier() #Identifier : { Token t = null; }
-{
-	t=<IDENTIFIER> { jjtThis.setImage(t.image); }
-}
-
-/*
- * Function
- * Namespace:Name(a,b,c)
- */
-void Function() #Function :
-{
-	Token t0 = null;
-	Token t1 = null;
-}
-{
-	t0=<IDENTIFIER> (<COLON> t1=<IDENTIFIER>)?
-	{
-		if (t1 != null) {
-			jjtThis.setPrefix(t0.image);
-			jjtThis.setLocalName(t1.image);
-		} else {
-			jjtThis.setLocalName(t0.image);
-		}
-	}
-        (MethodArguments())+
-}
-
-
-/*
- * Literal
- * Reserved Keywords
- */
-void Literal() : {}
-{
-	Boolean()
-	| FloatingPoint()
-	| Integer()
-	| String()
-	| Null()
-}
-
-/*
- * Boolean
- * For 'true' 'false'
- */
-void Boolean() : {}
-{
-	<TRUE> #True
-	| <FALSE> #False
-}
-
-/*
- * FloatinPoint
- * For Decimal and Floating Point Literals
- */
-void FloatingPoint() #FloatingPoint : { Token t = null; }
-{
-	t=<FLOATING_POINT_LITERAL> { jjtThis.setImage(t.image); }
-}
-
-/*
- * Integer
- * For Simple Numeric Literals
- */
-void Integer() #Integer : { Token t = null; }
-{
-	t=<INTEGER_LITERAL> { jjtThis.setImage(t.image); }
-}
-
-/*
- * String
- * For Quoted Literals
- */
-void String() #String : { Token t = null; }
-{
-	t=<STRING_LITERAL> { jjtThis.setImage(t.image); }
-}
-
-/*
- * Null
- * For 'null'
- */
-void Null() #Null : {}
-{
-	<NULL>
-}
-
-
-/* ========================================================================== */
-TOKEN_MGR_DECLS:
-{
-    java.util.Stack<Integer> stack = new java.util.Stack<Integer>();
-}
-
-<DEFAULT> TOKEN :
-{
-  < LITERAL_EXPRESSION:
-    ((~["\\", "$", "#"])
-      | ("\\" ("\\" | "$" | "#"))
-      | ("$" ~["{", "$", "#"])
-      | ("#" ~["{", "$", "#"])
-    )+
-    | "$"
-    | "#"
-  >
-|
-  < START_DYNAMIC_EXPRESSION: "${" > {stack.push(DEFAULT);}: IN_EXPRESSION
-|
-  < START_DEFERRED_EXPRESSION: "#{" > {stack.push(DEFAULT);}: IN_EXPRESSION
-}
-
-<DEFAULT> SKIP : { "\\" }
-
-<IN_EXPRESSION, IN_MAP> SKIP:
-{ " " | "\t" | "\n" | "\r" }
-
-<IN_EXPRESSION, IN_MAP> TOKEN :
-{
-        < START_MAP : "{" > {stack.push(curLexState);}: IN_MAP
-|       < RCURL: "}" > {SwitchTo(stack.pop());}
-|       < INTEGER_LITERAL: ["0"-"9"] (["0"-"9"])* >
-|	< FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? 
-		| "." (["0"-"9"])+ (<EXPONENT>)?
-		| (["0"-"9"])+ <EXPONENT>
-	>
-|	< #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
-|	< STRING_LITERAL: ("\"" ((~["\"","\\"])
-		| ("\\" ( ["\\","\""] )))* "\"")
-		| ("\'" ((~["\'","\\"])
-		| ("\\" ( ["\\","\'"] )))* "\'")
-	>
-|	< BADLY_ESCAPED_STRING_LITERAL: ("\"" (~["\"","\\"])* ("\\" ( ~["\\","\""] )))
-		| ("\'" (~["\'","\\"])* ("\\" ( ~["\\","\'"] )))
-	>
-|	< TRUE : "true" >
-|	< FALSE : "false" >
-|	< NULL : "null" >
-|	< DOT : "." >
-|	< LPAREN : "(" >
-|	< RPAREN : ")" >
-|	< LBRACK : "[" >
-|	< RBRACK : "]" >
-|	< COLON : ":" >
-|	< COMMA : "," >
-|       < SEMICOLON : ";" >
-|	< GT0 : ">" >
-|	< GT1 : "gt" >
-|	< LT0 : "<" >
-|	< LT1 : "lt" >
-|	< GE0 : ">=" >
-|	< GE1 : "ge" >
-|	< LE0 : "<=" >
-|	< LE1 : "le" >
-|	< EQ0 : "==" >
-|	< EQ1 : "eq" >
-|	< NE0 : "!=" >
-|	< NE1 : "ne" >
-|	< NOT0 : "!" >
-|	< NOT1 : "not" >
-|	< AND0 : "&&" >
-|	< AND1 : "and" >
-|	< OR0 : "||" >
-|	< OR1 : "or" >
-|	< EMPTY : "empty" >
-|	< INSTANCEOF : "instanceof" >
-|	< MULT : "*" >
-|	< PLUS : "+" >
-|	< MINUS : "-" >
-|	< QUESTIONMARK : "?" >
-|	< DIV0 : "/" >
-|	< DIV1 : "div" >
-|	< MOD0 : "%" >
-|	< MOD1 : "mod" >
-|       < CONCAT : "+=" >
-|       < ASSIGN : "=" >
-|       < ARROW : "->" >
-|	< IDENTIFIER : (<LETTER>|<IMPL_OBJ_START>) (<LETTER>|<DIGIT>)* >
-|	< #IMPL_OBJ_START: "#" >
-|	< #LETTER:
-		[
-		"\u0024",
-		"\u0041"-"\u005a",
-		"\u005f",
-		"\u0061"-"\u007a",
-		"\u00c0"-"\u00d6",
-		"\u00d8"-"\u00f6",
-		"\u00f8"-"\u00ff",
-		"\u0100"-"\u1fff",
-		"\u3040"-"\u318f",
-		"\u3300"-"\u337f",
-		"\u3400"-"\u3d2d",
-		"\u4e00"-"\u9fff",
-		"\uf900"-"\ufaff"
-		]
-	>
-|	< #DIGIT:
-		[
-		"\u0030"-"\u0039",
-		"\u0660"-"\u0669",
-		"\u06f0"-"\u06f9",
-		"\u0966"-"\u096f",
-		"\u09e6"-"\u09ef",
-		"\u0a66"-"\u0a6f",
-		"\u0ae6"-"\u0aef",
-		"\u0b66"-"\u0b6f",
-		"\u0be7"-"\u0bef",
-		"\u0c66"-"\u0c6f",
-		"\u0ce6"-"\u0cef",
-		"\u0d66"-"\u0d6f",
-		"\u0e50"-"\u0e59",
-		"\u0ed0"-"\u0ed9",
-		"\u1040"-"\u1049"
-		]
-	>
-|	< ILLEGAL_CHARACTER: (~[]) >
-}
-
diff --git a/impl/src/main/java/com/sun/el/parser/ELParserConstants.java b/impl/src/main/java/com/sun/el/parser/ELParserConstants.java
deleted file mode 100644
index 41445ce..0000000
--- a/impl/src/main/java/com/sun/el/parser/ELParserConstants.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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
- */
-
-/* Generated By:JJTree&JavaCC: Do not edit this line. ELParserConstants.java */
-package com.sun.el.parser;
-
-/**
- * Token literal values and constants. Generated by org.javacc.parser.OtherFilesGen#start()
- */
-public interface ELParserConstants {
-
-    /** End of File. */
-    int EOF = 0;
-    /** RegularExpression Id. */
-    int LITERAL_EXPRESSION = 1;
-    /** RegularExpression Id. */
-    int START_DYNAMIC_EXPRESSION = 2;
-    /** RegularExpression Id. */
-    int START_DEFERRED_EXPRESSION = 3;
-    /** RegularExpression Id. */
-    int START_MAP = 9;
-    /** RegularExpression Id. */
-    int RCURL = 10;
-    /** RegularExpression Id. */
-    int INTEGER_LITERAL = 11;
-    /** RegularExpression Id. */
-    int FLOATING_POINT_LITERAL = 12;
-    /** RegularExpression Id. */
-    int EXPONENT = 13;
-    /** RegularExpression Id. */
-    int STRING_LITERAL = 14;
-    /** RegularExpression Id. */
-    int BADLY_ESCAPED_STRING_LITERAL = 15;
-    /** RegularExpression Id. */
-    int TRUE = 16;
-    /** RegularExpression Id. */
-    int FALSE = 17;
-    /** RegularExpression Id. */
-    int NULL = 18;
-    /** RegularExpression Id. */
-    int DOT = 19;
-    /** RegularExpression Id. */
-    int LPAREN = 20;
-    /** RegularExpression Id. */
-    int RPAREN = 21;
-    /** RegularExpression Id. */
-    int LBRACK = 22;
-    /** RegularExpression Id. */
-    int RBRACK = 23;
-    /** RegularExpression Id. */
-    int COLON = 24;
-    /** RegularExpression Id. */
-    int COMMA = 25;
-    /** RegularExpression Id. */
-    int SEMICOLON = 26;
-    /** RegularExpression Id. */
-    int GT0 = 27;
-    /** RegularExpression Id. */
-    int GT1 = 28;
-    /** RegularExpression Id. */
-    int LT0 = 29;
-    /** RegularExpression Id. */
-    int LT1 = 30;
-    /** RegularExpression Id. */
-    int GE0 = 31;
-    /** RegularExpression Id. */
-    int GE1 = 32;
-    /** RegularExpression Id. */
-    int LE0 = 33;
-    /** RegularExpression Id. */
-    int LE1 = 34;
-    /** RegularExpression Id. */
-    int EQ0 = 35;
-    /** RegularExpression Id. */
-    int EQ1 = 36;
-    /** RegularExpression Id. */
-    int NE0 = 37;
-    /** RegularExpression Id. */
-    int NE1 = 38;
-    /** RegularExpression Id. */
-    int NOT0 = 39;
-    /** RegularExpression Id. */
-    int NOT1 = 40;
-    /** RegularExpression Id. */
-    int AND0 = 41;
-    /** RegularExpression Id. */
-    int AND1 = 42;
-    /** RegularExpression Id. */
-    int OR0 = 43;
-    /** RegularExpression Id. */
-    int OR1 = 44;
-    /** RegularExpression Id. */
-    int EMPTY = 45;
-    /** RegularExpression Id. */
-    int INSTANCEOF = 46;
-    /** RegularExpression Id. */
-    int MULT = 47;
-    /** RegularExpression Id. */
-    int PLUS = 48;
-    /** RegularExpression Id. */
-    int MINUS = 49;
-    /** RegularExpression Id. */
-    int QUESTIONMARK = 50;
-    /** RegularExpression Id. */
-    int DIV0 = 51;
-    /** RegularExpression Id. */
-    int DIV1 = 52;
-    /** RegularExpression Id. */
-    int MOD0 = 53;
-    /** RegularExpression Id. */
-    int MOD1 = 54;
-    /** RegularExpression Id. */
-    int CONCAT = 55;
-    /** RegularExpression Id. */
-    int ASSIGN = 56;
-    /** RegularExpression Id. */
-    int ARROW = 57;
-    /** RegularExpression Id. */
-    int IDENTIFIER = 58;
-    /** RegularExpression Id. */
-    int IMPL_OBJ_START = 59;
-    /** RegularExpression Id. */
-    int LETTER = 60;
-    /** RegularExpression Id. */
-    int DIGIT = 61;
-    /** RegularExpression Id. */
-    int ILLEGAL_CHARACTER = 62;
-
-    /** Lexical state. */
-    int DEFAULT = 0;
-    /** Lexical state. */
-    int IN_EXPRESSION = 1;
-    /** Lexical state. */
-    int IN_MAP = 2;
-
-    /** Literal token values. */
-    String[] tokenImage = { "<EOF>", "<LITERAL_EXPRESSION>", "\"${\"", "\"#{\"", "\"\\\\\"", "\" \"", "\"\\t\"", "\"\\n\"", "\"\\r\"", "\"{\"", "\"}\"",
-            "<INTEGER_LITERAL>", "<FLOATING_POINT_LITERAL>", "<EXPONENT>", "<STRING_LITERAL>", "<BADLY_ESCAPED_STRING_LITERAL>", "\"true\"", "\"false\"",
-            "\"null\"", "\".\"", "\"(\"", "\")\"", "\"[\"", "\"]\"", "\":\"", "\",\"", "\";\"", "\">\"", "\"gt\"", "\"<\"", "\"lt\"", "\">=\"", "\"ge\"",
-            "\"<=\"", "\"le\"", "\"==\"", "\"eq\"", "\"!=\"", "\"ne\"", "\"!\"", "\"not\"", "\"&&\"", "\"and\"", "\"||\"", "\"or\"", "\"empty\"",
-            "\"instanceof\"", "\"*\"", "\"+\"", "\"-\"", "\"?\"", "\"/\"", "\"div\"", "\"%\"", "\"mod\"", "\"+=\"", "\"=\"", "\"->\"", "<IDENTIFIER>", "\"#\"",
-            "<LETTER>", "<DIGIT>", "<ILLEGAL_CHARACTER>", };
-
-}
diff --git a/impl/src/main/java/com/sun/el/parser/ELParserTokenManager.java b/impl/src/main/java/com/sun/el/parser/ELParserTokenManager.java
deleted file mode 100644
index 0c59560..0000000
--- a/impl/src/main/java/com/sun/el/parser/ELParserTokenManager.java
+++ /dev/null
@@ -1,2204 +0,0 @@
-/*
- * 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
- */
-
-/* Generated By:JJTree&JavaCC: Do not edit this line. ELParserTokenManager.java */
-package com.sun.el.parser;
-
-/** Token Manager. */
-public class ELParserTokenManager implements ELParserConstants {
-    java.util.Stack<Integer> stack = new java.util.Stack<Integer>();
-
-    /** Debug output. */
-    public java.io.PrintStream debugStream = System.out;
-
-    /** Set debug output. */
-    public void setDebugStream(java.io.PrintStream ds) {
-        debugStream = ds;
-    }
-
-    private final int jjStopStringLiteralDfa_0(int pos, long active0) {
-        switch (pos) {
-        case 0:
-            if ((active0 & 0x10L) != 0L) {
-                return 2;
-            }
-            if ((active0 & 0xcL) != 0L) {
-                jjmatchedKind = 1;
-                return 4;
-            }
-            return -1;
-        default:
-            return -1;
-        }
-    }
-
-    private final int jjStartNfa_0(int pos, long active0) {
-        return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
-    }
-
-    private int jjStopAtPos(int pos, int kind) {
-        jjmatchedKind = kind;
-        jjmatchedPos = pos;
-        return pos + 1;
-    }
-
-    private int jjMoveStringLiteralDfa0_0() {
-        switch (curChar) {
-        case 35:
-            return jjMoveStringLiteralDfa1_0(0x8L);
-        case 36:
-            return jjMoveStringLiteralDfa1_0(0x4L);
-        case 92:
-            return jjStartNfaWithStates_0(0, 4, 2);
-        default:
-            return jjMoveNfa_0(6, 0);
-        }
-    }
-
-    private int jjMoveStringLiteralDfa1_0(long active0) {
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_0(0, active0);
-            return 1;
-        }
-        switch (curChar) {
-        case 123:
-            if ((active0 & 0x4L) != 0L) {
-                return jjStopAtPos(1, 2);
-            } else if ((active0 & 0x8L) != 0L) {
-                return jjStopAtPos(1, 3);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_0(0, active0);
-    }
-
-    private int jjStartNfaWithStates_0(int pos, int kind, int state) {
-        jjmatchedKind = kind;
-        jjmatchedPos = pos;
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            return pos + 1;
-        }
-        return jjMoveNfa_0(state, pos + 1);
-    }
-
-    static final long[] jjbitVec0 = { 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL };
-    static final long[] jjbitVec2 = { 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL };
-
-    private int jjMoveNfa_0(int startState, int curPos) {
-        int startsAt = 0;
-        jjnewStateCnt = 7;
-        int i = 1;
-        jjstateSet[0] = startState;
-        int kind = 0x7fffffff;
-        for (;;) {
-            if (++jjround == 0x7fffffff) {
-                ReInitRounds();
-            }
-            if (curChar < 64) {
-                long l = 1L << curChar;
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 6:
-                        if ((0xffffffe7ffffffffL & l) != 0L) {
-                            if (kind > 1) {
-                                kind = 1;
-                            }
-                            jjCheckNAddStates(0, 3);
-                        } else if ((0x1800000000L & l) != 0L) {
-                            if (kind > 1) {
-                                kind = 1;
-                            }
-                        }
-                        if (curChar == 35) {
-                            jjCheckNAdd(4);
-                        } else if (curChar == 36) {
-                            jjCheckNAdd(4);
-                        }
-                        break;
-                    case 0:
-                    case 4:
-                        if ((0xffffffe7ffffffffL & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 1) {
-                            kind = 1;
-                        }
-                        jjCheckNAddStates(0, 3);
-                        break;
-                    case 2:
-                        if ((0x1800000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 1) {
-                            kind = 1;
-                        }
-                        jjCheckNAddStates(0, 3);
-                        break;
-                    case 3:
-                        if (curChar == 36) {
-                            jjCheckNAdd(4);
-                        }
-                        break;
-                    case 5:
-                        if (curChar == 35) {
-                            jjCheckNAdd(4);
-                        }
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            } else if (curChar < 128) {
-                long l = 1L << (curChar & 077);
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 6:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            if (kind > 1) {
-                                kind = 1;
-                            }
-                            jjCheckNAddStates(0, 3);
-                        } else if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 2;
-                        }
-                        break;
-                    case 0:
-                        if ((0xffffffffefffffffL & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 1) {
-                            kind = 1;
-                        }
-                        jjCheckNAddStates(0, 3);
-                        break;
-                    case 1:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 2;
-                        }
-                        break;
-                    case 2:
-                        if (curChar != 92) {
-                            break;
-                        }
-                        if (kind > 1) {
-                            kind = 1;
-                        }
-                        jjCheckNAddStates(0, 3);
-                        break;
-                    case 4:
-                        if ((0xf7ffffffffffffffL & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 1) {
-                            kind = 1;
-                        }
-                        jjCheckNAddStates(0, 3);
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            } else {
-                int hiByte = curChar >> 8;
-                int i1 = hiByte >> 6;
-                long l1 = 1L << (hiByte & 077);
-                int i2 = (curChar & 0xff) >> 6;
-                long l2 = 1L << (curChar & 077);
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 6:
-                    case 0:
-                    case 4:
-                        if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            break;
-                        }
-                        if (kind > 1) {
-                            kind = 1;
-                        }
-                        jjCheckNAddStates(0, 3);
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            }
-            if (kind != 0x7fffffff) {
-                jjmatchedKind = kind;
-                jjmatchedPos = curPos;
-                kind = 0x7fffffff;
-            }
-            ++curPos;
-            if ((i = jjnewStateCnt) == (startsAt = 7 - (jjnewStateCnt = startsAt))) {
-                return curPos;
-            }
-            try {
-                curChar = input_stream.readChar();
-            } catch (java.io.IOException e) {
-                return curPos;
-            }
-        }
-    }
-
-    private final int jjStopStringLiteralDfa_2(int pos, long active0) {
-        switch (pos) {
-        case 0:
-            if ((active0 & 0x80000L) != 0L) {
-                return 1;
-            }
-            if ((active0 & 0x50755550070000L) != 0L) {
-                jjmatchedKind = 58;
-                return 6;
-            }
-            return -1;
-        case 1:
-            if ((active0 & 0x105550000000L) != 0L) {
-                return 6;
-            }
-            if ((active0 & 0x50650000070000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 1;
-                return 6;
-            }
-            return -1;
-        case 2:
-            if ((active0 & 0x50050000000000L) != 0L) {
-                return 6;
-            }
-            if ((active0 & 0x600000070000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 2;
-                return 6;
-            }
-            return -1;
-        case 3:
-            if ((active0 & 0x50000L) != 0L) {
-                return 6;
-            }
-            if ((active0 & 0x600000020000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 3;
-                return 6;
-            }
-            return -1;
-        case 4:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 4;
-                return 6;
-            }
-            if ((active0 & 0x200000020000L) != 0L) {
-                return 6;
-            }
-            return -1;
-        case 5:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 5;
-                return 6;
-            }
-            return -1;
-        case 6:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 6;
-                return 6;
-            }
-            return -1;
-        case 7:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 7;
-                return 6;
-            }
-            return -1;
-        case 8:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 8;
-                return 6;
-            }
-            return -1;
-        default:
-            return -1;
-        }
-    }
-
-    private final int jjStartNfa_2(int pos, long active0) {
-        return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
-    }
-
-    private int jjMoveStringLiteralDfa0_2() {
-        switch (curChar) {
-        case 33:
-            jjmatchedKind = 39;
-            return jjMoveStringLiteralDfa1_2(0x2000000000L);
-        case 37:
-            return jjStopAtPos(0, 53);
-        case 38:
-            return jjMoveStringLiteralDfa1_2(0x20000000000L);
-        case 40:
-            return jjStopAtPos(0, 20);
-        case 41:
-            return jjStopAtPos(0, 21);
-        case 42:
-            return jjStopAtPos(0, 47);
-        case 43:
-            jjmatchedKind = 48;
-            return jjMoveStringLiteralDfa1_2(0x80000000000000L);
-        case 44:
-            return jjStopAtPos(0, 25);
-        case 45:
-            jjmatchedKind = 49;
-            return jjMoveStringLiteralDfa1_2(0x200000000000000L);
-        case 46:
-            return jjStartNfaWithStates_2(0, 19, 1);
-        case 47:
-            return jjStopAtPos(0, 51);
-        case 58:
-            return jjStopAtPos(0, 24);
-        case 59:
-            return jjStopAtPos(0, 26);
-        case 60:
-            jjmatchedKind = 29;
-            return jjMoveStringLiteralDfa1_2(0x200000000L);
-        case 61:
-            jjmatchedKind = 56;
-            return jjMoveStringLiteralDfa1_2(0x800000000L);
-        case 62:
-            jjmatchedKind = 27;
-            return jjMoveStringLiteralDfa1_2(0x80000000L);
-        case 63:
-            return jjStopAtPos(0, 50);
-        case 91:
-            return jjStopAtPos(0, 22);
-        case 93:
-            return jjStopAtPos(0, 23);
-        case 97:
-            return jjMoveStringLiteralDfa1_2(0x40000000000L);
-        case 100:
-            return jjMoveStringLiteralDfa1_2(0x10000000000000L);
-        case 101:
-            return jjMoveStringLiteralDfa1_2(0x201000000000L);
-        case 102:
-            return jjMoveStringLiteralDfa1_2(0x20000L);
-        case 103:
-            return jjMoveStringLiteralDfa1_2(0x110000000L);
-        case 105:
-            return jjMoveStringLiteralDfa1_2(0x400000000000L);
-        case 108:
-            return jjMoveStringLiteralDfa1_2(0x440000000L);
-        case 109:
-            return jjMoveStringLiteralDfa1_2(0x40000000000000L);
-        case 110:
-            return jjMoveStringLiteralDfa1_2(0x14000040000L);
-        case 111:
-            return jjMoveStringLiteralDfa1_2(0x100000000000L);
-        case 116:
-            return jjMoveStringLiteralDfa1_2(0x10000L);
-        case 123:
-            return jjStopAtPos(0, 9);
-        case 124:
-            return jjMoveStringLiteralDfa1_2(0x80000000000L);
-        case 125:
-            return jjStopAtPos(0, 10);
-        default:
-            return jjMoveNfa_2(0, 0);
-        }
-    }
-
-    private int jjMoveStringLiteralDfa1_2(long active0) {
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(0, active0);
-            return 1;
-        }
-        switch (curChar) {
-        case 38:
-            if ((active0 & 0x20000000000L) != 0L) {
-                return jjStopAtPos(1, 41);
-            }
-            break;
-        case 61:
-            if ((active0 & 0x80000000L) != 0L) {
-                return jjStopAtPos(1, 31);
-            } else if ((active0 & 0x200000000L) != 0L) {
-                return jjStopAtPos(1, 33);
-            } else if ((active0 & 0x800000000L) != 0L) {
-                return jjStopAtPos(1, 35);
-            } else if ((active0 & 0x2000000000L) != 0L) {
-                return jjStopAtPos(1, 37);
-            } else if ((active0 & 0x80000000000000L) != 0L) {
-                return jjStopAtPos(1, 55);
-            }
-            break;
-        case 62:
-            if ((active0 & 0x200000000000000L) != 0L) {
-                return jjStopAtPos(1, 57);
-            }
-            break;
-        case 97:
-            return jjMoveStringLiteralDfa2_2(active0, 0x20000L);
-        case 101:
-            if ((active0 & 0x100000000L) != 0L) {
-                return jjStartNfaWithStates_2(1, 32, 6);
-            } else if ((active0 & 0x400000000L) != 0L) {
-                return jjStartNfaWithStates_2(1, 34, 6);
-            } else if ((active0 & 0x4000000000L) != 0L) {
-                return jjStartNfaWithStates_2(1, 38, 6);
-            }
-            break;
-        case 105:
-            return jjMoveStringLiteralDfa2_2(active0, 0x10000000000000L);
-        case 109:
-            return jjMoveStringLiteralDfa2_2(active0, 0x200000000000L);
-        case 110:
-            return jjMoveStringLiteralDfa2_2(active0, 0x440000000000L);
-        case 111:
-            return jjMoveStringLiteralDfa2_2(active0, 0x40010000000000L);
-        case 113:
-            if ((active0 & 0x1000000000L) != 0L) {
-                return jjStartNfaWithStates_2(1, 36, 6);
-            }
-            break;
-        case 114:
-            if ((active0 & 0x100000000000L) != 0L) {
-                return jjStartNfaWithStates_2(1, 44, 6);
-            }
-            return jjMoveStringLiteralDfa2_2(active0, 0x10000L);
-        case 116:
-            if ((active0 & 0x10000000L) != 0L) {
-                return jjStartNfaWithStates_2(1, 28, 6);
-            } else if ((active0 & 0x40000000L) != 0L) {
-                return jjStartNfaWithStates_2(1, 30, 6);
-            }
-            break;
-        case 117:
-            return jjMoveStringLiteralDfa2_2(active0, 0x40000L);
-        case 124:
-            if ((active0 & 0x80000000000L) != 0L) {
-                return jjStopAtPos(1, 43);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_2(0, active0);
-    }
-
-    private int jjMoveStringLiteralDfa2_2(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_2(0, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(1, active0);
-            return 2;
-        }
-        switch (curChar) {
-        case 100:
-            if ((active0 & 0x40000000000L) != 0L) {
-                return jjStartNfaWithStates_2(2, 42, 6);
-            } else if ((active0 & 0x40000000000000L) != 0L) {
-                return jjStartNfaWithStates_2(2, 54, 6);
-            }
-            break;
-        case 108:
-            return jjMoveStringLiteralDfa3_2(active0, 0x60000L);
-        case 112:
-            return jjMoveStringLiteralDfa3_2(active0, 0x200000000000L);
-        case 115:
-            return jjMoveStringLiteralDfa3_2(active0, 0x400000000000L);
-        case 116:
-            if ((active0 & 0x10000000000L) != 0L) {
-                return jjStartNfaWithStates_2(2, 40, 6);
-            }
-            break;
-        case 117:
-            return jjMoveStringLiteralDfa3_2(active0, 0x10000L);
-        case 118:
-            if ((active0 & 0x10000000000000L) != 0L) {
-                return jjStartNfaWithStates_2(2, 52, 6);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_2(1, active0);
-    }
-
-    private int jjMoveStringLiteralDfa3_2(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_2(1, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(2, active0);
-            return 3;
-        }
-        switch (curChar) {
-        case 101:
-            if ((active0 & 0x10000L) != 0L) {
-                return jjStartNfaWithStates_2(3, 16, 6);
-            }
-            break;
-        case 108:
-            if ((active0 & 0x40000L) != 0L) {
-                return jjStartNfaWithStates_2(3, 18, 6);
-            }
-            break;
-        case 115:
-            return jjMoveStringLiteralDfa4_2(active0, 0x20000L);
-        case 116:
-            return jjMoveStringLiteralDfa4_2(active0, 0x600000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_2(2, active0);
-    }
-
-    private int jjMoveStringLiteralDfa4_2(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_2(2, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(3, active0);
-            return 4;
-        }
-        switch (curChar) {
-        case 97:
-            return jjMoveStringLiteralDfa5_2(active0, 0x400000000000L);
-        case 101:
-            if ((active0 & 0x20000L) != 0L) {
-                return jjStartNfaWithStates_2(4, 17, 6);
-            }
-            break;
-        case 121:
-            if ((active0 & 0x200000000000L) != 0L) {
-                return jjStartNfaWithStates_2(4, 45, 6);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_2(3, active0);
-    }
-
-    private int jjMoveStringLiteralDfa5_2(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_2(3, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(4, active0);
-            return 5;
-        }
-        switch (curChar) {
-        case 110:
-            return jjMoveStringLiteralDfa6_2(active0, 0x400000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_2(4, active0);
-    }
-
-    private int jjMoveStringLiteralDfa6_2(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_2(4, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(5, active0);
-            return 6;
-        }
-        switch (curChar) {
-        case 99:
-            return jjMoveStringLiteralDfa7_2(active0, 0x400000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_2(5, active0);
-    }
-
-    private int jjMoveStringLiteralDfa7_2(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_2(5, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(6, active0);
-            return 7;
-        }
-        switch (curChar) {
-        case 101:
-            return jjMoveStringLiteralDfa8_2(active0, 0x400000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_2(6, active0);
-    }
-
-    private int jjMoveStringLiteralDfa8_2(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_2(6, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(7, active0);
-            return 8;
-        }
-        switch (curChar) {
-        case 111:
-            return jjMoveStringLiteralDfa9_2(active0, 0x400000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_2(7, active0);
-    }
-
-    private int jjMoveStringLiteralDfa9_2(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_2(7, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_2(8, active0);
-            return 9;
-        }
-        switch (curChar) {
-        case 102:
-            if ((active0 & 0x400000000000L) != 0L) {
-                return jjStartNfaWithStates_2(9, 46, 6);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_2(8, active0);
-    }
-
-    private int jjStartNfaWithStates_2(int pos, int kind, int state) {
-        jjmatchedKind = kind;
-        jjmatchedPos = pos;
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            return pos + 1;
-        }
-        return jjMoveNfa_2(state, pos + 1);
-    }
-
-    static final long[] jjbitVec3 = { 0x1ff00000fffffffeL, 0xffffffffffffc000L, 0xffffffffL, 0x600000000000000L };
-    static final long[] jjbitVec4 = { 0x0L, 0x0L, 0x0L, 0xff7fffffff7fffffL };
-    static final long[] jjbitVec5 = { 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL };
-    static final long[] jjbitVec6 = { 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffL, 0x0L };
-    static final long[] jjbitVec7 = { 0xffffffffffffffffL, 0xffffffffffffffffL, 0x0L, 0x0L };
-    static final long[] jjbitVec8 = { 0x3fffffffffffL, 0x0L, 0x0L, 0x0L };
-
-    private int jjMoveNfa_2(int startState, int curPos) {
-        int startsAt = 0;
-        jjnewStateCnt = 35;
-        int i = 1;
-        jjstateSet[0] = startState;
-        int kind = 0x7fffffff;
-        for (;;) {
-            if (++jjround == 0x7fffffff) {
-                ReInitRounds();
-            }
-            if (curChar < 64) {
-                long l = 1L << curChar;
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 0:
-                        if ((0x3ff000000000000L & l) != 0L) {
-                            if (kind > 11) {
-                                kind = 11;
-                            }
-                            jjCheckNAddStates(4, 8);
-                        } else if ((0x1800000000L & l) != 0L) {
-                            if (kind > 58) {
-                                kind = 58;
-                            }
-                            jjCheckNAdd(6);
-                        } else if (curChar == 39) {
-                            jjCheckNAddStates(9, 13);
-                        } else if (curChar == 34) {
-                            jjCheckNAddStates(14, 18);
-                        } else if (curChar == 46) {
-                            jjCheckNAdd(1);
-                        }
-                        break;
-                    case 1:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAddTwoStates(1, 2);
-                        break;
-                    case 3:
-                        if ((0x280000000000L & l) != 0L) {
-                            jjCheckNAdd(4);
-                        }
-                        break;
-                    case 4:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAdd(4);
-                        break;
-                    case 5:
-                        if ((0x1800000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 58) {
-                            kind = 58;
-                        }
-                        jjCheckNAdd(6);
-                        break;
-                    case 6:
-                        if ((0x3ff001000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 58) {
-                            kind = 58;
-                        }
-                        jjCheckNAdd(6);
-                        break;
-                    case 7:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 11) {
-                            kind = 11;
-                        }
-                        jjCheckNAddStates(4, 8);
-                        break;
-                    case 8:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 11) {
-                            kind = 11;
-                        }
-                        jjCheckNAdd(8);
-                        break;
-                    case 9:
-                        if ((0x3ff000000000000L & l) != 0L) {
-                            jjCheckNAddTwoStates(9, 10);
-                        }
-                        break;
-                    case 10:
-                        if (curChar != 46) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAddTwoStates(11, 12);
-                        break;
-                    case 11:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAddTwoStates(11, 12);
-                        break;
-                    case 13:
-                        if ((0x280000000000L & l) != 0L) {
-                            jjCheckNAdd(14);
-                        }
-                        break;
-                    case 14:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAdd(14);
-                        break;
-                    case 15:
-                        if ((0x3ff000000000000L & l) != 0L) {
-                            jjCheckNAddTwoStates(15, 16);
-                        }
-                        break;
-                    case 17:
-                        if ((0x280000000000L & l) != 0L) {
-                            jjCheckNAdd(18);
-                        }
-                        break;
-                    case 18:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAdd(18);
-                        break;
-                    case 19:
-                        if (curChar == 34) {
-                            jjCheckNAddStates(14, 18);
-                        }
-                        break;
-                    case 20:
-                        if ((0xfffffffbffffffffL & l) != 0L) {
-                            jjCheckNAddStates(19, 21);
-                        }
-                        break;
-                    case 22:
-                        if (curChar == 34) {
-                            jjCheckNAddStates(19, 21);
-                        }
-                        break;
-                    case 23:
-                        if (curChar == 34 && kind > 14) {
-                            kind = 14;
-                        }
-                        break;
-                    case 24:
-                        if ((0xfffffffbffffffffL & l) != 0L) {
-                            jjCheckNAddTwoStates(24, 25);
-                        }
-                        break;
-                    case 26:
-                        if ((0xfffffffbffffffffL & l) != 0L && kind > 15) {
-                            kind = 15;
-                        }
-                        break;
-                    case 27:
-                        if (curChar == 39) {
-                            jjCheckNAddStates(9, 13);
-                        }
-                        break;
-                    case 28:
-                        if ((0xffffff7fffffffffL & l) != 0L) {
-                            jjCheckNAddStates(22, 24);
-                        }
-                        break;
-                    case 30:
-                        if (curChar == 39) {
-                            jjCheckNAddStates(22, 24);
-                        }
-                        break;
-                    case 31:
-                        if (curChar == 39 && kind > 14) {
-                            kind = 14;
-                        }
-                        break;
-                    case 32:
-                        if ((0xffffff7fffffffffL & l) != 0L) {
-                            jjCheckNAddTwoStates(32, 33);
-                        }
-                        break;
-                    case 34:
-                        if ((0xffffff7fffffffffL & l) != 0L && kind > 15) {
-                            kind = 15;
-                        }
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            } else if (curChar < 128) {
-                long l = 1L << (curChar & 077);
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 0:
-                    case 6:
-                        if ((0x7fffffe87fffffeL & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 58) {
-                            kind = 58;
-                        }
-                        jjCheckNAdd(6);
-                        break;
-                    case 2:
-                        if ((0x2000000020L & l) != 0L) {
-                            jjAddStates(25, 26);
-                        }
-                        break;
-                    case 12:
-                        if ((0x2000000020L & l) != 0L) {
-                            jjAddStates(27, 28);
-                        }
-                        break;
-                    case 16:
-                        if ((0x2000000020L & l) != 0L) {
-                            jjAddStates(29, 30);
-                        }
-                        break;
-                    case 20:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            jjCheckNAddStates(19, 21);
-                        }
-                        break;
-                    case 21:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 22;
-                        }
-                        break;
-                    case 22:
-                        if (curChar == 92) {
-                            jjCheckNAddStates(19, 21);
-                        }
-                        break;
-                    case 24:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            jjAddStates(31, 32);
-                        }
-                        break;
-                    case 25:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 26;
-                        }
-                        break;
-                    case 26:
-                    case 34:
-                        if ((0xffffffffefffffffL & l) != 0L && kind > 15) {
-                            kind = 15;
-                        }
-                        break;
-                    case 28:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            jjCheckNAddStates(22, 24);
-                        }
-                        break;
-                    case 29:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 30;
-                        }
-                        break;
-                    case 30:
-                        if (curChar == 92) {
-                            jjCheckNAddStates(22, 24);
-                        }
-                        break;
-                    case 32:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            jjAddStates(33, 34);
-                        }
-                        break;
-                    case 33:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 34;
-                        }
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            } else {
-                int hiByte = curChar >> 8;
-                int i1 = hiByte >> 6;
-                long l1 = 1L << (hiByte & 077);
-                int i2 = (curChar & 0xff) >> 6;
-                long l2 = 1L << (curChar & 077);
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 0:
-                    case 6:
-                        if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) {
-                            break;
-                        }
-                        if (kind > 58) {
-                            kind = 58;
-                        }
-                        jjCheckNAdd(6);
-                        break;
-                    case 20:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            jjAddStates(19, 21);
-                        }
-                        break;
-                    case 24:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            jjAddStates(31, 32);
-                        }
-                        break;
-                    case 26:
-                    case 34:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 15) {
-                            kind = 15;
-                        }
-                        break;
-                    case 28:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            jjAddStates(22, 24);
-                        }
-                        break;
-                    case 32:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            jjAddStates(33, 34);
-                        }
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            }
-            if (kind != 0x7fffffff) {
-                jjmatchedKind = kind;
-                jjmatchedPos = curPos;
-                kind = 0x7fffffff;
-            }
-            ++curPos;
-            if ((i = jjnewStateCnt) == (startsAt = 35 - (jjnewStateCnt = startsAt))) {
-                return curPos;
-            }
-            try {
-                curChar = input_stream.readChar();
-            } catch (java.io.IOException e) {
-                return curPos;
-            }
-        }
-    }
-
-    private final int jjStopStringLiteralDfa_1(int pos, long active0) {
-        switch (pos) {
-        case 0:
-            if ((active0 & 0x80000L) != 0L) {
-                return 1;
-            }
-            if ((active0 & 0x50755550070000L) != 0L) {
-                jjmatchedKind = 58;
-                return 6;
-            }
-            return -1;
-        case 1:
-            if ((active0 & 0x105550000000L) != 0L) {
-                return 6;
-            }
-            if ((active0 & 0x50650000070000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 1;
-                return 6;
-            }
-            return -1;
-        case 2:
-            if ((active0 & 0x50050000000000L) != 0L) {
-                return 6;
-            }
-            if ((active0 & 0x600000070000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 2;
-                return 6;
-            }
-            return -1;
-        case 3:
-            if ((active0 & 0x50000L) != 0L) {
-                return 6;
-            }
-            if ((active0 & 0x600000020000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 3;
-                return 6;
-            }
-            return -1;
-        case 4:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 4;
-                return 6;
-            }
-            if ((active0 & 0x200000020000L) != 0L) {
-                return 6;
-            }
-            return -1;
-        case 5:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 5;
-                return 6;
-            }
-            return -1;
-        case 6:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 6;
-                return 6;
-            }
-            return -1;
-        case 7:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 7;
-                return 6;
-            }
-            return -1;
-        case 8:
-            if ((active0 & 0x400000000000L) != 0L) {
-                jjmatchedKind = 58;
-                jjmatchedPos = 8;
-                return 6;
-            }
-            return -1;
-        default:
-            return -1;
-        }
-    }
-
-    private final int jjStartNfa_1(int pos, long active0) {
-        return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
-    }
-
-    private int jjMoveStringLiteralDfa0_1() {
-        switch (curChar) {
-        case 33:
-            jjmatchedKind = 39;
-            return jjMoveStringLiteralDfa1_1(0x2000000000L);
-        case 37:
-            return jjStopAtPos(0, 53);
-        case 38:
-            return jjMoveStringLiteralDfa1_1(0x20000000000L);
-        case 40:
-            return jjStopAtPos(0, 20);
-        case 41:
-            return jjStopAtPos(0, 21);
-        case 42:
-            return jjStopAtPos(0, 47);
-        case 43:
-            jjmatchedKind = 48;
-            return jjMoveStringLiteralDfa1_1(0x80000000000000L);
-        case 44:
-            return jjStopAtPos(0, 25);
-        case 45:
-            jjmatchedKind = 49;
-            return jjMoveStringLiteralDfa1_1(0x200000000000000L);
-        case 46:
-            return jjStartNfaWithStates_1(0, 19, 1);
-        case 47:
-            return jjStopAtPos(0, 51);
-        case 58:
-            return jjStopAtPos(0, 24);
-        case 59:
-            return jjStopAtPos(0, 26);
-        case 60:
-            jjmatchedKind = 29;
-            return jjMoveStringLiteralDfa1_1(0x200000000L);
-        case 61:
-            jjmatchedKind = 56;
-            return jjMoveStringLiteralDfa1_1(0x800000000L);
-        case 62:
-            jjmatchedKind = 27;
-            return jjMoveStringLiteralDfa1_1(0x80000000L);
-        case 63:
-            return jjStopAtPos(0, 50);
-        case 91:
-            return jjStopAtPos(0, 22);
-        case 93:
-            return jjStopAtPos(0, 23);
-        case 97:
-            return jjMoveStringLiteralDfa1_1(0x40000000000L);
-        case 100:
-            return jjMoveStringLiteralDfa1_1(0x10000000000000L);
-        case 101:
-            return jjMoveStringLiteralDfa1_1(0x201000000000L);
-        case 102:
-            return jjMoveStringLiteralDfa1_1(0x20000L);
-        case 103:
-            return jjMoveStringLiteralDfa1_1(0x110000000L);
-        case 105:
-            return jjMoveStringLiteralDfa1_1(0x400000000000L);
-        case 108:
-            return jjMoveStringLiteralDfa1_1(0x440000000L);
-        case 109:
-            return jjMoveStringLiteralDfa1_1(0x40000000000000L);
-        case 110:
-            return jjMoveStringLiteralDfa1_1(0x14000040000L);
-        case 111:
-            return jjMoveStringLiteralDfa1_1(0x100000000000L);
-        case 116:
-            return jjMoveStringLiteralDfa1_1(0x10000L);
-        case 123:
-            return jjStopAtPos(0, 9);
-        case 124:
-            return jjMoveStringLiteralDfa1_1(0x80000000000L);
-        case 125:
-            return jjStopAtPos(0, 10);
-        default:
-            return jjMoveNfa_1(0, 0);
-        }
-    }
-
-    private int jjMoveStringLiteralDfa1_1(long active0) {
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(0, active0);
-            return 1;
-        }
-        switch (curChar) {
-        case 38:
-            if ((active0 & 0x20000000000L) != 0L) {
-                return jjStopAtPos(1, 41);
-            }
-            break;
-        case 61:
-            if ((active0 & 0x80000000L) != 0L) {
-                return jjStopAtPos(1, 31);
-            } else if ((active0 & 0x200000000L) != 0L) {
-                return jjStopAtPos(1, 33);
-            } else if ((active0 & 0x800000000L) != 0L) {
-                return jjStopAtPos(1, 35);
-            } else if ((active0 & 0x2000000000L) != 0L) {
-                return jjStopAtPos(1, 37);
-            } else if ((active0 & 0x80000000000000L) != 0L) {
-                return jjStopAtPos(1, 55);
-            }
-            break;
-        case 62:
-            if ((active0 & 0x200000000000000L) != 0L) {
-                return jjStopAtPos(1, 57);
-            }
-            break;
-        case 97:
-            return jjMoveStringLiteralDfa2_1(active0, 0x20000L);
-        case 101:
-            if ((active0 & 0x100000000L) != 0L) {
-                return jjStartNfaWithStates_1(1, 32, 6);
-            } else if ((active0 & 0x400000000L) != 0L) {
-                return jjStartNfaWithStates_1(1, 34, 6);
-            } else if ((active0 & 0x4000000000L) != 0L) {
-                return jjStartNfaWithStates_1(1, 38, 6);
-            }
-            break;
-        case 105:
-            return jjMoveStringLiteralDfa2_1(active0, 0x10000000000000L);
-        case 109:
-            return jjMoveStringLiteralDfa2_1(active0, 0x200000000000L);
-        case 110:
-            return jjMoveStringLiteralDfa2_1(active0, 0x440000000000L);
-        case 111:
-            return jjMoveStringLiteralDfa2_1(active0, 0x40010000000000L);
-        case 113:
-            if ((active0 & 0x1000000000L) != 0L) {
-                return jjStartNfaWithStates_1(1, 36, 6);
-            }
-            break;
-        case 114:
-            if ((active0 & 0x100000000000L) != 0L) {
-                return jjStartNfaWithStates_1(1, 44, 6);
-            }
-            return jjMoveStringLiteralDfa2_1(active0, 0x10000L);
-        case 116:
-            if ((active0 & 0x10000000L) != 0L) {
-                return jjStartNfaWithStates_1(1, 28, 6);
-            } else if ((active0 & 0x40000000L) != 0L) {
-                return jjStartNfaWithStates_1(1, 30, 6);
-            }
-            break;
-        case 117:
-            return jjMoveStringLiteralDfa2_1(active0, 0x40000L);
-        case 124:
-            if ((active0 & 0x80000000000L) != 0L) {
-                return jjStopAtPos(1, 43);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_1(0, active0);
-    }
-
-    private int jjMoveStringLiteralDfa2_1(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_1(0, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(1, active0);
-            return 2;
-        }
-        switch (curChar) {
-        case 100:
-            if ((active0 & 0x40000000000L) != 0L) {
-                return jjStartNfaWithStates_1(2, 42, 6);
-            } else if ((active0 & 0x40000000000000L) != 0L) {
-                return jjStartNfaWithStates_1(2, 54, 6);
-            }
-            break;
-        case 108:
-            return jjMoveStringLiteralDfa3_1(active0, 0x60000L);
-        case 112:
-            return jjMoveStringLiteralDfa3_1(active0, 0x200000000000L);
-        case 115:
-            return jjMoveStringLiteralDfa3_1(active0, 0x400000000000L);
-        case 116:
-            if ((active0 & 0x10000000000L) != 0L) {
-                return jjStartNfaWithStates_1(2, 40, 6);
-            }
-            break;
-        case 117:
-            return jjMoveStringLiteralDfa3_1(active0, 0x10000L);
-        case 118:
-            if ((active0 & 0x10000000000000L) != 0L) {
-                return jjStartNfaWithStates_1(2, 52, 6);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_1(1, active0);
-    }
-
-    private int jjMoveStringLiteralDfa3_1(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_1(1, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(2, active0);
-            return 3;
-        }
-        switch (curChar) {
-        case 101:
-            if ((active0 & 0x10000L) != 0L) {
-                return jjStartNfaWithStates_1(3, 16, 6);
-            }
-            break;
-        case 108:
-            if ((active0 & 0x40000L) != 0L) {
-                return jjStartNfaWithStates_1(3, 18, 6);
-            }
-            break;
-        case 115:
-            return jjMoveStringLiteralDfa4_1(active0, 0x20000L);
-        case 116:
-            return jjMoveStringLiteralDfa4_1(active0, 0x600000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_1(2, active0);
-    }
-
-    private int jjMoveStringLiteralDfa4_1(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_1(2, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(3, active0);
-            return 4;
-        }
-        switch (curChar) {
-        case 97:
-            return jjMoveStringLiteralDfa5_1(active0, 0x400000000000L);
-        case 101:
-            if ((active0 & 0x20000L) != 0L) {
-                return jjStartNfaWithStates_1(4, 17, 6);
-            }
-            break;
-        case 121:
-            if ((active0 & 0x200000000000L) != 0L) {
-                return jjStartNfaWithStates_1(4, 45, 6);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_1(3, active0);
-    }
-
-    private int jjMoveStringLiteralDfa5_1(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_1(3, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(4, active0);
-            return 5;
-        }
-        switch (curChar) {
-        case 110:
-            return jjMoveStringLiteralDfa6_1(active0, 0x400000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_1(4, active0);
-    }
-
-    private int jjMoveStringLiteralDfa6_1(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_1(4, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(5, active0);
-            return 6;
-        }
-        switch (curChar) {
-        case 99:
-            return jjMoveStringLiteralDfa7_1(active0, 0x400000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_1(5, active0);
-    }
-
-    private int jjMoveStringLiteralDfa7_1(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_1(5, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(6, active0);
-            return 7;
-        }
-        switch (curChar) {
-        case 101:
-            return jjMoveStringLiteralDfa8_1(active0, 0x400000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_1(6, active0);
-    }
-
-    private int jjMoveStringLiteralDfa8_1(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_1(6, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(7, active0);
-            return 8;
-        }
-        switch (curChar) {
-        case 111:
-            return jjMoveStringLiteralDfa9_1(active0, 0x400000000000L);
-        default:
-            break;
-        }
-        return jjStartNfa_1(7, active0);
-    }
-
-    private int jjMoveStringLiteralDfa9_1(long old0, long active0) {
-        if (((active0 &= old0)) == 0L) {
-            return jjStartNfa_1(7, old0);
-        }
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            jjStopStringLiteralDfa_1(8, active0);
-            return 9;
-        }
-        switch (curChar) {
-        case 102:
-            if ((active0 & 0x400000000000L) != 0L) {
-                return jjStartNfaWithStates_1(9, 46, 6);
-            }
-            break;
-        default:
-            break;
-        }
-        return jjStartNfa_1(8, active0);
-    }
-
-    private int jjStartNfaWithStates_1(int pos, int kind, int state) {
-        jjmatchedKind = kind;
-        jjmatchedPos = pos;
-        try {
-            curChar = input_stream.readChar();
-        } catch (java.io.IOException e) {
-            return pos + 1;
-        }
-        return jjMoveNfa_1(state, pos + 1);
-    }
-
-    private int jjMoveNfa_1(int startState, int curPos) {
-        int startsAt = 0;
-        jjnewStateCnt = 35;
-        int i = 1;
-        jjstateSet[0] = startState;
-        int kind = 0x7fffffff;
-        for (;;) {
-            if (++jjround == 0x7fffffff) {
-                ReInitRounds();
-            }
-            if (curChar < 64) {
-                long l = 1L << curChar;
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 0:
-                        if ((0x3ff000000000000L & l) != 0L) {
-                            if (kind > 11) {
-                                kind = 11;
-                            }
-                            jjCheckNAddStates(4, 8);
-                        } else if ((0x1800000000L & l) != 0L) {
-                            if (kind > 58) {
-                                kind = 58;
-                            }
-                            jjCheckNAdd(6);
-                        } else if (curChar == 39) {
-                            jjCheckNAddStates(9, 13);
-                        } else if (curChar == 34) {
-                            jjCheckNAddStates(14, 18);
-                        } else if (curChar == 46) {
-                            jjCheckNAdd(1);
-                        }
-                        break;
-                    case 1:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAddTwoStates(1, 2);
-                        break;
-                    case 3:
-                        if ((0x280000000000L & l) != 0L) {
-                            jjCheckNAdd(4);
-                        }
-                        break;
-                    case 4:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAdd(4);
-                        break;
-                    case 5:
-                        if ((0x1800000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 58) {
-                            kind = 58;
-                        }
-                        jjCheckNAdd(6);
-                        break;
-                    case 6:
-                        if ((0x3ff001000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 58) {
-                            kind = 58;
-                        }
-                        jjCheckNAdd(6);
-                        break;
-                    case 7:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 11) {
-                            kind = 11;
-                        }
-                        jjCheckNAddStates(4, 8);
-                        break;
-                    case 8:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 11) {
-                            kind = 11;
-                        }
-                        jjCheckNAdd(8);
-                        break;
-                    case 9:
-                        if ((0x3ff000000000000L & l) != 0L) {
-                            jjCheckNAddTwoStates(9, 10);
-                        }
-                        break;
-                    case 10:
-                        if (curChar != 46) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAddTwoStates(11, 12);
-                        break;
-                    case 11:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAddTwoStates(11, 12);
-                        break;
-                    case 13:
-                        if ((0x280000000000L & l) != 0L) {
-                            jjCheckNAdd(14);
-                        }
-                        break;
-                    case 14:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAdd(14);
-                        break;
-                    case 15:
-                        if ((0x3ff000000000000L & l) != 0L) {
-                            jjCheckNAddTwoStates(15, 16);
-                        }
-                        break;
-                    case 17:
-                        if ((0x280000000000L & l) != 0L) {
-                            jjCheckNAdd(18);
-                        }
-                        break;
-                    case 18:
-                        if ((0x3ff000000000000L & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 12) {
-                            kind = 12;
-                        }
-                        jjCheckNAdd(18);
-                        break;
-                    case 19:
-                        if (curChar == 34) {
-                            jjCheckNAddStates(14, 18);
-                        }
-                        break;
-                    case 20:
-                        if ((0xfffffffbffffffffL & l) != 0L) {
-                            jjCheckNAddStates(19, 21);
-                        }
-                        break;
-                    case 22:
-                        if (curChar == 34) {
-                            jjCheckNAddStates(19, 21);
-                        }
-                        break;
-                    case 23:
-                        if (curChar == 34 && kind > 14) {
-                            kind = 14;
-                        }
-                        break;
-                    case 24:
-                        if ((0xfffffffbffffffffL & l) != 0L) {
-                            jjCheckNAddTwoStates(24, 25);
-                        }
-                        break;
-                    case 26:
-                        if ((0xfffffffbffffffffL & l) != 0L && kind > 15) {
-                            kind = 15;
-                        }
-                        break;
-                    case 27:
-                        if (curChar == 39) {
-                            jjCheckNAddStates(9, 13);
-                        }
-                        break;
-                    case 28:
-                        if ((0xffffff7fffffffffL & l) != 0L) {
-                            jjCheckNAddStates(22, 24);
-                        }
-                        break;
-                    case 30:
-                        if (curChar == 39) {
-                            jjCheckNAddStates(22, 24);
-                        }
-                        break;
-                    case 31:
-                        if (curChar == 39 && kind > 14) {
-                            kind = 14;
-                        }
-                        break;
-                    case 32:
-                        if ((0xffffff7fffffffffL & l) != 0L) {
-                            jjCheckNAddTwoStates(32, 33);
-                        }
-                        break;
-                    case 34:
-                        if ((0xffffff7fffffffffL & l) != 0L && kind > 15) {
-                            kind = 15;
-                        }
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            } else if (curChar < 128) {
-                long l = 1L << (curChar & 077);
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 0:
-                    case 6:
-                        if ((0x7fffffe87fffffeL & l) == 0L) {
-                            break;
-                        }
-                        if (kind > 58) {
-                            kind = 58;
-                        }
-                        jjCheckNAdd(6);
-                        break;
-                    case 2:
-                        if ((0x2000000020L & l) != 0L) {
-                            jjAddStates(25, 26);
-                        }
-                        break;
-                    case 12:
-                        if ((0x2000000020L & l) != 0L) {
-                            jjAddStates(27, 28);
-                        }
-                        break;
-                    case 16:
-                        if ((0x2000000020L & l) != 0L) {
-                            jjAddStates(29, 30);
-                        }
-                        break;
-                    case 20:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            jjCheckNAddStates(19, 21);
-                        }
-                        break;
-                    case 21:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 22;
-                        }
-                        break;
-                    case 22:
-                        if (curChar == 92) {
-                            jjCheckNAddStates(19, 21);
-                        }
-                        break;
-                    case 24:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            jjAddStates(31, 32);
-                        }
-                        break;
-                    case 25:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 26;
-                        }
-                        break;
-                    case 26:
-                    case 34:
-                        if ((0xffffffffefffffffL & l) != 0L && kind > 15) {
-                            kind = 15;
-                        }
-                        break;
-                    case 28:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            jjCheckNAddStates(22, 24);
-                        }
-                        break;
-                    case 29:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 30;
-                        }
-                        break;
-                    case 30:
-                        if (curChar == 92) {
-                            jjCheckNAddStates(22, 24);
-                        }
-                        break;
-                    case 32:
-                        if ((0xffffffffefffffffL & l) != 0L) {
-                            jjAddStates(33, 34);
-                        }
-                        break;
-                    case 33:
-                        if (curChar == 92) {
-                            jjstateSet[jjnewStateCnt++] = 34;
-                        }
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            } else {
-                int hiByte = curChar >> 8;
-                int i1 = hiByte >> 6;
-                long l1 = 1L << (hiByte & 077);
-                int i2 = (curChar & 0xff) >> 6;
-                long l2 = 1L << (curChar & 077);
-                do {
-                    switch (jjstateSet[--i]) {
-                    case 0:
-                    case 6:
-                        if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) {
-                            break;
-                        }
-                        if (kind > 58) {
-                            kind = 58;
-                        }
-                        jjCheckNAdd(6);
-                        break;
-                    case 20:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            jjAddStates(19, 21);
-                        }
-                        break;
-                    case 24:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            jjAddStates(31, 32);
-                        }
-                        break;
-                    case 26:
-                    case 34:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 15) {
-                            kind = 15;
-                        }
-                        break;
-                    case 28:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            jjAddStates(22, 24);
-                        }
-                        break;
-                    case 32:
-                        if (jjCanMove_0(hiByte, i1, i2, l1, l2)) {
-                            jjAddStates(33, 34);
-                        }
-                        break;
-                    default:
-                        break;
-                    }
-                } while (i != startsAt);
-            }
-            if (kind != 0x7fffffff) {
-                jjmatchedKind = kind;
-                jjmatchedPos = curPos;
-                kind = 0x7fffffff;
-            }
-            ++curPos;
-            if ((i = jjnewStateCnt) == (startsAt = 35 - (jjnewStateCnt = startsAt))) {
-                return curPos;
-            }
-            try {
-                curChar = input_stream.readChar();
-            } catch (java.io.IOException e) {
-                return curPos;
-            }
-        }
-    }
-
-    static final int[] jjnextStates = { 0, 1, 3, 5, 8, 9, 10, 15, 16, 28, 29, 31, 32, 33, 20, 21, 23, 24, 25, 20, 21, 23, 28, 29, 31, 3, 4, 13, 14, 17, 18, 24,
-            25, 32, 33, };
-
-    private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) {
-        switch (hiByte) {
-        case 0:
-            return ((jjbitVec2[i2] & l2) != 0L);
-        default:
-            if ((jjbitVec0[i1] & l1) != 0L) {
-                return true;
-            }
-            return false;
-        }
-    }
-
-    private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2) {
-        switch (hiByte) {
-        case 0:
-            return ((jjbitVec4[i2] & l2) != 0L);
-        case 48:
-            return ((jjbitVec5[i2] & l2) != 0L);
-        case 49:
-            return ((jjbitVec6[i2] & l2) != 0L);
-        case 51:
-            return ((jjbitVec7[i2] & l2) != 0L);
-        case 61:
-            return ((jjbitVec8[i2] & l2) != 0L);
-        default:
-            if ((jjbitVec3[i1] & l1) != 0L) {
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /** Token literal values. */
-    public static final String[] jjstrLiteralImages = { "", null, "\44\173", "\43\173", null, null, null, null, null, "\173", "\175", null, null, null, null,
-            null, "\164\162\165\145", "\146\141\154\163\145", "\156\165\154\154", "\56", "\50", "\51", "\133", "\135", "\72", "\54", "\73", "\76", "\147\164",
-            "\74", "\154\164", "\76\75", "\147\145", "\74\75", "\154\145", "\75\75", "\145\161", "\41\75", "\156\145", "\41", "\156\157\164", "\46\46",
-            "\141\156\144", "\174\174", "\157\162", "\145\155\160\164\171", "\151\156\163\164\141\156\143\145\157\146", "\52", "\53", "\55", "\77", "\57",
-            "\144\151\166", "\45", "\155\157\144", "\53\75", "\75", "\55\76", null, null, null, null, null, };
-
-    /** Lexer state names. */
-    public static final String[] lexStateNames = { "DEFAULT", "IN_EXPRESSION", "IN_MAP", };
-
-    /** Lex State array. */
-    public static final int[] jjnewLexState = { -1, -1, 1, 1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
-    static final long[] jjtoToken = { 0x47ffffffffffde0fL, };
-    static final long[] jjtoSkip = { 0x1f0L, };
-    protected SimpleCharStream input_stream;
-    private final int[] jjrounds = new int[35];
-    private final int[] jjstateSet = new int[70];
-    private final StringBuilder jjimage = new StringBuilder();
-    private StringBuilder image = jjimage;
-    private int jjimageLen;
-    private int lengthOfMatch;
-    protected char curChar;
-
-    /** Constructor. */
-    public ELParserTokenManager(SimpleCharStream stream) {
-        if (SimpleCharStream.staticFlag) {
-            throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
-        }
-        input_stream = stream;
-    }
-
-    /** Constructor. */
-    public ELParserTokenManager(SimpleCharStream stream, int lexState) {
-        this(stream);
-        SwitchTo(lexState);
-    }
-
-    /** Reinitialise parser. */
-    public void ReInit(SimpleCharStream stream) {
-        jjmatchedPos = jjnewStateCnt = 0;
-        curLexState = defaultLexState;
-        input_stream = stream;
-        ReInitRounds();
-    }
-
-    private void ReInitRounds() {
-        int i;
-        jjround = 0x80000001;
-        for (i = 35; i-- > 0;) {
-            jjrounds[i] = 0x80000000;
-        }
-    }
-
-    /** Reinitialise parser. */
-    public void ReInit(SimpleCharStream stream, int lexState) {
-        ReInit(stream);
-        SwitchTo(lexState);
-    }
-
-    /** Switch to specified lex state. */
-    public void SwitchTo(int lexState) {
-        if (lexState >= 3 || lexState < 0) {
-            throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
-        } else {
-            curLexState = lexState;
-        }
-    }
-
-    protected Token jjFillToken() {
-        final Token t;
-        final String curTokenImage;
-        final int beginLine;
-        final int endLine;
-        final int beginColumn;
-        final int endColumn;
-        String im = jjstrLiteralImages[jjmatchedKind];
-        curTokenImage = (im == null) ? input_stream.GetImage() : im;
-        beginLine = input_stream.getBeginLine();
-        beginColumn = input_stream.getBeginColumn();
-        endLine = input_stream.getEndLine();
-        endColumn = input_stream.getEndColumn();
-        t = Token.newToken(jjmatchedKind);
-        t.kind = jjmatchedKind;
-        t.image = curTokenImage;
-
-        t.beginLine = beginLine;
-        t.endLine = endLine;
-        t.beginColumn = beginColumn;
-        t.endColumn = endColumn;
-
-        return t;
-    }
-
-    int curLexState = 0;
-    int defaultLexState = 0;
-    int jjnewStateCnt;
-    int jjround;
-    int jjmatchedPos;
-    int jjmatchedKind;
-
-    /** Get the next Token. */
-    public Token getNextToken() {
-        Token matchedToken;
-        int curPos = 0;
-
-        EOFLoop: for (;;) {
-            try {
-                curChar = input_stream.BeginToken();
-            } catch (java.io.IOException e) {
-                jjmatchedKind = 0;
-                matchedToken = jjFillToken();
-                return matchedToken;
-            }
-            image = jjimage;
-            image.setLength(0);
-            jjimageLen = 0;
-
-            switch (curLexState) {
-            case 0:
-                jjmatchedKind = 0x7fffffff;
-                jjmatchedPos = 0;
-                curPos = jjMoveStringLiteralDfa0_0();
-                break;
-            case 1:
-                try {
-                    input_stream.backup(0);
-                    while (curChar <= 32 && (0x100002600L & (1L << curChar)) != 0L) {
-                        curChar = input_stream.BeginToken();
-                    }
-                } catch (java.io.IOException e1) {
-                    continue EOFLoop;
-                }
-                jjmatchedKind = 0x7fffffff;
-                jjmatchedPos = 0;
-                curPos = jjMoveStringLiteralDfa0_1();
-                if (jjmatchedPos == 0 && jjmatchedKind > 62) {
-                    jjmatchedKind = 62;
-                }
-                break;
-            case 2:
-                try {
-                    input_stream.backup(0);
-                    while (curChar <= 32 && (0x100002600L & (1L << curChar)) != 0L) {
-                        curChar = input_stream.BeginToken();
-                    }
-                } catch (java.io.IOException e1) {
-                    continue EOFLoop;
-                }
-                jjmatchedKind = 0x7fffffff;
-                jjmatchedPos = 0;
-                curPos = jjMoveStringLiteralDfa0_2();
-                if (jjmatchedPos == 0 && jjmatchedKind > 62) {
-                    jjmatchedKind = 62;
-                }
-                break;
-            }
-            if (jjmatchedKind != 0x7fffffff) {
-                if (jjmatchedPos + 1 < curPos) {
-                    input_stream.backup(curPos - jjmatchedPos - 1);
-                }
-                if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) {
-                    matchedToken = jjFillToken();
-                    TokenLexicalActions(matchedToken);
-                    if (jjnewLexState[jjmatchedKind] != -1) {
-                        curLexState = jjnewLexState[jjmatchedKind];
-                    }
-                    return matchedToken;
-                } else {
-                    if (jjnewLexState[jjmatchedKind] != -1) {
-                        curLexState = jjnewLexState[jjmatchedKind];
-                    }
-                    continue EOFLoop;
-                }
-            }
-            int error_line = input_stream.getEndLine();
-            int error_column = input_stream.getEndColumn();
-            String error_after = null;
-            boolean EOFSeen = false;
-            try {
-                input_stream.readChar();
-                input_stream.backup(1);
-            } catch (java.io.IOException e1) {
-                EOFSeen = true;
-                error_after = curPos <= 1 ? "" : input_stream.GetImage();
-                if (curChar == '\n' || curChar == '\r') {
-                    error_line++;
-                    error_column = 0;
-                } else {
-                    error_column++;
-                }
-            }
-            if (!EOFSeen) {
-                input_stream.backup(1);
-                error_after = curPos <= 1 ? "" : input_stream.GetImage();
-            }
-            throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
-        }
-    }
-
-    void TokenLexicalActions(Token matchedToken) {
-        switch (jjmatchedKind) {
-        case 2:
-            image.append(jjstrLiteralImages[2]);
-            lengthOfMatch = jjstrLiteralImages[2].length();
-            stack.push(DEFAULT);
-            break;
-        case 3:
-            image.append(jjstrLiteralImages[3]);
-            lengthOfMatch = jjstrLiteralImages[3].length();
-            stack.push(DEFAULT);
-            break;
-        case 9:
-            image.append(jjstrLiteralImages[9]);
-            lengthOfMatch = jjstrLiteralImages[9].length();
-            stack.push(curLexState);
-            break;
-        case 10:
-            image.append(jjstrLiteralImages[10]);
-            lengthOfMatch = jjstrLiteralImages[10].length();
-            SwitchTo(stack.pop());
-            break;
-        default:
-            break;
-        }
-    }
-
-    private void jjCheckNAdd(int state) {
-        if (jjrounds[state] != jjround) {
-            jjstateSet[jjnewStateCnt++] = state;
-            jjrounds[state] = jjround;
-        }
-    }
-
-    private void jjAddStates(int start, int end) {
-        do {
-            jjstateSet[jjnewStateCnt++] = jjnextStates[start];
-        } while (start++ != end);
-    }
-
-    private void jjCheckNAddTwoStates(int state1, int state2) {
-        jjCheckNAdd(state1);
-        jjCheckNAdd(state2);
-    }
-
-    private void jjCheckNAddStates(int start, int end) {
-        do {
-            jjCheckNAdd(jjnextStates[start]);
-        } while (start++ != end);
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/parser/ELParserTreeConstants.java b/impl/src/main/java/com/sun/el/parser/ELParserTreeConstants.java
deleted file mode 100644
index 8a2762f..0000000
--- a/impl/src/main/java/com/sun/el/parser/ELParserTreeConstants.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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
- */
-
-/* Generated By:JavaCC: Do not edit this line. ELParserTreeConstants.java Version 5.0 */
-package com.sun.el.parser;
-
-public interface ELParserTreeConstants {
-    int JJTCOMPOSITEEXPRESSION = 0;
-    int JJTLITERALEXPRESSION = 1;
-    int JJTDEFERREDEXPRESSION = 2;
-    int JJTDYNAMICEXPRESSION = 3;
-    int JJTVOID = 4;
-    int JJTSEMICOLON = 5;
-    int JJTASSIGN = 6;
-    int JJTLAMBDAEXPRESSION = 7;
-    int JJTLAMBDAPARAMETERS = 8;
-    int JJTCHOICE = 9;
-    int JJTOR = 10;
-    int JJTAND = 11;
-    int JJTEQUAL = 12;
-    int JJTNOTEQUAL = 13;
-    int JJTLESSTHAN = 14;
-    int JJTGREATERTHAN = 15;
-    int JJTLESSTHANEQUAL = 16;
-    int JJTGREATERTHANEQUAL = 17;
-    int JJTCONCAT = 18;
-    int JJTPLUS = 19;
-    int JJTMINUS = 20;
-    int JJTMULT = 21;
-    int JJTDIV = 22;
-    int JJTMOD = 23;
-    int JJTNEGATIVE = 24;
-    int JJTNOT = 25;
-    int JJTEMPTY = 26;
-    int JJTVALUE = 27;
-    int JJTDOTSUFFIX = 28;
-    int JJTBRACKETSUFFIX = 29;
-    int JJTMETHODARGUMENTS = 30;
-    int JJTMAPDATA = 31;
-    int JJTMAPENTRY = 32;
-    int JJTLISTDATA = 33;
-    int JJTIDENTIFIER = 34;
-    int JJTFUNCTION = 35;
-    int JJTTRUE = 36;
-    int JJTFALSE = 37;
-    int JJTFLOATINGPOINT = 38;
-    int JJTINTEGER = 39;
-    int JJTSTRING = 40;
-    int JJTNULL = 41;
-
-    String[] jjtNodeName = { "CompositeExpression", "LiteralExpression", "DeferredExpression", "DynamicExpression", "void", "SemiColon", "Assign",
-            "LambdaExpression", "LambdaParameters", "Choice", "Or", "And", "Equal", "NotEqual", "LessThan", "GreaterThan", "LessThanEqual", "GreaterThanEqual",
-            "Concat", "Plus", "Minus", "Mult", "Div", "Mod", "Negative", "Not", "Empty", "Value", "DotSuffix", "BracketSuffix", "MethodArguments", "MapData",
-            "MapEntry", "ListData", "Identifier", "Function", "True", "False", "FloatingPoint", "Integer", "String", "Null", };
-}
-/* JavaCC - OriginalChecksum=295bae338407e43a1d349f1ce802614a (do not edit this line) */
diff --git a/impl/src/main/java/com/sun/el/parser/JJTELParserState.java b/impl/src/main/java/com/sun/el/parser/JJTELParserState.java
deleted file mode 100644
index 80c0298..0000000
--- a/impl/src/main/java/com/sun/el/parser/JJTELParserState.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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
- */
-
-/* Generated By:JavaCC: Do not edit this line. JJTELParserState.java Version 5.0 */
-package com.sun.el.parser;
-
-public class JJTELParserState {
-    private java.util.List<Node> nodes;
-    private java.util.List<Integer> marks;
-
-    private int sp; // number of nodes on stack
-    private int mk; // current mark
-    private boolean node_created;
-
-    public JJTELParserState() {
-        nodes = new java.util.ArrayList<Node>();
-        marks = new java.util.ArrayList<Integer>();
-        sp = 0;
-        mk = 0;
-    }
-
-    /*
-     * Determines whether the current node was actually closed and pushed. This should only be called in the final user
-     * action of a node scope.
-     */
-    public boolean nodeCreated() {
-        return node_created;
-    }
-
-    /*
-     * Call this to reinitialize the node stack. It is called automatically by the parser's ReInit() method.
-     */
-    public void reset() {
-        nodes.clear();
-        marks.clear();
-        sp = 0;
-        mk = 0;
-    }
-
-    /*
-     * Returns the root node of the AST. It only makes sense to call this after a successful parse.
-     */
-    public Node rootNode() {
-        return nodes.get(0);
-    }
-
-    /* Pushes a node on to the stack. */
-    public void pushNode(Node n) {
-        nodes.add(n);
-        ++sp;
-    }
-
-    /*
-     * Returns the node on the top of the stack, and remove it from the stack.
-     */
-    public Node popNode() {
-        if (--sp < mk) {
-            mk = marks.remove(marks.size() - 1);
-        }
-        return nodes.remove(nodes.size() - 1);
-    }
-
-    /* Returns the node currently on the top of the stack. */
-    public Node peekNode() {
-        return nodes.get(nodes.size() - 1);
-    }
-
-    /*
-     * Returns the number of children on the stack in the current node scope.
-     */
-    public int nodeArity() {
-        return sp - mk;
-    }
-
-    public void clearNodeScope(Node n) {
-        while (sp > mk) {
-            popNode();
-        }
-        mk = marks.remove(marks.size() - 1);
-    }
-
-    public void openNodeScope(Node n) {
-        marks.add(mk);
-        mk = sp;
-        n.jjtOpen();
-    }
-
-    /*
-     * A definite node is constructed from a specified number of children. That number of nodes are popped from the stack
-     * and made the children of the definite node. Then the definite node is pushed on to the stack.
-     */
-    public void closeNodeScope(Node n, int num) {
-        mk = marks.remove(marks.size() - 1);
-        while (num-- > 0) {
-            Node c = popNode();
-            c.jjtSetParent(n);
-            n.jjtAddChild(c, num);
-        }
-        n.jjtClose();
-        pushNode(n);
-        node_created = true;
-    }
-
-    /*
-     * A conditional node is constructed if its condition is true. All the nodes that have been pushed since the node was
-     * opened are made children of the conditional node, which is then pushed on to the stack. If the condition is false the
-     * node is not constructed and they are left on the stack.
-     */
-    public void closeNodeScope(Node n, boolean condition) {
-        if (condition) {
-            int a = nodeArity();
-            mk = marks.remove(marks.size() - 1);
-            while (a-- > 0) {
-                Node c = popNode();
-                c.jjtSetParent(n);
-                n.jjtAddChild(c, a);
-            }
-            n.jjtClose();
-            pushNode(n);
-            node_created = true;
-        } else {
-            mk = marks.remove(marks.size() - 1);
-            node_created = false;
-        }
-    }
-}
-/* JavaCC - OriginalChecksum=a169ec9bf66edaa6db0c5550b112beee (do not edit this line) */
diff --git a/impl/src/main/java/com/sun/el/parser/Node.java b/impl/src/main/java/com/sun/el/parser/Node.java
deleted file mode 100644
index be71187..0000000
--- a/impl/src/main/java/com/sun/el/parser/Node.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-import javax.el.MethodInfo;
-import javax.el.ValueReference;
-
-import com.sun.el.lang.EvaluationContext;
-
-/* All AST nodes must implement this interface.  It provides basic
-   machinery for constructing the parent and child relationships
-   between nodes. */
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public interface Node {
-
-    /**
-     * This method is called after the node has been made the current node. It indicates that child nodes can now be added
-     * to it.
-     */
-    void jjtOpen();
-
-    /**
-     * This method is called after all the child nodes have been added.
-     */
-    void jjtClose();
-
-    /**
-     * This pair of methods are used to inform the node of its parent.
-     */
-    void jjtSetParent(Node n);
-
-    Node jjtGetParent();
-
-    /**
-     * This method tells the node to add its argument to the node's list of children.
-     */
-    void jjtAddChild(Node n, int i);
-
-    /**
-     * This method returns a child node. The children are numbered from zero, left to right.
-     */
-    Node jjtGetChild(int i);
-
-    /** Return the number of children the node has. */
-    int jjtGetNumChildren();
-
-    String getImage();
-
-    Object getValue(EvaluationContext ctx) throws ELException;
-
-    void setValue(EvaluationContext ctx, Object value) throws ELException;
-
-    Class getType(EvaluationContext ctx) throws ELException;
-
-    ValueReference getValueReference(EvaluationContext ctx) throws ELException;
-
-    boolean isReadOnly(EvaluationContext ctx) throws ELException;
-
-    void accept(NodeVisitor visitor) throws ELException;
-
-    MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes) throws ELException;
-
-    Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException;
-
-    @Override
-    boolean equals(Object n);
-
-    @Override
-    int hashCode();
-
-    boolean isParametersProvided();
-}
diff --git a/impl/src/main/java/com/sun/el/parser/NodeVisitor.java b/impl/src/main/java/com/sun/el/parser/NodeVisitor.java
deleted file mode 100644
index e18922c..0000000
--- a/impl/src/main/java/com/sun/el/parser/NodeVisitor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public interface NodeVisitor {
-    void visit(Node node) throws ELException;
-}
diff --git a/impl/src/main/java/com/sun/el/parser/ParseException.java b/impl/src/main/java/com/sun/el/parser/ParseException.java
deleted file mode 100644
index ac9dee3..0000000
--- a/impl/src/main/java/com/sun/el/parser/ParseException.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-/**
- * This exception is thrown when parse errors are encountered. You can explicitly create objects of this exception type
- * by calling the method generateParseException in the generated parser.
- *
- * You can modify this class to customize your error reporting mechanisms so long as you retain the public fields.
- */
-public class ParseException extends Exception {
-
-    /**
-     * This constructor is used by the method "generateParseException" in the generated parser. Calling this constructor
-     * generates a new object of this type with the fields "currentToken", "expectedTokenSequences", and "tokenImage" set.
-     * The boolean flag "specialConstructor" is also set to true to indicate that this constructor was used to create this
-     * object. This constructor calls its super class with the empty string to force the "toString" method of parent class
-     * "Throwable" to print the error message in the form: ParseException: <result of getMessage>
-     */
-    public ParseException(Token currentTokenVal, int[][] expectedTokenSequencesVal, String[] tokenImageVal) {
-        super("");
-        specialConstructor = true;
-        currentToken = currentTokenVal;
-        expectedTokenSequences = expectedTokenSequencesVal;
-        tokenImage = tokenImageVal;
-    }
-
-    /**
-     * The following constructors are for use by you for whatever purpose you can think of. Constructing the exception in
-     * this manner makes the exception behave in the normal way - i.e., as documented in the class "Throwable". The fields
-     * "errorToken", "expectedTokenSequences", and "tokenImage" do not contain relevant information. The JavaCC generated
-     * code does not use these constructors.
-     */
-
-    public ParseException() {
-        super();
-        specialConstructor = false;
-    }
-
-    public ParseException(String message) {
-        super(message);
-        specialConstructor = false;
-    }
-
-    /**
-     * This variable determines which constructor was used to create this object and thereby affects the semantics of the
-     * "getMessage" method (see below).
-     */
-    protected boolean specialConstructor;
-
-    /**
-     * This is the last token that has been consumed successfully. If this object has been created due to a parse error, the
-     * token followng this token will (therefore) be the first error token.
-     */
-    public Token currentToken;
-
-    /**
-     * Each entry in this array is an array of integers. Each array of integers represents a sequence of tokens (by their
-     * ordinal values) that is expected at this point of the parse.
-     */
-    public int[][] expectedTokenSequences;
-
-    /**
-     * This is a reference to the "tokenImage" array of the generated parser within which the parse error occurred. This
-     * array is defined in the generated ...Constants interface.
-     */
-    public String[] tokenImage;
-
-    /**
-     * This method has the standard behavior when this object has been created using the standard constructors. Otherwise,
-     * it uses "currentToken" and "expectedTokenSequences" to generate a parse error message and returns it. If this object
-     * has been created due to a parse error, and you do not catch it (it gets thrown from the parser), then this method is
-     * called during the printing of the final stack trace, and hence the correct error message gets displayed.
-     */
-    @Override
-    public String getMessage() {
-        if (!specialConstructor) {
-            return super.getMessage();
-        }
-        String expected = "";
-        int maxSize = 0;
-        for (int i = 0; i < expectedTokenSequences.length; i++) {
-            if (maxSize < expectedTokenSequences[i].length) {
-                maxSize = expectedTokenSequences[i].length;
-            }
-            for (int j = 0; j < expectedTokenSequences[i].length; j++) {
-                expected += tokenImage[expectedTokenSequences[i][j]] + " ";
-            }
-            if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
-                expected += "...";
-            }
-            expected += eol + "    ";
-        }
-        String retval = "Encountered \"";
-        Token tok = currentToken.next;
-        for (int i = 0; i < maxSize; i++) {
-            if (i != 0) {
-                retval += " ";
-            }
-            if (tok.kind == 0) {
-                retval += tokenImage[0];
-                break;
-            }
-            retval += add_escapes(tok.image);
-            tok = tok.next;
-        }
-        retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
-        retval += "." + eol;
-        if (expectedTokenSequences.length == 1) {
-            retval += "Was expecting:" + eol + "    ";
-        } else {
-            retval += "Was expecting one of:" + eol + "    ";
-        }
-        retval += expected;
-        return retval;
-    }
-
-    /**
-     * The end of line string for this machine.
-     */
-    protected String eol = System.getProperty("line.separator", "\n");
-
-    /**
-     * Used to convert raw characters to their escaped version when these raw version cannot be used as part of an ASCII
-     * string literal.
-     */
-    protected String add_escapes(String str) {
-        StringBuffer retval = new StringBuffer();
-        char ch;
-        for (int i = 0; i < str.length(); i++) {
-            switch (str.charAt(i)) {
-            case 0:
-                continue;
-            case '\b':
-                retval.append("\\b");
-                continue;
-            case '\t':
-                retval.append("\\t");
-                continue;
-            case '\n':
-                retval.append("\\n");
-                continue;
-            case '\f':
-                retval.append("\\f");
-                continue;
-            case '\r':
-                retval.append("\\r");
-                continue;
-            case '\"':
-                retval.append("\\\"");
-                continue;
-            case '\'':
-                retval.append("\\\'");
-                continue;
-            case '\\':
-                retval.append("\\\\");
-                continue;
-            default:
-                if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                    String s = "0000" + Integer.toString(ch, 16);
-                    retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-                } else {
-                    retval.append(ch);
-                }
-                continue;
-            }
-        }
-        return retval.toString();
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/parser/SimpleCharStream.java b/impl/src/main/java/com/sun/el/parser/SimpleCharStream.java
deleted file mode 100644
index 4b0b619..0000000
--- a/impl/src/main/java/com/sun/el/parser/SimpleCharStream.java
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * 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
- */
-
-/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
-/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
-package com.sun.el.parser;
-
-/**
- * An implementation of interface CharStream, where the stream is assumed to contain only ASCII characters (without
- * unicode processing).
- */
-
-public class SimpleCharStream {
-    /** Whether parser is static. */
-    public static final boolean staticFlag = false;
-    int bufsize;
-    int available;
-    int tokenBegin;
-    /** Position in buffer. */
-    public int bufpos = -1;
-    protected int bufline[];
-    protected int bufcolumn[];
-
-    protected int column = 0;
-    protected int line = 1;
-
-    protected boolean prevCharIsCR = false;
-    protected boolean prevCharIsLF = false;
-
-    protected java.io.Reader inputStream;
-
-    protected char[] buffer;
-    protected int maxNextCharInd = 0;
-    protected int inBuf = 0;
-    protected int tabSize = 8;
-
-    protected void setTabSize(int i) {
-        tabSize = i;
-    }
-
-    protected int getTabSize(int i) {
-        return tabSize;
-    }
-
-    protected void ExpandBuff(boolean wrapAround) {
-        char[] newbuffer = new char[bufsize + 2048];
-        int newbufline[] = new int[bufsize + 2048];
-        int newbufcolumn[] = new int[bufsize + 2048];
-
-        try {
-            if (wrapAround) {
-                System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-                System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
-                buffer = newbuffer;
-
-                System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-                System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
-                bufline = newbufline;
-
-                System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-                System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
-                bufcolumn = newbufcolumn;
-
-                maxNextCharInd = (bufpos += (bufsize - tokenBegin));
-            } else {
-                System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-                buffer = newbuffer;
-
-                System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-                bufline = newbufline;
-
-                System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-                bufcolumn = newbufcolumn;
-
-                maxNextCharInd = (bufpos -= tokenBegin);
-            }
-        } catch (Throwable t) {
-            throw new Error(t.getMessage());
-        }
-
-        bufsize += 2048;
-        available = bufsize;
-        tokenBegin = 0;
-    }
-
-    protected void FillBuff() throws java.io.IOException {
-        if (maxNextCharInd == available) {
-            if (available == bufsize) {
-                if (tokenBegin > 2048) {
-                    bufpos = maxNextCharInd = 0;
-                    available = tokenBegin;
-                } else if (tokenBegin < 0) {
-                    bufpos = maxNextCharInd = 0;
-                } else {
-                    ExpandBuff(false);
-                }
-            } else if (available > tokenBegin) {
-                available = bufsize;
-            } else if ((tokenBegin - available) < 2048) {
-                ExpandBuff(true);
-            } else {
-                available = tokenBegin;
-            }
-        }
-
-        int i;
-        try {
-            if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) {
-                inputStream.close();
-                throw new java.io.IOException();
-            } else {
-                maxNextCharInd += i;
-            }
-            return;
-        } catch (java.io.IOException e) {
-            --bufpos;
-            backup(0);
-            if (tokenBegin == -1) {
-                tokenBegin = bufpos;
-            }
-            throw e;
-        }
-    }
-
-    /** Start. */
-    public char BeginToken() throws java.io.IOException {
-        tokenBegin = -1;
-        char c = readChar();
-        tokenBegin = bufpos;
-
-        return c;
-    }
-
-    protected void UpdateLineColumn(char c) {
-        column++;
-
-        if (prevCharIsLF) {
-            prevCharIsLF = false;
-            line += (column = 1);
-        } else if (prevCharIsCR) {
-            prevCharIsCR = false;
-            if (c == '\n') {
-                prevCharIsLF = true;
-            } else {
-                line += (column = 1);
-            }
-        }
-
-        switch (c) {
-        case '\r':
-            prevCharIsCR = true;
-            break;
-        case '\n':
-            prevCharIsLF = true;
-            break;
-        case '\t':
-            column--;
-            column += (tabSize - (column % tabSize));
-            break;
-        default:
-            break;
-        }
-
-        bufline[bufpos] = line;
-        bufcolumn[bufpos] = column;
-    }
-
-    /** Read a character. */
-    public char readChar() throws java.io.IOException {
-        if (inBuf > 0) {
-            --inBuf;
-
-            if (++bufpos == bufsize) {
-                bufpos = 0;
-            }
-
-            return buffer[bufpos];
-        }
-
-        if (++bufpos >= maxNextCharInd) {
-            FillBuff();
-        }
-
-        char c = buffer[bufpos];
-
-        UpdateLineColumn(c);
-        return c;
-    }
-
-    @Deprecated
-    /**
-     * @deprecated
-     * @see #getEndColumn
-     */
-
-    public int getColumn() {
-        return bufcolumn[bufpos];
-    }
-
-    @Deprecated
-    /**
-     * @deprecated
-     * @see #getEndLine
-     */
-
-    public int getLine() {
-        return bufline[bufpos];
-    }
-
-    /** Get token end column number. */
-    public int getEndColumn() {
-        return bufcolumn[bufpos];
-    }
-
-    /** Get token end line number. */
-    public int getEndLine() {
-        return bufline[bufpos];
-    }
-
-    /** Get token beginning column number. */
-    public int getBeginColumn() {
-        return bufcolumn[tokenBegin];
-    }
-
-    /** Get token beginning line number. */
-    public int getBeginLine() {
-        return bufline[tokenBegin];
-    }
-
-    /** Backup a number of characters. */
-    public void backup(int amount) {
-
-        inBuf += amount;
-        if ((bufpos -= amount) < 0) {
-            bufpos += bufsize;
-        }
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.Reader dstream, int startline, int startcolumn, int buffersize) {
-        inputStream = dstream;
-        line = startline;
-        column = startcolumn - 1;
-
-        available = bufsize = buffersize;
-        buffer = new char[buffersize];
-        bufline = new int[buffersize];
-        bufcolumn = new int[buffersize];
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.Reader dstream, int startline, int startcolumn) {
-        this(dstream, startline, startcolumn, 4096);
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.Reader dstream) {
-        this(dstream, 1, 1, 4096);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.Reader dstream, int startline, int startcolumn, int buffersize) {
-        inputStream = dstream;
-        line = startline;
-        column = startcolumn - 1;
-
-        if (buffer == null || buffersize != buffer.length) {
-            available = bufsize = buffersize;
-            buffer = new char[buffersize];
-            bufline = new int[buffersize];
-            bufcolumn = new int[buffersize];
-        }
-        prevCharIsLF = prevCharIsCR = false;
-        tokenBegin = inBuf = maxNextCharInd = 0;
-        bufpos = -1;
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.Reader dstream, int startline, int startcolumn) {
-        ReInit(dstream, startline, startcolumn, 4096);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.Reader dstream) {
-        ReInit(dstream, 1, 1, 4096);
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, int startcolumn, int buffersize)
-            throws java.io.UnsupportedEncodingException {
-        this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.InputStream dstream, int startline, int startcolumn, int buffersize) {
-        this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, int startcolumn) throws java.io.UnsupportedEncodingException {
-        this(dstream, encoding, startline, startcolumn, 4096);
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.InputStream dstream, int startline, int startcolumn) {
-        this(dstream, startline, startcolumn, 4096);
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException {
-        this(dstream, encoding, 1, 1, 4096);
-    }
-
-    /** Constructor. */
-    public SimpleCharStream(java.io.InputStream dstream) {
-        this(dstream, 1, 1, 4096);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.InputStream dstream, String encoding, int startline, int startcolumn, int buffersize)
-            throws java.io.UnsupportedEncodingException {
-        ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn,
-                buffersize);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.InputStream dstream, int startline, int startcolumn, int buffersize) {
-        ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException {
-        ReInit(dstream, encoding, 1, 1, 4096);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.InputStream dstream) {
-        ReInit(dstream, 1, 1, 4096);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.InputStream dstream, String encoding, int startline, int startcolumn) throws java.io.UnsupportedEncodingException {
-        ReInit(dstream, encoding, startline, startcolumn, 4096);
-    }
-
-    /** Reinitialise. */
-    public void ReInit(java.io.InputStream dstream, int startline, int startcolumn) {
-        ReInit(dstream, startline, startcolumn, 4096);
-    }
-
-    /** Get token literal value. */
-    public String GetImage() {
-        if (bufpos >= tokenBegin) {
-            return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
-        } else {
-            return new String(buffer, tokenBegin, bufsize - tokenBegin) + new String(buffer, 0, bufpos + 1);
-        }
-    }
-
-    /** Get the suffix. */
-    public char[] GetSuffix(int len) {
-        char[] ret = new char[len];
-
-        if ((bufpos + 1) >= len) {
-            System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
-        } else {
-            System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, len - bufpos - 1);
-            System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
-        }
-
-        return ret;
-    }
-
-    /** Reset buffer when finished. */
-    public void Done() {
-        buffer = null;
-        bufline = null;
-        bufcolumn = null;
-    }
-
-    /**
-     * Method to adjust line and column numbers for the start of a token.
-     */
-    public void adjustBeginLineColumn(int newLine, int newCol) {
-        int start = tokenBegin;
-        int len;
-
-        if (bufpos >= tokenBegin) {
-            len = bufpos - tokenBegin + inBuf + 1;
-        } else {
-            len = bufsize - tokenBegin + bufpos + 1 + inBuf;
-        }
-
-        int i = 0, j = 0, k = 0;
-        int nextColDiff = 0, columnDiff = 0;
-
-        while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) {
-            bufline[j] = newLine;
-            nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
-            bufcolumn[j] = newCol + columnDiff;
-            columnDiff = nextColDiff;
-            i++;
-        }
-
-        if (i < len) {
-            bufline[j] = newLine++;
-            bufcolumn[j] = newCol + columnDiff;
-
-            while (i++ < len) {
-                if (bufline[j = start % bufsize] != bufline[++start % bufsize]) {
-                    bufline[j] = newLine++;
-                } else {
-                    bufline[j] = newLine;
-                }
-            }
-        }
-
-        line = bufline[j];
-        column = bufcolumn[j];
-    }
-
-}
-/* JavaCC - OriginalChecksum=7ea14199259e7ce0336b228c8cdb9958 (do not edit this line) */
diff --git a/impl/src/main/java/com/sun/el/parser/SimpleNode.java b/impl/src/main/java/com/sun/el/parser/SimpleNode.java
deleted file mode 100644
index 1c004c6..0000000
--- a/impl/src/main/java/com/sun/el/parser/SimpleNode.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import javax.el.ELException;
-import javax.el.MethodInfo;
-import javax.el.PropertyNotWritableException;
-import javax.el.ValueReference;
-
-import com.sun.el.lang.ELSupport;
-import com.sun.el.lang.EvaluationContext;
-import com.sun.el.util.MessageFactory;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public abstract class SimpleNode extends ELSupport implements Node {
-    protected Node parent;
-
-    protected Node[] children;
-
-    protected int id;
-
-    protected String image;
-
-    public SimpleNode(int i) {
-        id = i;
-    }
-
-    @Override
-    public void jjtOpen() {
-    }
-
-    @Override
-    public void jjtClose() {
-    }
-
-    @Override
-    public void jjtSetParent(Node n) {
-        parent = n;
-    }
-
-    @Override
-    public Node jjtGetParent() {
-        return parent;
-    }
-
-    @Override
-    public void jjtAddChild(Node n, int i) {
-        if (children == null) {
-            children = new Node[i + 1];
-        } else if (i >= children.length) {
-            Node c[] = new Node[i + 1];
-            System.arraycopy(children, 0, c, 0, children.length);
-            children = c;
-        }
-        children[i] = n;
-    }
-
-    @Override
-    public Node jjtGetChild(int i) {
-        return children[i];
-    }
-
-    @Override
-    public int jjtGetNumChildren() {
-        return (children == null) ? 0 : children.length;
-    }
-
-    /*
-     * You can override these two methods in subclasses of SimpleNode to customize the way the node appears when the tree is
-     * dumped. If your output uses more than one line you should override toString(String), otherwise overriding toString()
-     * is probably all you need to do.
-     */
-
-    @Override
-    public String toString() {
-        if (this.image != null) {
-            return ELParserTreeConstants.jjtNodeName[id] + "[" + this.image + "]";
-        }
-        return ELParserTreeConstants.jjtNodeName[id];
-    }
-
-    public String toString(String prefix) {
-        return prefix + toString();
-    }
-
-    /*
-     * Override this method if you want to customize how the node dumps out its children.
-     */
-
-    public void dump(String prefix) {
-        System.out.println(toString(prefix));
-        if (children != null) {
-            for (int i = 0; i < children.length; ++i) {
-                SimpleNode n = (SimpleNode) children[i];
-                if (n != null) {
-                    n.dump(prefix + " ");
-                }
-            }
-        }
-    }
-
-    @Override
-    public String getImage() {
-        return image;
-    }
-
-    public void setImage(String image) {
-        this.image = image;
-    }
-
-    @Override
-    public Class getType(EvaluationContext ctx) throws ELException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Object getValue(EvaluationContext ctx) throws ELException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ValueReference getValueReference(EvaluationContext ctx) throws ELException {
-        return null;
-    }
-
-    @Override
-    public boolean isReadOnly(EvaluationContext ctx) throws ELException {
-        return true;
-    }
-
-    @Override
-    public void setValue(EvaluationContext ctx, Object value) throws ELException {
-        throw new PropertyNotWritableException(MessageFactory.get("error.syntax.set"));
-    }
-
-    @Override
-    public void accept(NodeVisitor visitor) throws ELException {
-        visitor.visit(this);
-        if (this.children != null && this.children.length > 0) {
-            for (int i = 0; i < this.children.length; i++) {
-                this.children[i].accept(visitor);
-            }
-        }
-    }
-
-    @Override
-    public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes) throws ELException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean equals(Object node) {
-        if (!(node instanceof SimpleNode)) {
-            return false;
-        }
-        SimpleNode n = (SimpleNode) node;
-        if (this.id != n.id) {
-            return false;
-        }
-        if (this.children == null && n.children == null) {
-            if (this.image == null) {
-                return n.image == null;
-            }
-            return this.image.equals(n.image);
-        }
-        if (this.children == null || n.children == null) {
-            // One is null and the other is non-null
-            return false;
-        }
-        if (this.children.length != n.children.length) {
-            return false;
-        }
-        if (this.children.length == 0) {
-            if (this.image == null) {
-                return n.image == null;
-            }
-            return this.image.equals(n.image);
-        }
-        for (int i = 0; i < this.children.length; i++) {
-            if (!this.children[i].equals(n.children[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean isParametersProvided() {
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        if (this.children == null || this.children.length == 0) {
-            if (this.image != null) {
-                return this.image.hashCode();
-            }
-            return this.id;
-        }
-        int h = 0;
-        for (int i = this.children.length - 1; i >= 0; i--) {
-            h = h + h + h + this.children[i].hashCode();
-        }
-        h = h + h + h + id;
-        return h;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/parser/Token.java b/impl/src/main/java/com/sun/el/parser/Token.java
deleted file mode 100644
index 54eab3e..0000000
--- a/impl/src/main/java/com/sun/el/parser/Token.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-import java.io.Serializable;
-
-/**
- * Describes the input token stream.
- */
-
-public class Token implements Serializable {
-
-    /**
-     * An integer that describes the kind of this token. This numbering system is determined by JavaCCParser, and a table of
-     * these numbers is stored in the file ...Constants.java.
-     */
-    public int kind;
-
-    /**
-     * beginLine and beginColumn describe the position of the first character of this token; endLine and endColumn describe
-     * the position of the last character of this token.
-     */
-    public int beginLine, beginColumn, endLine, endColumn;
-
-    /**
-     * The string image of the token.
-     */
-    public String image;
-
-    /**
-     * A reference to the next regular (non-special) token from the input stream. If this is the last token from the input
-     * stream, or if the token manager has not read tokens beyond this one, this field is set to null. This is true only if
-     * this token is also a regular token. Otherwise, see below for a description of the contents of this field.
-     */
-    public Token next;
-
-    /**
-     * This field is used to access special tokens that occur prior to this token, but after the immediately preceding
-     * regular (non-special) token. If there are no such special tokens, this field is set to null. When there are more than
-     * one such special token, this field refers to the last of these special tokens, which in turn refers to the next
-     * previous special token through its specialToken field, and so on until the first special token (whose specialToken
-     * field is null). The next fields of special tokens refer to other special tokens that immediately follow it (without
-     * an intervening regular token). If there is no such token, this field is null.
-     */
-    public Token specialToken;
-
-    /**
-     * Returns the image.
-     */
-    @Override
-    public String toString() {
-        return image;
-    }
-
-    /**
-     * Returns a new Token object, by default. However, if you want, you can create and return subclass objects based on the
-     * value of ofKind. Simply add the cases to the switch for all those special cases. For example, if you have a subclass
-     * of Token called IDToken that you want to create if ofKind is ID, simlpy add something like :
-     *
-     * case MyParserConstants.ID : return new IDToken();
-     *
-     * to the following switch statement. Then you can cast matchedToken variable to the appropriate type and use it in your
-     * lexical actions.
-     */
-    public static final Token newToken(int ofKind) {
-        switch (ofKind) {
-        default:
-            return new Token();
-        }
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/parser/TokenMgrError.java b/impl/src/main/java/com/sun/el/parser/TokenMgrError.java
deleted file mode 100644
index ae39207..0000000
--- a/impl/src/main/java/com/sun/el/parser/TokenMgrError.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.parser;
-
-public class TokenMgrError extends Error {
-    /*
-     * Ordinals for various reasons why an Error of this type can be thrown.
-     */
-
-    /**
-     * Lexical error occured.
-     */
-    static final int LEXICAL_ERROR = 0;
-
-    /**
-     * An attempt wass made to create a second instance of a static token manager.
-     */
-    static final int STATIC_LEXER_ERROR = 1;
-
-    /**
-     * Tried to change to an invalid lexical state.
-     */
-    static final int INVALID_LEXICAL_STATE = 2;
-
-    /**
-     * Detected (and bailed out of) an infinite loop in the token manager.
-     */
-    static final int LOOP_DETECTED = 3;
-
-    /**
-     * Indicates the reason why the exception is thrown. It will have one of the above 4 values.
-     */
-    int errorCode;
-
-    /**
-     * Replaces unprintable characters by their espaced (or unicode escaped) equivalents in the given string
-     */
-    protected static final String addEscapes(String str) {
-        StringBuffer retval = new StringBuffer();
-        char ch;
-        for (int i = 0; i < str.length(); i++) {
-            switch (str.charAt(i)) {
-            case 0:
-                continue;
-            case '\b':
-                retval.append("\\b");
-                continue;
-            case '\t':
-                retval.append("\\t");
-                continue;
-            case '\n':
-                retval.append("\\n");
-                continue;
-            case '\f':
-                retval.append("\\f");
-                continue;
-            case '\r':
-                retval.append("\\r");
-                continue;
-            case '\"':
-                retval.append("\\\"");
-                continue;
-            case '\'':
-                retval.append("\\\'");
-                continue;
-            case '\\':
-                retval.append("\\\\");
-                continue;
-            default:
-                if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                    String s = "0000" + Integer.toString(ch, 16);
-                    retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-                } else {
-                    retval.append(ch);
-                }
-                continue;
-            }
-        }
-        return retval.toString();
-    }
-
-    /**
-     * Returns a detailed message for the Error when it is thrown by the token manager to indicate a lexical error.
-     * Parameters : EOFSeen : indicates if EOF caused the lexicl error curLexState : lexical state in which this error
-     * occured errorLine : line number when the error occured errorColumn : column number when the error occured errorAfter
-     * : prefix that was seen before this error occured curchar : the offending character Note: You can customize the
-     * lexical error message by modifying this method.
-     */
-    protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
-        return ("Lexical error at line " + errorLine + ", column " + errorColumn + ".  Encountered: "
-                + (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int) curChar + "), ") + "after : \""
-                + addEscapes(errorAfter) + "\"");
-    }
-
-    /**
-     * You can also modify the body of this method to customize your error messages. For example, cases like LOOP_DETECTED
-     * and INVALID_LEXICAL_STATE are not of end-users concern, so you can return something like :
-     *
-     * "Internal Error : Please file a bug report .... "
-     *
-     * from this method for such cases in the release version of your parser.
-     */
-    @Override
-    public String getMessage() {
-        return super.getMessage();
-    }
-
-    /*
-     * Constructors of various flavors follow.
-     */
-
-    public TokenMgrError() {
-    }
-
-    public TokenMgrError(String message, int reason) {
-        super(message);
-        errorCode = reason;
-    }
-
-    public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
-        this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/stream/Operator.java b/impl/src/main/java/com/sun/el/stream/Operator.java
deleted file mode 100644
index 4793ce3..0000000
--- a/impl/src/main/java/com/sun/el/stream/Operator.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.stream;
-
-import java.util.Iterator;
-
-interface Operator {
-
-    Iterator<Object> iterator(Iterator<Object> upstream);
-}
diff --git a/impl/src/main/java/com/sun/el/stream/Optional.java b/impl/src/main/java/com/sun/el/stream/Optional.java
deleted file mode 100644
index 2ea52b6..0000000
--- a/impl/src/main/java/com/sun/el/stream/Optional.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.stream;
-
-import javax.el.LambdaExpression;
-
-public class Optional {
-
-    private final static Optional EMPTY = new Optional();
-    private final Object value;
-
-    Optional(Object value) {
-        if (value == null) {
-            throw new NullPointerException();
-        }
-        this.value = value;
-    }
-
-    Optional() {
-        this.value = null;
-    }
-
-    public boolean isPresent() {
-        return value != null;
-    }
-
-    public void ifPresent(LambdaExpression lambda) {
-        if (value != null) {
-            lambda.invoke(value);
-        }
-    }
-
-    public Object get() {
-        if (value == null) {
-            throw new java.util.NoSuchElementException("No value present");
-        }
-        return value;
-    }
-
-    public Object orElse(Object other) {
-        return value != null ? value : other;
-    }
-
-    public Object orElseGet(LambdaExpression other) {
-        return value != null ? value : other.invoke();
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/stream/Stream.java b/impl/src/main/java/com/sun/el/stream/Stream.java
deleted file mode 100644
index 9091271..0000000
--- a/impl/src/main/java/com/sun/el/stream/Stream.java
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.stream;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.PriorityQueue;
-import java.util.Set;
-
-import javax.el.ELException;
-import javax.el.LambdaExpression;
-
-import com.sun.el.lang.ELArithmetic;
-import com.sun.el.lang.ELSupport;
-
-/*
- */
-
-public class Stream {
-
-    private Iterator<Object> source;
-    private Stream upstream;
-    private Operator op;
-
-    Stream(Iterator<Object> source) {
-        this.source = source;
-    }
-
-    Stream(Stream upstream, Operator op) {
-        this.upstream = upstream;
-        this.op = op;
-    }
-
-    public Iterator<Object> iterator() {
-        if (source != null) {
-            return source;
-        }
-
-        return op.iterator(upstream.iterator());
-    }
-
-    public Stream filter(final LambdaExpression predicate) {
-        return new Stream(this, new Operator() {
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> upstream) {
-                return new Iterator2(upstream) {
-                    @Override
-                    public void doItem(Object item) {
-                        if ((Boolean) predicate.invoke(item)) {
-                            yield(item);
-                        }
-                    }
-                };
-            }
-        });
-    }
-
-    public Stream map(final LambdaExpression mapper) {
-        return new Stream(this, new Operator() {
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> up) {
-                return new Iterator1(up) {
-                    @Override
-                    public Object next() {
-                        return mapper.invoke(iter.next());
-                    }
-                };
-            }
-        });
-    }
-
-    public Stream peek(final LambdaExpression comsumer) {
-        return new Stream(this, new Operator() {
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> up) {
-                return new Iterator2(up) {
-                    @Override
-                    void doItem(Object item) {
-                        comsumer.invoke(item);
-                        yield(item);
-                    }
-                };
-            }
-        });
-    }
-
-    public Stream limit(final long n) {
-        if (n < 0) {
-            throw new IllegalArgumentException("limit must be non-negative");
-        }
-        return new Stream(this, new Operator() {
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> up) {
-                return new Iterator0() {
-                    long limit = n;
-
-                    @Override
-                    public boolean hasNext() {
-                        return (limit > 0) ? up.hasNext() : false;
-                    }
-
-                    @Override
-                    public Object next() {
-                        limit--;
-                        return up.next();
-                    }
-                };
-            }
-        });
-    }
-
-    public Stream substream(final long startIndex) {
-        if (startIndex < 0) {
-            throw new IllegalArgumentException("substream index must be non-negative");
-        }
-        return new Stream(this, new Operator() {
-            long skip = startIndex;
-
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> up) {
-                while (skip > 0 && up.hasNext()) {
-                    up.next();
-                    skip--;
-                }
-                return up;
-            }
-        });
-    }
-
-    public Stream substream(long startIndex, long endIndex) {
-        return substream(startIndex).limit(endIndex - startIndex);
-    }
-
-    public Stream distinct() {
-        return new Stream(this, new Operator() {
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> up) {
-                return new Iterator2(up) {
-                    private Set<Object> set = new HashSet<Object>();
-
-                    @Override
-                    public void doItem(Object item) {
-                        if (set.add(item)) {
-                            yield(item);
-                        }
-                    }
-                };
-            }
-        });
-    }
-
-    public Stream sorted() {
-        return new Stream(this, new Operator() {
-
-            private PriorityQueue<Object> queue = null;
-
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> up) {
-                if (queue == null) {
-                    queue = new PriorityQueue<Object>(16, new Comparator<Object>() {
-                        @Override
-                        public int compare(Object o1, Object o2) {
-                            return ((Comparable) o1).compareTo(o2);
-                        }
-                    });
-
-                    while (up.hasNext()) {
-                        queue.add(up.next());
-                    }
-                }
-
-                return new Iterator0() {
-                    @Override
-                    public boolean hasNext() {
-                        return !queue.isEmpty();
-                    }
-
-                    @Override
-                    public Object next() {
-                        return queue.remove();
-                    }
-                };
-            }
-        });
-    }
-
-    public Stream sorted(final LambdaExpression comparator) {
-        return new Stream(this, new Operator() {
-
-            private PriorityQueue<Object> queue = null;
-
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> up) {
-                if (queue == null) {
-                    queue = new PriorityQueue<Object>(16, new Comparator<Object>() {
-                        @Override
-                        public int compare(Object o1, Object o2) {
-                            return (Integer) ELSupport.coerceToType(comparator.invoke(o1, o2), Integer.class);
-                        }
-                    });
-
-                    while (up.hasNext()) {
-                        queue.add(up.next());
-                    }
-                }
-
-                return new Iterator0() {
-                    @Override
-                    public boolean hasNext() {
-                        return !queue.isEmpty();
-                    }
-
-                    @Override
-                    public Object next() {
-                        return queue.remove();
-                    }
-                };
-            }
-        });
-    }
-
-    public Stream flatMap(final LambdaExpression mapper) {
-        return new Stream(this, new Operator() {
-            @Override
-            public Iterator<Object> iterator(final Iterator<Object> upstream) {
-                return new Iterator0() {
-                    Iterator<Object> iter = null;
-
-                    @Override
-                    public boolean hasNext() {
-                        while (true) {
-                            if (iter == null) {
-                                if (!upstream.hasNext()) {
-                                    return false;
-                                }
-                                Object mapped = mapper.invoke(upstream.next());
-                                if (!(mapped instanceof Stream)) {
-                                    throw new ELException("Expecting a Stream " + "from flatMap's mapper function.");
-                                }
-                                iter = ((Stream) mapped).iterator();
-                            } else {
-                                if (iter.hasNext()) {
-                                    return true;
-                                }
-                                iter = null;
-                            }
-                        }
-                    }
-
-                    @Override
-                    public Object next() {
-                        if (iter == null) {
-                            return null;
-                        }
-                        return iter.next();
-                    }
-                };
-            }
-        });
-    }
-
-    public Object reduce(Object base, LambdaExpression op) {
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            base = op.invoke(base, iter.next());
-        }
-        return base;
-    }
-
-    public Optional reduce(LambdaExpression op) {
-        Iterator<Object> iter = iterator();
-        if (iter.hasNext()) {
-            Object base = iter.next();
-            while (iter.hasNext()) {
-                base = op.invoke(base, iter.next());
-            }
-            return new Optional(base);
-        }
-        return new Optional();
-    }
-
-    /*
-     * public Map<Object,Object> reduceBy(LambdaExpression classifier, LambdaExpression seed, LambdaExpression reducer) {
-     * Map<Object,Object> map = new HashMap<Object,Object>(); Iterator<Object> iter = iterator(); while (iter.hasNext()) {
-     * Object item = iter.next(); Object key = classifier.invoke(item); Object value = map.get(key); if (value == null) {
-     * value = seed.invoke(); } map.put(key, reducer.invoke(value, item)); } return map; }
-     */
-
-    public void forEach(LambdaExpression comsumer) {
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            comsumer.invoke(iter.next());
-        }
-    }
-
-    /*
-     * public Map<Object,Collection<Object>> groupBy(LambdaExpression classifier) { Map<Object, Collection<Object>> map =
-     * new HashMap<Object, Collection<Object>>(); Iterator<Object> iter = iterator(); while (iter.hasNext()) { Object item =
-     * iter.next(); Object key = classifier.invoke(item); if (key == null) { throw new ELException("null key"); }
-     * Collection<Object> c = map.get(key); if (c == null) { c = new ArrayList<Object>(); map.put(key, c); } c.add(item); }
-     * return map; }
-     */
-    public boolean anyMatch(LambdaExpression predicate) {
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            if ((Boolean) predicate.invoke(iter.next())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean allMatch(LambdaExpression predicate) {
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            if (!(Boolean) predicate.invoke(iter.next())) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public boolean noneMatch(LambdaExpression predicate) {
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            if ((Boolean) predicate.invoke(iter.next())) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public Object[] toArray() {
-        Iterator<Object> iter = iterator();
-        ArrayList<Object> al = new ArrayList<Object>();
-        while (iter.hasNext()) {
-            al.add(iter.next());
-        }
-        return al.toArray();
-    }
-
-    public Object toList() {
-        Iterator<Object> iter = iterator();
-        ArrayList<Object> al = new ArrayList<Object>();
-        while (iter.hasNext()) {
-            al.add(iter.next());
-        }
-        return al;
-    }
-
-    /*
-     * public Object into(Object target) { if (! (target instanceof Collection)) { throw new
-     * ELException("The argument type for into operation mush be a Collection"); } Collection<Object> c =
-     * (Collection<Object>) target; Iterator<Object> iter = iterator(); while (iter.hasNext()) { c.add(iter.next()); }
-     * return c; }
-     */
-
-    public Optional findFirst() {
-        Iterator<Object> iter = iterator();
-        if (iter.hasNext()) {
-            return new Optional(iter.next());
-        } else {
-            return new Optional();
-        }
-    }
-
-    public Object sum() {
-        Number sum = Long.valueOf(0);
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            sum = ELArithmetic.add(sum, iter.next());
-        }
-        return sum;
-    }
-
-    public Object count() {
-        long count = 0;
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            count++;
-            iter.next();
-        }
-        return Long.valueOf(count);
-    }
-
-    public Optional min() {
-        Object min = null;
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            Object item = iter.next();
-            if (min == null || ELSupport.compare(min, item) > 0) {
-                min = item;
-            }
-        }
-        if (min == null) {
-            return new Optional();
-        }
-        return new Optional(min);
-    }
-
-    public Optional max() {
-        Object max = null;
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            Object item = iter.next();
-            if (max == null || ELSupport.compare(max, item) < 0) {
-                max = item;
-            }
-        }
-        if (max == null) {
-            return new Optional();
-        }
-        return new Optional(max);
-    }
-
-    public Optional min(final LambdaExpression comparator) {
-        Object min = null;
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            Object item = iter.next();
-            if (min == null || ELSupport.compare(comparator.invoke(item, min), Long.valueOf(0)) < 0) {
-                min = item;
-            }
-        }
-        if (min == null) {
-            return new Optional();
-        }
-        return new Optional(min);
-    }
-
-    public Optional max(final LambdaExpression comparator) {
-        Object max = null;
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            Object item = iter.next();
-            if (max == null || ELSupport.compare(comparator.invoke(max, item), Long.valueOf(0)) < 0) {
-                max = item;
-            }
-        }
-        if (max == null) {
-            return new Optional();
-        }
-        return new Optional(max);
-    }
-
-    public Optional average() {
-        Number sum = Long.valueOf(0);
-        long count = 0;
-        Iterator<Object> iter = iterator();
-        while (iter.hasNext()) {
-            count++;
-            sum = ELArithmetic.add(sum, iter.next());
-        }
-        if (count == 0) {
-            return new Optional();
-        }
-        return new Optional(ELArithmetic.divide(sum, count));
-    }
-
-    abstract class Iterator0 implements Iterator<Object> {
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    abstract class Iterator1 extends Iterator0 {
-
-        Iterator iter;
-
-        Iterator1(Iterator iter) {
-            this.iter = iter;
-        }
-
-        @Override
-        public boolean hasNext() {
-            return iter.hasNext();
-        }
-    }
-
-    abstract class Iterator2 extends Iterator1 {
-        private Object current;
-        private boolean yielded;
-
-        Iterator2(Iterator upstream) {
-            super(upstream);
-        }
-
-        @Override
-        public Object next() {
-            yielded = false;
-            return current;
-        }
-
-        @Override
-        public boolean hasNext() {
-            while ((!yielded) && iter.hasNext()) {
-                doItem(iter.next());
-            }
-            return yielded;
-        }
-
-        void yield(Object current) {
-            this.current = current;
-            yielded = true;
-        }
-
-        abstract void doItem(Object item);
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/stream/StreamELResolver.java b/impl/src/main/java/com/sun/el/stream/StreamELResolver.java
deleted file mode 100644
index 0963a55..0000000
--- a/impl/src/main/java/com/sun/el/stream/StreamELResolver.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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
- */
-
-package com.sun.el.stream;
-
-import java.beans.FeatureDescriptor;
-import java.lang.reflect.Array;
-import java.util.Collection;
-import java.util.Iterator;
-
-import javax.el.ELContext;
-import javax.el.ELResolver;
-
-/*
- * This ELResolver intercepts method calls to a Collections, to provide
- * support for collection operations.
- */
-
-public class StreamELResolver extends ELResolver {
-
-    @Override
-    public Object invoke(final ELContext context, final Object base, final Object method, final Class<?>[] paramTypes, final Object[] params) {
-
-        if (context == null) {
-            throw new NullPointerException();
-        }
-
-        if (base instanceof Collection) {
-            @SuppressWarnings("unchecked")
-            Collection<Object> c = (Collection<Object>) base;
-            if ("stream".equals(method) && params.length == 0) {
-                context.setPropertyResolved(true);
-                return new Stream(c.iterator());
-            }
-        }
-        if (base.getClass().isArray()) {
-            if ("stream".equals(method) && params.length == 0) {
-                context.setPropertyResolved(true);
-                return new Stream(arrayIterator(base));
-            }
-        }
-        return null;
-    }
-
-    private static Iterator<Object> arrayIterator(final Object base) {
-        final int size = Array.getLength(base);
-        return new Iterator<Object>() {
-            int index = 0;
-            boolean yielded;
-            Object current;
-
-            @Override
-            public boolean hasNext() {
-                if ((!yielded) && index < size) {
-                    current = Array.get(base, index++);
-                    yielded = true;
-                }
-                return yielded;
-            }
-
-            @Override
-            public Object next() {
-                yielded = false;
-                return current;
-            }
-
-            @Override
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
-    }
-
-    /*
-     * private LambdaExpression getLambda(Object obj, String method) { if (obj == null || ! (obj instanceof
-     * LambdaExpression)) { throw new ELException ("When calling " + method + ", expecting an " +
-     * "EL lambda expression, but found " + obj); } return (LambdaExpression) obj; }
-     */
-    @Override
-    public Object getValue(ELContext context, Object base, Object property) {
-        return null;
-    }
-
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property) {
-        return null;
-    }
-
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object value) {
-    }
-
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property) {
-        return false;
-    }
-
-    @Override
-    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
-        return null;
-    }
-
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base) {
-        return String.class;
-    }
-}
diff --git a/impl/src/main/java/com/sun/el/util/MessageFactory.java b/impl/src/main/java/com/sun/el/util/MessageFactory.java
deleted file mode 100644
index 356124b..0000000
--- a/impl/src/main/java/com/sun/el/util/MessageFactory.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.util;
-
-import java.text.MessageFormat;
-import java.util.ResourceBundle;
-
-/**
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public final class MessageFactory {
-
-    protected final static ResourceBundle bundle = ResourceBundle.getBundle("com.sun.el.Messages");
-
-    /**
-     *
-     */
-    public MessageFactory() {
-        super();
-    }
-
-    public static String get(final String key) {
-        return bundle.getString(key);
-    }
-
-    public static String get(final String key, final Object obj0) {
-        return getArray(key, new Object[] { obj0 });
-    }
-
-    public static String get(final String key, final Object obj0, final Object obj1) {
-        return getArray(key, new Object[] { obj0, obj1 });
-    }
-
-    public static String get(final String key, final Object obj0, final Object obj1, final Object obj2) {
-        return getArray(key, new Object[] { obj0, obj1, obj2 });
-    }
-
-    public static String get(final String key, final Object obj0, final Object obj1, final Object obj2, final Object obj3) {
-        return getArray(key, new Object[] { obj0, obj1, obj2, obj3 });
-    }
-
-    public static String get(final String key, final Object obj0, final Object obj1, final Object obj2, final Object obj3, final Object obj4) {
-        return getArray(key, new Object[] { obj0, obj1, obj2, obj3, obj4 });
-    }
-
-    public static String getArray(final String key, final Object[] objA) {
-        return MessageFormat.format(bundle.getString(key), objA);
-    }
-
-}
diff --git a/impl/src/main/java/com/sun/el/util/ReflectionUtil.java b/impl/src/main/java/com/sun/el/util/ReflectionUtil.java
deleted file mode 100644
index 3e4e48e..0000000
--- a/impl/src/main/java/com/sun/el/util/ReflectionUtil.java
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * Copyright (c) 1997, 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.el.util;
-
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.MethodNotFoundException;
-import javax.el.PropertyNotFoundException;
-
-import com.sun.el.lang.ELSupport;
-
-/**
- * Utilities for Managing Serialization and Reflection
- *
- * @author Jacob Hookom [jacob@hookom.net]
- * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
- */
-public class ReflectionUtil {
-
-    protected static final String[] EMPTY_STRING = new String[0];
-
-    protected static final String[] PRIMITIVE_NAMES = new String[] { "boolean", "byte", "char", "double", "float", "int", "long", "short", "void" };
-
-    protected static final Class[] PRIMITIVES = new Class[] { boolean.class, byte.class, char.class, double.class, float.class, int.class, long.class,
-            short.class, Void.TYPE };
-
-    /**
-     *
-     */
-    private ReflectionUtil() {
-        super();
-    }
-
-    public static Class forName(String name) throws ClassNotFoundException {
-        if (null == name || "".equals(name)) {
-            return null;
-        }
-        Class c = forNamePrimitive(name);
-        if (c == null) {
-            if (name.endsWith("[]")) {
-                String nc = name.substring(0, name.length() - 2);
-                c = Class.forName(nc, true, Thread.currentThread().getContextClassLoader());
-                c = Array.newInstance(c, 0).getClass();
-            } else {
-                c = Class.forName(name, true, Thread.currentThread().getContextClassLoader());
-            }
-        }
-        return c;
-    }
-
-    protected static Class forNamePrimitive(String name) {
-        if (name.length() <= 8) {
-            int p = Arrays.binarySearch(PRIMITIVE_NAMES, name);
-            if (p >= 0) {
-                return PRIMITIVES[p];
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Converts an array of Class names to Class types
-     *
-     * @param s
-     * @return The array of Classes
-     * @throws ClassNotFoundException
-     */
-    public static Class[] toTypeArray(String[] s) throws ClassNotFoundException {
-        if (s == null) {
-            return null;
-        }
-        Class[] c = new Class[s.length];
-        for (int i = 0; i < s.length; i++) {
-            c[i] = forName(s[i]);
-        }
-        return c;
-    }
-
-    /**
-     * Converts an array of Class types to Class names
-     *
-     * @param c
-     * @return The array of Classes
-     */
-    public static String[] toTypeNameArray(Class[] c) {
-        if (c == null) {
-            return null;
-        }
-        String[] s = new String[c.length];
-        for (int i = 0; i < c.length; i++) {
-            s[i] = c[i].getName();
-        }
-        return s;
-    }
-
-    /**
-     * @param base The base object
-     * @param property The property
-     * @return The PropertyDescriptor for the base with the given property
-     * @throws ELException
-     * @throws PropertyNotFoundException
-     */
-    public static PropertyDescriptor getPropertyDescriptor(Object base, Object property) throws ELException, PropertyNotFoundException {
-        String name = ELSupport.coerceToString(property);
-        PropertyDescriptor p = null;
-        try {
-            PropertyDescriptor[] desc = Introspector.getBeanInfo(base.getClass()).getPropertyDescriptors();
-            for (int i = 0; i < desc.length; i++) {
-                if (desc[i].getName().equals(name)) {
-                    return desc[i];
-                }
-            }
-        } catch (IntrospectionException ie) {
-            throw new ELException(ie);
-        }
-        throw new PropertyNotFoundException(MessageFactory.get("error.property.notfound", base, name));
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    public static Object invokeMethod(ELContext context, Method m, Object base, Object[] params) {
-
-        Object[] parameters = buildParameters(context, m.getParameterTypes(), m.isVarArgs(), params);
-        try {
-            return m.invoke(base, parameters);
-        } catch (IllegalAccessException iae) {
-            throw new ELException(iae);
-        } catch (IllegalArgumentException iae) {
-            throw new ELException(iae);
-        } catch (InvocationTargetException ite) {
-            throw new ELException(ite.getCause());
-        }
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    public static Method findMethod(Class<?> clazz, String methodName, Class<?>[] paramTypes, Object[] paramValues) {
-
-        if (clazz == null || methodName == null) {
-            throw new MethodNotFoundException(MessageFactory.get("error.method.notfound", clazz, methodName, paramString(paramTypes)));
-        }
-
-        if (paramTypes == null) {
-            paramTypes = getTypesFromValues(paramValues);
-        }
-
-        Method[] methods = clazz.getMethods();
-
-        List<Wrapper> wrappers = Wrapper.wrap(methods, methodName);
-
-        Wrapper result = findWrapper(clazz, wrappers, methodName, paramTypes, paramValues);
-
-        if (result == null) {
-            return null;
-        }
-        return getMethod(clazz, (Method) result.unWrap());
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static Wrapper findWrapper(Class<?> clazz, List<Wrapper> wrappers, String name, Class<?>[] paramTypes, Object[] paramValues) {
-
-        List<Wrapper> assignableCandidates = new ArrayList<Wrapper>();
-        List<Wrapper> coercibleCandidates = new ArrayList<Wrapper>();
-        List<Wrapper> varArgsCandidates = new ArrayList<Wrapper>();
-
-        int paramCount;
-        if (paramTypes == null) {
-            paramCount = 0;
-        } else {
-            paramCount = paramTypes.length;
-        }
-
-        for (Wrapper w : wrappers) {
-            Class<?>[] mParamTypes = w.getParameterTypes();
-            int mParamCount;
-            if (mParamTypes == null) {
-                mParamCount = 0;
-            } else {
-                mParamCount = mParamTypes.length;
-            }
-
-            // Check the number of parameters
-            if (!(paramCount == mParamCount || (w.isVarArgs() && paramCount >= mParamCount - 1))) {
-                // Method has wrong number of parameters
-                continue;
-            }
-
-            // Check the parameters match
-            boolean assignable = false;
-            boolean coercible = false;
-            boolean varArgs = false;
-            boolean noMatch = false;
-            for (int i = 0; i < mParamCount; i++) {
-                if (i == (mParamCount - 1) && w.isVarArgs()) {
-                    varArgs = true;
-                    // exact var array type match
-                    if (mParamCount == paramCount) {
-                        if (mParamTypes[i] == paramTypes[i]) {
-                            continue;
-                        }
-                    }
-
-                    // unwrap the array's component type
-                    Class<?> varType = mParamTypes[i].getComponentType();
-                    for (int j = i; j < paramCount; j++) {
-                        if (!isAssignableFrom(paramTypes[j], varType)
-                                && !(paramValues != null && j < paramValues.length && isCoercibleFrom(paramValues[j], varType))) {
-                            noMatch = true;
-                            break;
-                        }
-                    }
-                } else if (mParamTypes[i].equals(paramTypes[i])) {
-                } else if (isAssignableFrom(paramTypes[i], mParamTypes[i])) {
-                    assignable = true;
-                } else {
-                    if (paramValues == null || i >= paramValues.length) {
-                        noMatch = true;
-                        break;
-                    } else {
-                        if (isCoercibleFrom(paramValues[i], mParamTypes[i])) {
-                            coercible = true;
-                        } else {
-                            noMatch = true;
-                            break;
-                        }
-                    }
-                }
-            }
-            if (noMatch) {
-                continue;
-            }
-
-            if (varArgs) {
-                varArgsCandidates.add(w);
-            } else if (coercible) {
-                coercibleCandidates.add(w);
-            } else if (assignable) {
-                assignableCandidates.add(w);
-            } else {
-                // If a method is found where every parameter matches exactly,
-                // return it
-                return w;
-            }
-
-        }
-
-        String errorMsg = MessageFactory.get("error.method.ambiguous", clazz, name, paramString(paramTypes));
-        if (!assignableCandidates.isEmpty()) {
-            return findMostSpecificWrapper(assignableCandidates, paramTypes, false, errorMsg);
-        } else if (!coercibleCandidates.isEmpty()) {
-            return findMostSpecificWrapper(coercibleCandidates, paramTypes, true, errorMsg);
-        } else if (!varArgsCandidates.isEmpty()) {
-            return findMostSpecificWrapper(varArgsCandidates, paramTypes, true, errorMsg);
-        } else {
-            throw new MethodNotFoundException(MessageFactory.get("error.method.notfound", clazz, name, paramString(paramTypes)));
-        }
-
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static Wrapper findMostSpecificWrapper(List<Wrapper> candidates, Class<?>[] matchingTypes, boolean elSpecific, String errorMsg) {
-        List<Wrapper> ambiguouses = new ArrayList<Wrapper>();
-        for (Wrapper candidate : candidates) {
-            boolean lessSpecific = false;
-
-            Iterator<Wrapper> it = ambiguouses.iterator();
-            while (it.hasNext()) {
-                int result = isMoreSpecific(candidate, it.next(), matchingTypes, elSpecific);
-                if (result == 1) {
-                    it.remove();
-                } else if (result == -1) {
-                    lessSpecific = true;
-                }
-            }
-
-            if (!lessSpecific) {
-                ambiguouses.add(candidate);
-            }
-        }
-
-        if (ambiguouses.size() > 1) {
-            throw new MethodNotFoundException(errorMsg);
-        }
-
-        return ambiguouses.get(0);
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static int isMoreSpecific(Wrapper wrapper1, Wrapper wrapper2, Class<?>[] matchingTypes, boolean elSpecific) {
-        Class<?>[] paramTypes1 = wrapper1.getParameterTypes();
-        Class<?>[] paramTypes2 = wrapper2.getParameterTypes();
-
-        if (wrapper1.isVarArgs()) {
-            // JLS8 15.12.2.5 Choosing the Most Specific Method
-            int length = Math.max(Math.max(paramTypes1.length, paramTypes2.length), matchingTypes.length);
-            paramTypes1 = getComparingParamTypesForVarArgsMethod(paramTypes1, length);
-            paramTypes2 = getComparingParamTypesForVarArgsMethod(paramTypes2, length);
-
-            if (length > matchingTypes.length) {
-                Class<?>[] matchingTypes2 = new Class<?>[length];
-                System.arraycopy(matchingTypes, 0, matchingTypes2, 0, matchingTypes.length);
-                matchingTypes = matchingTypes2;
-            }
-        }
-
-        int result = 0;
-        for (int i = 0; i < paramTypes1.length; i++) {
-            if (paramTypes1[i] != paramTypes2[i]) {
-                int r2 = isMoreSpecific(paramTypes1[i], paramTypes2[i], matchingTypes[i], elSpecific);
-                if (r2 == 1) {
-                    if (result == -1) {
-                        return 0;
-                    }
-                    result = 1;
-                } else if (r2 == -1) {
-                    if (result == 1) {
-                        return 0;
-                    }
-                    result = -1;
-                } else {
-                    return 0;
-                }
-            }
-        }
-
-        if (result == 0) {
-            // The nature of bridge methods is such that it actually
-            // doesn't matter which one we pick as long as we pick
-            // one. That said, pick the 'right' one (the non-bridge
-            // one) anyway.
-            result = Boolean.compare(wrapper1.isBridge(), wrapper2.isBridge());
-        }
-
-        return result;
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static int isMoreSpecific(Class<?> type1, Class<?> type2, Class<?> matchingType, boolean elSpecific) {
-        type1 = getBoxingTypeIfPrimitive(type1);
-        type2 = getBoxingTypeIfPrimitive(type2);
-        if (type2.isAssignableFrom(type1)) {
-            return 1;
-        } else if (type1.isAssignableFrom(type2)) {
-            return -1;
-        } else {
-            if (elSpecific) {
-                /*
-                 * Number will be treated as more specific
-                 *
-                 * ASTInteger only return Long or BigInteger, no Byte / Short / Integer. ASTFloatingPoint also.
-                 *
-                 */
-                if (matchingType != null && Number.class.isAssignableFrom(matchingType)) {
-                    boolean b1 = Number.class.isAssignableFrom(type1) || type1.isPrimitive();
-                    boolean b2 = Number.class.isAssignableFrom(type2) || type2.isPrimitive();
-                    if (b1 && !b2) {
-                        return 1;
-                    } else if (b2 && !b1) {
-                        return -1;
-                    } else {
-                        return 0;
-                    }
-                }
-
-                return 0;
-            } else {
-                return 0;
-            }
-        }
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static Class<?> getBoxingTypeIfPrimitive(Class<?> clazz) {
-        if (clazz.isPrimitive()) {
-            if (clazz == Boolean.TYPE) {
-                return Boolean.class;
-            } else if (clazz == Character.TYPE) {
-                return Character.class;
-            } else if (clazz == Byte.TYPE) {
-                return Byte.class;
-            } else if (clazz == Short.TYPE) {
-                return Short.class;
-            } else if (clazz == Integer.TYPE) {
-                return Integer.class;
-            } else if (clazz == Long.TYPE) {
-                return Long.class;
-            } else if (clazz == Float.TYPE) {
-                return Float.class;
-            } else {
-                return Double.class;
-            }
-        } else {
-            return clazz;
-        }
-
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static Class<?>[] getComparingParamTypesForVarArgsMethod(Class<?>[] paramTypes, int length) {
-        Class<?>[] result = new Class<?>[length];
-        System.arraycopy(paramTypes, 0, result, 0, paramTypes.length - 1);
-        Class<?> type = paramTypes[paramTypes.length - 1].getComponentType();
-        for (int i = paramTypes.length - 1; i < length; i++) {
-            result[i] = type;
-        }
-
-        return result;
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static final String paramString(Class<?>[] types) {
-        if (types != null) {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < types.length; i++) {
-                if (types[i] == null) {
-                    sb.append("null, ");
-                } else {
-                    sb.append(types[i].getName()).append(", ");
-                }
-            }
-            if (sb.length() > 2) {
-                sb.setLength(sb.length() - 2);
-            }
-            return sb.toString();
-        }
-        return null;
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    static boolean isAssignableFrom(Class<?> src, Class<?> target) {
-        // src will always be an object
-        // Short-cut. null is always assignable to an object and in EL null
-        // can always be coerced to a valid value for a primitive
-        if (src == null) {
-            return true;
-        }
-
-        target = getBoxingTypeIfPrimitive(target);
-
-        return target.isAssignableFrom(src);
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static boolean isCoercibleFrom(Object src, Class<?> target) {
-        // TODO: This isn't pretty but it works. Significant refactoring would
-        // be required to avoid the exception.
-        try {
-            ELSupport.coerceToType(src, target);
-        } catch (Exception e) {
-            return false;
-        }
-        return true;
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static Class<?>[] getTypesFromValues(Object[] values) {
-        if (values == null) {
-            return null;
-        }
-
-        Class<?> result[] = new Class<?>[values.length];
-        for (int i = 0; i < values.length; i++) {
-            if (values[i] == null) {
-                result[i] = null;
-            } else {
-                result[i] = values[i].getClass();
-            }
-        }
-        return result;
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     *
-     * Get a public method form a public class or interface of a given method. Note that if a PropertyDescriptor is obtained
-     * for a non-public class that implements a public interface, the read/write methods will be for the class, and
-     * therefore inaccessible. To correct this, a version of the same method must be found in a superclass or interface.
-     *
-     */
-    static Method getMethod(Class<?> type, Method m) {
-        if (m == null || Modifier.isPublic(type.getModifiers())) {
-            return m;
-        }
-        Class<?>[] inf = type.getInterfaces();
-        Method mp = null;
-        for (int i = 0; i < inf.length; i++) {
-            try {
-                mp = inf[i].getMethod(m.getName(), m.getParameterTypes());
-                mp = getMethod(mp.getDeclaringClass(), mp);
-                if (mp != null) {
-                    return mp;
-                }
-            } catch (NoSuchMethodException e) {
-                // Ignore
-            }
-        }
-        Class<?> sup = type.getSuperclass();
-        if (sup != null) {
-            try {
-                mp = sup.getMethod(m.getName(), m.getParameterTypes());
-                mp = getMethod(mp.getDeclaringClass(), mp);
-                if (mp != null) {
-                    return mp;
-                }
-            } catch (NoSuchMethodException e) {
-                // Ignore
-            }
-        }
-        return null;
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    static Constructor<?> getConstructor(Class<?> type, Constructor<?> c) {
-        if (c == null || Modifier.isPublic(type.getModifiers())) {
-            return c;
-        }
-        Constructor<?> cp = null;
-        Class<?> sup = type.getSuperclass();
-        if (sup != null) {
-            try {
-                cp = sup.getConstructor(c.getParameterTypes());
-                cp = getConstructor(cp.getDeclaringClass(), cp);
-                if (cp != null) {
-                    return cp;
-                }
-            } catch (NoSuchMethodException e) {
-                // Ignore
-            }
-        }
-        return null;
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    static Object[] buildParameters(ELContext context, Class<?>[] parameterTypes, boolean isVarArgs, Object[] params) {
-        Object[] parameters = null;
-        if (parameterTypes.length > 0) {
-            parameters = new Object[parameterTypes.length];
-            int paramCount = params == null ? 0 : params.length;
-            if (isVarArgs) {
-                int varArgIndex = parameterTypes.length - 1;
-                // First argCount-1 parameters are standard
-                for (int i = 0; (i < varArgIndex && i < paramCount); i++) {
-                    parameters[i] = context.convertToType(params[i], parameterTypes[i]);
-                }
-                // Last parameter is the varargs
-                if (parameterTypes.length == paramCount && parameterTypes[varArgIndex] == params[varArgIndex].getClass()) {
-                    parameters[varArgIndex] = params[varArgIndex];
-                } else {
-                    Class<?> varArgClass = parameterTypes[varArgIndex].getComponentType();
-                    final Object varargs = Array.newInstance(varArgClass, (paramCount - varArgIndex));
-                    for (int i = (varArgIndex); i < paramCount; i++) {
-                        Array.set(varargs, i - varArgIndex, context.convertToType(params[i], varArgClass));
-                    }
-                    parameters[varArgIndex] = varargs;
-                }
-            } else {
-                for (int i = 0; i < parameterTypes.length && i < paramCount; i++) {
-                    parameters[i] = context.convertToType(params[i], parameterTypes[i]);
-                }
-            }
-        }
-        return parameters;
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private abstract static class Wrapper {
-
-        public static List<Wrapper> wrap(Method[] methods, String name) {
-            List<Wrapper> result = new ArrayList<>();
-            for (Method method : methods) {
-                if (method.getName().equals(name)) {
-                    result.add(new MethodWrapper(method));
-                }
-            }
-            return result;
-        }
-
-        public static List<Wrapper> wrap(Constructor<?>[] constructors) {
-            List<Wrapper> result = new ArrayList<>();
-            for (Constructor<?> constructor : constructors) {
-                result.add(new ConstructorWrapper(constructor));
-            }
-            return result;
-        }
-
-        public abstract Object unWrap();
-
-        public abstract Class<?>[] getParameterTypes();
-
-        public abstract boolean isVarArgs();
-
-        public abstract boolean isBridge();
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static class MethodWrapper extends Wrapper {
-        private final Method m;
-
-        public MethodWrapper(Method m) {
-            this.m = m;
-        }
-
-        @Override
-        public Object unWrap() {
-            return m;
-        }
-
-        @Override
-        public Class<?>[] getParameterTypes() {
-            return m.getParameterTypes();
-        }
-
-        @Override
-        public boolean isVarArgs() {
-            return m.isVarArgs();
-        }
-
-        @Override
-        public boolean isBridge() {
-            return m.isBridge();
-        }
-    }
-
-    /*
-     * This method duplicates code in javax.el.ELUtil. When making changes keep the code in sync.
-     */
-    private static class ConstructorWrapper extends Wrapper {
-        private final Constructor<?> c;
-
-        public ConstructorWrapper(Constructor<?> c) {
-            this.c = c;
-        }
-
-        @Override
-        public Object unWrap() {
-            return c;
-        }
-
-        @Override
-        public Class<?>[] getParameterTypes() {
-            return c.getParameterTypes();
-        }
-
-        @Override
-        public boolean isVarArgs() {
-            return c.isVarArgs();
-        }
-
-        @Override
-        public boolean isBridge() {
-            return false;
-        }
-    }
-
-}
diff --git a/parent-pom/pom.xml b/parent-pom/pom.xml
deleted file mode 100644
index 26c74f5..0000000
--- a/parent-pom/pom.xml
+++ /dev/null
@@ -1,150 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 1997, 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
-
--->
-
-<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>
-    <groupId>org.glassfish.web</groupId>
-    <artifactId>el</artifactId>
-    <version>2.2.1-SNAPSHOT</version>
-    <packaging>pom</packaging>
-    <name>Expression Language related modules</name>
-
-    <properties>
-        <findbugs.version>2.3.1</findbugs.version>
-        <findbugs.exclude />
-        <findbugs.threshold>High</findbugs.threshold>
-    </properties>
-
-    <build>
-        <plugins>
-            <plugin>
-                <artifactId>maven-compiler-plugin</artifactId>
-                    <configuration>
-                        <source>1.5</source>
-                        <target>1.5</target>
-                    </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-source-plugin</artifactId>
-                <version> 2.1 </version>
-                <configuration>
-                    <includePom>true</includePom>
-                </configuration>
-                <executions>
-                    <execution>
-                       <id>attach-sources</id>
-                       <goals>
-                           <goal>jar-no-fork</goal> 
-                       </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-              <groupId>org.apache.maven.plugins</groupId>
-              <artifactId>maven-javadoc-plugin</artifactId>
-              <executions>
-                  <execution>
-                      <id>attach-javadocs</id>
-                      <goals>
-                          <goal>jar</goal>
-                      </goals>
-                 </execution>
-              </executions>
-           </plugin>
-           <plugin>
-              <groupId>org.codehaus.mojo</groupId>
-              <artifactId>findbugs-maven-plugin</artifactId>
-              <version>${findbugs.version}</version>
-              <configuration>
-                  <threshold>${findbugs.threshold}</threshold>
-                  <excludeFilterFile>${findbugs.exclude}</excludeFilterFile>
-                  <findbugsXmlOutput>true</findbugsXmlOutput>
-                  <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
-              </configuration>
-           </plugin>
-        </plugins>
-        <extensions>
-            <extension>
-                <groupId>org.jvnet.wagon-svn</groupId>
-                <artifactId>wagon-svn</artifactId>
-                <version>1.12</version>
-            </extension>
-            <extension>
-                 <groupId>org.apache.maven.wagon</groupId>
-                 <artifactId>wagon-webdav</artifactId>
-                 <version>1.0-beta-2</version>
-            </extension> 
-        </extensions>
-    </build>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>findbugs-maven-plugin</artifactId>
-                <version>2.1</version>
-                <configuration>
-                    <threshold>High</threshold>
-                    <excludeFilterFile>${findbugs.exclude}</excludeFilterFile>
-                </configuration>
-            </plugin>
-        </plugins>
-    </reporting>
-
-    <scm>
-        <connection>scm:svn:svn+ssh://janey@svn.java.net/uel~svn/trunk</connection>
-        <developerConnection>scm:svn:svn+ssh://janey@svn.java.net/uel~svn/trunk</developerConnection>
-        <url>svn+ssh://janey@svn.java.net/uel~svn/trunk/</url>
-    </scm>
-
-    <repositories>
-        <repository>
-            <id>glassfish-repository</id>
-            <url>http://download.java.net/maven/glassfish</url>
-        </repository>
-        <repository>
-            <id>maven2-repository.dev.java.net</id>
-            <name>Java.net Repository for Maven</name>
-            <url>http://download.java.net/maven/2</url>
-        </repository>
-    </repositories>
-    <pluginRepositories>
-        <pluginRepository>
-            <id>glassfish-repository</id>
-            <name>Java.net Repository for Maven 2</name>
-            <url>http://download.java.net/maven/glassfish</url>
-            <snapshots>
-                <updatePolicy>never</updatePolicy>
-            </snapshots>
-        </pluginRepository>
-    </pluginRepositories>
-    <distributionManagement>
-        <site>
-            <id>java.net-el</id>
-            <url>java-net:/uel~svn/trunk/repo/</url>
-        </site>
-        <repository>
-            <uniqueVersion>false</uniqueVersion>
-            <id>java.net-maven2-repository</id>
-            <url>java-net:/maven2-repository~svn/trunk/repository/</url>
-        </repository>
-    </distributionManagement>
-</project>
-
diff --git a/spec/README.md b/spec/README.md
deleted file mode 100644
index 70f25b2..0000000
--- a/spec/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-Jakarta Expression Language Specification
-============================
-
-This project generates the Jakarta Expression Language Specification.
-
-Building
---------
-
-Prerequisites:
-
-* JDK8+
-* Maven 3.0.3+
-
-Run the full build:
-
-`mvn install`
-
-Locate the html files:
-- `target/generated-docs/expression-language-spec-<version>.html`
-
-Locate the PDF files:
-- `target/generated-docs/expression-language-spec-<version>.pdf`
diff --git a/spec/assembly.xml b/spec/assembly.xml
deleted file mode 100644
index 7f30954..0000000
--- a/spec/assembly.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!--
- 
-    Copyright (c) 2019 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
- 
--->
-
-<assembly>
-    <id>spec</id>
-    <formats>
-    <format>zip</format>
-    </formats>
-    <baseDirectory>expression-language-spec</baseDirectory>
-    <fileSets>
-        <fileSet>
-            <directory>target/generated-docs</directory>
-            <outputDirectory></outputDirectory>
-        </fileSet>
-    </fileSets>
-</assembly>
diff --git a/spec/pom.xml b/spec/pom.xml
deleted file mode 100644
index 56ecc77..0000000
--- a/spec/pom.xml
+++ /dev/null
@@ -1,176 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2019 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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
-    
-    <parent>
-        <groupId>org.eclipse.ee4j</groupId>
-        <artifactId>project</artifactId>
-        <version>1.0.5</version>
-        <relativePath/>
-    </parent>
-    
-    <groupId>org.eclipse.ee4j.expression-language</groupId>
-    <artifactId>expression-language-spec</artifactId>
-    <packaging>pom</packaging>
-    <name>Jakarta Expression Language Specification</name>
-
-    <properties>
-        <site.output.dir>${project.build.directory}/staging</site.output.dir>
-        <maven.site.skip>true</maven.site.skip>
-        <asciidoctor.maven.plugin.version>1.5.7.1</asciidoctor.maven.plugin.version>
-        <asciidoctorj.version>1.6.2</asciidoctorj.version>
-        <asciidoctorj.pdf.version>1.5.0-alpha.16</asciidoctorj.pdf.version>
-        <jruby.version>9.2.6.0</jruby.version>
-        <!-- status: DRAFT, BETA, etc., or blank for final -->
-        <status>DRAFT</status>
-        <maven.build.timestamp.format>MMMM dd, yyyy</maven.build.timestamp.format>
-        <revisiondate>${maven.build.timestamp}</revisiondate>
-    </properties>
-
-    <build>
-        <defaultGoal>package</defaultGoal>
-        <plugins>
-            <plugin>
-                <groupId>org.asciidoctor</groupId>
-                <artifactId>asciidoctor-maven-plugin</artifactId>
-                <version>${asciidoctor.maven.plugin.version}</version>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.jruby</groupId>
-                        <artifactId>jruby-complete</artifactId>
-                        <version>${jruby.version}</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.asciidoctor</groupId>
-                        <artifactId>asciidoctorj</artifactId>
-                        <version>${asciidoctorj.version}</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.asciidoctor</groupId>
-                        <artifactId>asciidoctorj-pdf</artifactId>
-                        <version>${asciidoctorj.pdf.version}</version>
-                    </dependency>
-                </dependencies>
-                <executions>
-                    <execution>
-                        <id>asciidoc-to-html</id>
-                        <phase>generate-resources</phase>
-                        <goals>
-                            <goal>process-asciidoc</goal>
-                        </goals>
-                        <configuration>
-                            <backend>html5</backend>
-                            <outputFile>${project.build.directory}/generated-docs/expression-language-spec-${project.version}.html</outputFile>
-                            <attributes>
-                                <doctype>book</doctype>
-                                <status>${status}</status>
-                                <data-uri />
-                                <icons>font</icons>
-                                <toc>left</toc>
-                                <icons>font</icons>
-                                <sectanchors>true</sectanchors>
-                                <idprefix />
-                                <idseparator>-</idseparator>
-                                <docinfo1>true</docinfo1>
-                            </attributes>
-                        </configuration>
-                    </execution>
-                    <execution>
-                        <id>asciidoc-to-pdf</id>
-                        <phase>generate-resources</phase>
-                        <goals>
-                            <goal>process-asciidoc</goal>
-                        </goals>
-                        <configuration>
-                            <backend>pdf</backend>
-                            <outputFile>${project.build.directory}/generated-docs/expression-language-spec-${project.version}.pdf</outputFile>
-                            <attributes>
-                                <pdf-stylesdir>${project.basedir}/src/main/theme</pdf-stylesdir>
-                                <pdf-style>jakartaee</pdf-style>
-                                <doctype>book</doctype>
-                                <status>${status}</status>
-                                <data-uri />
-                                <icons>font</icons>
-                                <pagenums />
-                                <toc />
-                                <icons>font</icons>
-                                <sectanchors>true</sectanchors>
-                                <idprefix />
-                                <idseparator>-</idseparator>
-                                <docinfo1>true</docinfo1>
-                                <embedAssets>true</embedAssets>
-                            </attributes>
-                        </configuration>
-                    </execution>
-                </executions>
-                <configuration>
-                    <sourceDocumentName>expression-language-spec.adoc</sourceDocumentName>
-                    <sourceHighlighter>coderay</sourceHighlighter>
-                    <attributes>
-                        <revnumber>${project.version}</revnumber>
-                        <revremark>${status}</revremark>
-                        <revdate>${revisiondate}</revdate>
-                    </attributes>
-                </configuration>
-            </plugin>
-            
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-release-plugin</artifactId>
-                <version>2.5.2</version>
-                <configuration>
-                    <mavenExecutorId>forked-path</mavenExecutorId>
-                    <useReleaseProfile>false</useReleaseProfile>
-                    <arguments>${release.arguments}</arguments>
-                </configuration>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.apache.maven.scm</groupId>
-                        <artifactId>maven-scm-provider-gitexe</artifactId>
-                        <version>1.9.4</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-
-            <!--
-                This is the rule that builds the zip file for download.
-            -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-assembly-plugin</artifactId>
-                <version>3.1.1</version>
-                <inherited>false</inherited>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>single</goal>
-                        </goals>
-                        <configuration>
-                            <appendAssemblyId>false</appendAssemblyId>
-                            <descriptors>
-                                <descriptor>assembly.xml</descriptor>
-                            </descriptors>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/spec/src/main/asciidoc/expression-language-spec.adoc b/spec/src/main/asciidoc/expression-language-spec.adoc
deleted file mode 100644
index 7af1bc8..0000000
--- a/spec/src/main/asciidoc/expression-language-spec.adoc
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (c) 2017, 2019 Contributors to the Eclipse Foundation
-//
-
-= Jakarta Expression Language 3.0
-:authors: Jakarta Expression Language Team, https://projects.eclipse.org/projects/ee4j.el
-:email: https://dev.eclipse.org/mailman/listinfo/el-dev
-:version-label!:
-:doctype: book
-:license: Eclipse Foundation Specification License v1.0
-:source-highlighter: coderay
-:toc: left
-:toclevels: 4
-:sectnumlevels: 4
-:sectanchors:
-ifdef::backend-pdf[]
-:pagenums:
-:numbered:
-:title-logo-image: image:jakarta_ee_logo_schooner_color_stacked_default.png[pdfwidth=4.25in,align=right]
-endif::[]
-
-// == License
-:sectnums!:
-include::license-efsl.adoc[]
-
-// == Scope
-:sectnums:
-include::scope.adoc[]
diff --git a/spec/src/main/asciidoc/images/jakarta_ee_logo_schooner_color_stacked_default.png b/spec/src/main/asciidoc/images/jakarta_ee_logo_schooner_color_stacked_default.png
deleted file mode 100644
index 97b46ce..0000000
--- a/spec/src/main/asciidoc/images/jakarta_ee_logo_schooner_color_stacked_default.png
+++ /dev/null
Binary files differ
diff --git a/spec/src/main/asciidoc/license-efsl.adoc b/spec/src/main/asciidoc/license-efsl.adoc
deleted file mode 100644
index 855fc87..0000000
--- a/spec/src/main/asciidoc/license-efsl.adoc
+++ /dev/null
@@ -1,72 +0,0 @@
-[subs="normal"]
-....
-Specification: {doctitle}
-
-Version: {revnumber}
-
-Status: {revremark}
-
-Release: {revdate}
-....
-
-=== Eclipse Foundation Specification License
-
-By using and/or copying this document, or the Eclipse Foundation
-document from which this statement is linked, you (the licensee) agree
-that you have read, understood, and will comply with the following
-terms and conditions:
-
-Permission to copy, and distribute the contents of this document, or
-the Eclipse Foundation document from which this statement is linked, in
-any medium for any purpose and without fee or royalty is hereby
-granted, provided that you include the following on ALL copies of the
-document, or portions thereof, that you use:
-
-* link or URL to the original Eclipse Foundation document.
-* All existing copyright notices, or if one does not exist, a notice
-  (hypertext is preferred, but a textual representation is permitted)
-  of the form: "Copyright (c) [$date-of-document]
-  Eclipse Foundation, Inc. <<url to this license>>"
-
-Inclusion of the full text of this NOTICE must be provided. We
-request that authorship attribution be provided in any software,
-documents, or other items or products that you create pursuant to the
-implementation of the contents of this document, or any portion
-thereof.
-
-No right to create modifications or derivatives of Eclipse Foundation
-documents is granted pursuant to this license, except anyone may
-prepare and distribute derivative works and portions of this document
-in software that implements the specification, in supporting materials
-accompanying such software, and in documentation of such software,
-PROVIDED that all such works include the notice below. HOWEVER, the
-publication of derivative works of this document for use as a technical
-specification is expressly prohibited.
-
-The notice is:
-
-"Copyright (c) 2018 Eclipse Foundation. This software or
-document includes material copied from or derived from [title and URI
-of the Eclipse Foundation specification document]."
-
-==== Disclaimers
-
-THIS DOCUMENT IS PROVIDED &quot;AS IS,&quot; AND THE COPYRIGHT
-HOLDERS AND THE ECLIPSE FOUNDATION MAKE NO REPRESENTATIONS OR
-WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
-NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE
-SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS
-WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR
-OTHER RIGHTS.
-
-THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION WILL NOT BE LIABLE
-FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT
-OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE
-CONTENTS THEREOF.
-
-The name and trademarks of the copyright holders or the Eclipse
-Foundation may NOT be used in advertising or publicity pertaining to
-this document or its contents without specific, written prior
-permission. Title to copyright in this document will at all times
-remain with copyright holders.
diff --git a/spec/src/main/asciidoc/scope.adoc b/spec/src/main/asciidoc/scope.adoc
deleted file mode 100644
index 196b43c..0000000
--- a/spec/src/main/asciidoc/scope.adoc
+++ /dev/null
@@ -1,3 +0,0 @@
-== Specification Scope
-
-Jakarta Expression Language provides a specification document, API, reference implementation and TCK that describes an expression language for Java applications.
diff --git a/spec/src/main/theme/jakartaee-theme.yml b/spec/src/main/theme/jakartaee-theme.yml
deleted file mode 100644
index 6092a2f..0000000
--- a/spec/src/main/theme/jakartaee-theme.yml
+++ /dev/null
@@ -1,299 +0,0 @@
-#
-# 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/src/assembly/assembly.xml b/src/assembly/assembly.xml
deleted file mode 100644
index 8780af6..0000000
--- a/src/assembly/assembly.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<!--
-
-    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
-
--->
-
-<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
-
-    <id>el-sources</id>
-    <formats>
-        <format>zip</format>
-    </formats>
-
-    <fileSets>
-        <fileSet>
-            <directory>${project.basedir}</directory>
-            <outputDirectory>/</outputDirectory>
-            <excludes>
-                <exclude>spec/**</exclude>
-                <exclude>fonts/**</exclude>
-                <exclude>target/**</exclude>
-                <exclude>api/target/**</exclude>
-                <exclude>src/assembly/**</exclude>
-            </excludes>
-        </fileSet>
-        <fileSet>
-            <outputDirectory>/</outputDirectory>
-            <directory>${project.build.directory}/license</directory>
-        </fileSet>
-    </fileSets>
-</assembly>             
diff --git a/src/test/java/org/glassfish/el/test/ConvertTest.java b/src/test/java/org/glassfish/el/test/ConvertTest.java
deleted file mode 100644
index 814e924..0000000
--- a/src/test/java/org/glassfish/el/test/ConvertTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-import javax.el.*;
-
-/**
- *
- * @author kichung
- */
-public class ConvertTest {
-    ELProcessor elp;
-
-    public ConvertTest() {
-    }
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws Exception {
-    }
-
-    @Before
-    public void setUp() {
-        elp = new ELProcessor();
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    static public class MyBean {
-        String name;
-        int pint;
-        Integer integer;
-
-        MyBean() {
-
-        }
-        MyBean(String name) {
-            this.name = name;
-        }
-        public String getName() {
-            return this.name;
-        }
-        public void setPint(int v) {
-            this.pint = v;
-        }
-        public int getPint() {
-            return this.pint;
-        }
-
-        public void setInteger(Integer i){
-            this.integer = i;
-        }
-
-        public Integer getInteger() {
-            return this.integer;
-        }
-    }
-    @Test
-    public void testVoid() {
-        MyBean bean = new MyBean();
-        elp.defineBean("bean", bean);
-        // Assig null to int is 0;
-        Object obj = elp.eval("bean.pint = null");
-        assertEquals(obj, null);
-        assertEquals(bean.getPint(), 0);
-
-        // Assig null to Integer is null
-        elp.setValue("bean.integer", null);
-        assertEquals(bean.getInteger(), null);
-    }
-
-    @Test
-    public void testCustom() {
-        elp.getELManager().addELResolver(new TypeConverter() {
-            @Override
-            public Object convertToType(ELContext context, Object obj, Class<?> type) {
-                if (obj instanceof String && type == MyBean.class) {
-                    context.setPropertyResolved(true);
-                    return new MyBean((String) obj);
-                }
-                return null;
-            }
-        });
-        
-        Object val = elp.getValue("'John Doe'", MyBean.class);
-        assertTrue(val instanceof MyBean);
-        assertEquals(((MyBean)val).getName(), "John Doe");
-    }
-}
diff --git a/src/test/java/org/glassfish/el/test/Customer.java b/src/test/java/org/glassfish/el/test/Customer.java
deleted file mode 100644
index 533ec01..0000000
--- a/src/test/java/org/glassfish/el/test/Customer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import java.util.List;
-import java.util.ArrayList;
-
-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/src/test/java/org/glassfish/el/test/DataBase.java b/src/test/java/org/glassfish/el/test/DataBase.java
deleted file mode 100644
index 51daab7..0000000
--- a/src/test/java/org/glassfish/el/test/DataBase.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import java.util.List;
-import java.util.ArrayList;
-
-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;
-
-    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>();
-        initCustomer();
-        initProduct();
-        initOrder();
-    }        
-
-    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/src/test/java/org/glassfish/el/test/Date.java b/src/test/java/org/glassfish/el/test/Date.java
deleted file mode 100644
index f202fb2..0000000
--- a/src/test/java/org/glassfish/el/test/Date.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-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/src/test/java/org/glassfish/el/test/ELProcessorTest.java b/src/test/java/org/glassfish/el/test/ELProcessorTest.java
deleted file mode 100644
index 3381e7d..0000000
--- a/src/test/java/org/glassfish/el/test/ELProcessorTest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import org.junit.Test;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import javax.el.ELProcessor;
-import javax.el.ELManager;
-import javax.el.ExpressionFactory;
-import javax.el.MethodExpression;
-import javax.el.ELContext;
-import java.lang.reflect.Method;
-
-public class ELProcessorTest {
-
-    static ELProcessor elp;
-    static ELManager elm;
-    static ExpressionFactory factory;
-    
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-        elp = new ELProcessor();
-        elm = elp.getELManager();
-        factory = elm.getExpressionFactory();
-    }
-    
-    @Before
-    public void setUp() {
-    }
-
-    @Test
-    public void testMethExpr() {
-        MethodExpression meth = null;
-        ELContext ctxt = elm.getELContext();
-        try {
-            meth = factory.createMethodExpression(
-                ctxt, "#{str.length}", Object.class, null);
-        } catch (NullPointerException ex){
-            // Do nothing
-        }
-        assertTrue(meth == null);
-        meth = factory.createMethodExpression(
-                ctxt, "#{'abc'.length()}", Object.class, null);
-        Object result = meth.invoke(ctxt, new Object[] {"abcde"});
-        System.out.println("'abc'.length() called, equals " + result);
-        assertEquals(result, new Integer(3));
-    }
-
-    @Test
-    public void testGetValue() {
-        Object result = elp.eval("10 + 1");
-        assertEquals(result.toString(), "11");
-        result = elp.getValue("10 + 2", String.class);
-        assertEquals(result, "12");
-    }
-
-    @Test
-    public void testSetVariable () {
-        elp.setVariable("xx", "100");
-        Object result = elp.getValue("xx + 11", String.class);
-        assertEquals(result, "111");
-        elp.setVariable("xx", null);
-        assertEquals(elp.eval("xx"), null);
-        elp.setVariable("yy", "abc");
-        assertEquals(elp.eval("yy = 123; abc"), 123L);
-        assertEquals(elp.eval("abc = 456; yy"), 456L);
-    }
-
-    @Test
-    public void testConcat() {
-        Object result = elp.eval("'10' + 1");
-        assertEquals(result, 11L);
-        result = elp.eval("10 += '1'");
-        assertEquals(result.toString(), "101");
-    }
-    
-    @Test
-    public void defineFuncTest() {
-        Class c = MyBean.class;
-        Method meth = null;
-        Method meth2 = null;
-        try {
-            meth = c.getMethod("getBar", new Class<?>[] {});
-            meth2 = c.getMethod("getFoo", new Class<?>[] {});
-        } catch (Exception e) {
-            System.out.printf("Exception: ", e);
-        }
-        try {
-            elp.defineFunction("xx", "", meth);
-            Object ret = elp.eval("xx:getBar() == 64");
-            assertTrue((Boolean)ret);
-        } catch (NoSuchMethodException ex) {
-            
-        }
-        
-        boolean caught = false;
-        try {
-            elp.defineFunction("", "", meth2);
-            Object ret = elp.eval("getFoo() == 100");
-            assertTrue((Boolean)ret);
-        } catch (NoSuchMethodException ex) {
-            caught = true;
-        }
-        assertTrue(caught);
-        
-        try {
-            elp.defineFunction("yy", "", "org.glassfish.el.test.ELProcessorTest$MyBean", "getBar");
-            Object ret = elp.eval("yy:getBar() == 64");
-            assertTrue((Boolean)ret);
-        } catch (ClassNotFoundException | NoSuchMethodException ex) {
-            
-        }
-        
-        caught = false;
-        try {
-            elp.defineFunction("yy", "", "org.glassfish.el.test.ELProcessorTest$MyBean", "getFooBar");
-            Object ret = elp.eval("yy:getBar() == 100");
-            assertTrue((Boolean)ret);
-        } catch (ClassNotFoundException | NoSuchMethodException ex) {
-            caught = true;
-        }
-        assertTrue(caught);
-        
-        caught = false;
-        try {
-            elp.defineFunction("yy", "", "testBean", "getFoo");
-            Object ret = elp.eval("yy:getBar() == 100");
-            assertTrue((Boolean)ret);
-        } catch (ClassNotFoundException | NoSuchMethodException ex) {
-            caught = true;
-        }
-        assertTrue(caught);
-    }
-/*
-    @Test
-    public void testBean() {
-        elp.defineBean("xyz", new MyBean());
-        Object result = elp.eval("xyz.foo");
-        assertEquals(result.toString(), "100");
-    }
-*/
-
-    @Test
-    public void testImport() {
-        elm.importClass("org.glassfish.el.test.ELProcessorTest$MyBean");
-        assertTrue((Boolean)elp.eval("ELProcessorTest$MyBean.aaaa == 101"));
-        assertTrue((Boolean)elp.eval("ELProcessorTest$MyBean.getBar() == 64"));
-        elm.importStatic("org.glassfish.el.test.ELProcessorTest$MyBean.aaaa");
-        assertEquals(new Integer(101), elp.eval("aaaa"));
-        elm.importStatic("org.glassfish.el.test.ELProcessorTest$MyBean.getBar");
-        assertEquals(new Integer(64), elp.eval("getBar()"));
- /*
-        elm.importStatic("a.b.NonExisting.foobar");
-        elp.eval("foobar");
-        elp.eval("ELProcessorTest$MyBean.getFoo()");
-        */
-    }
-
-    static public class MyBean {
-        public static int aaaa = 101;
-        public int getFoo() {
-            return 100;
-        }
-        public int getFoo(int i) {
-            return 200;
-        }
-        public static int getBar() {
-            return 64;
-        }
-    }
-}
-
diff --git a/src/test/java/org/glassfish/el/test/ElasticityTest.java.sav b/src/test/java/org/glassfish/el/test/ElasticityTest.java.sav
deleted file mode 100644
index 3da7dce..0000000
--- a/src/test/java/org/glassfish/el/test/ElasticityTest.java.sav
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import java.util.*;
-import javax.el.*;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-/**
- *
- * @author kichung
- */
-public class ElasticityTest {
-
-    ELProcessor elp;
-
-    public ElasticityTest() {
-    }
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws Exception {
-    }
-
-    @Before
-    public void setUp() {
-        elp = new ELProcessor();
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    static public class Data {
-        int s;
-        int d;
-
-        public Data(int s, int d) {
-            this.s = s;
-            this.d = d;
-        }
-
-        public int getS() {
-            return this.s;
-        }
-
-        public int getD() {
-            return this.d;
-        }
-    }
-
-    static public class Metric {
-        int limit;
-        List<Data> list = new ArrayList<Data>();
-        
-        public Metric(int limit) {
-            this.limit = limit;
-        }
-        
-        public int getLimit() {
-            return limit;
-        }
-        
-        public List<Data> getList() {
-            return list;
-        }
-    }
-    Map<String, Metric> clusters = new HashMap<String, Metric>();
-
-    private void init() {
-        Metric m1 = new Metric(10);
-        m1.getList().add(new Data(1, 80));
-        m1.getList().add(new Data(3, 90));
-        m1.getList().add(new Data(4, 100));
-        m1.getList().add(new Data(5, 50));
-        m1.getList().add(new Data(6, 60));
-
-        Metric m2 = new Metric(10);
-        m2.getList().add(new Data(1, 80));
-        m2.getList().add(new Data(3, 82));
-        m2.getList().add(new Data(7, 90));
-        m2.getList().add(new Data(9, 140));
-        m2.getList().add(new Data(15, 80));
-
-        Metric m3 = new Metric(10);
-        m3.getList().add(new Data(4, 100));
-        m3.getList().add(new Data(5, 81));
-        m3.getList().add(new Data(6, 200));
-        m3.getList().add(new Data(20, 80));
-
-        clusters.put("c1", m1);
-        clusters.put("c2", m2);
-        clusters.put("c3", m3);
-
-        elp.defineBean("c", clusters);
-    }
-    @Test
-    public void testElaticity() {
-        init();
-        Object obj;
-        
-        obj = elp.eval(
-            "c.values().select(" +
-                "v->v.list.where(d->d.s>1 && d.s<10)." +
-                          "average(d->d.d)).toList()");
-
-        System.out.println(obj);
-        obj = elp.eval(
-            "c.values().select(v->v.list." +
-                       "where(d->d.s>1 && d.s<10)." +
-                       "average(d->d.d) > 100).toList()");
-        System.out.println(obj);
-        obj = elp.eval(
-            "c.values().select(v->v.list." +
-                       "where(d->d.s>1 && d.s<10)." +
-                       "average(d->d.d) > 100).any()");
-        System.out.println(obj);
-        obj = elp.eval(
-            "c.entrySet().select(s->[s.key, s.value.list." +
-                       "where(d->d.s>1 && d.s<10)." +
-                       "average(d->d.d)]).toList()");
-        System.out.println(obj);
-    }
-}
diff --git a/src/test/java/org/glassfish/el/test/EvalListenerTest.java b/src/test/java/org/glassfish/el/test/EvalListenerTest.java
deleted file mode 100644
index 410bde2..0000000
--- a/src/test/java/org/glassfish/el/test/EvalListenerTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import java.util.ArrayList;
-import javax.el.ELManager;
-import javax.el.ELContext;
-import javax.el.ELProcessor;
-import javax.el.EvaluationListener;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-/**
- *
- * @author kichung
- */
-public class EvalListenerTest {
-
-    public EvalListenerTest() {
-    }
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws Exception {
-    }
-
-    @Before
-    public void setUp() {
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test
-    public void testEvalListener() {
-        ELProcessor elp = new ELProcessor();
-        ELManager elm = elp.getELManager();
-        final ArrayList<String> msgs = new ArrayList<String>();
-        elm.addEvaluationListener(new EvaluationListener() {
-            @Override
-            public void beforeEvaluation(ELContext ctxt, String expr) {
-                System.out.println("Before: " + expr);
-                msgs.add("Before: " + expr);
-            }
-            @Override
-            public void afterEvaluation(ELContext ctxt, String expr) {
-                System.out.println("After: " + expr);
-                msgs.add("After: " + expr);
-            }
-        });
-        elp.eval("100 + 10");
-        elp.eval("x = 5; x*101");
-        String[] expected = {"Before: ${100 + 10}",
-            "After: ${100 + 10}",
-            "Before: ${x = 5; x*101}",
-            "After: ${x = 5; x*101}" };
-        for (int i = 0; i < expected.length; i++) {
-            assertEquals(expected[i], msgs.get(i));
-        }
-    }
-
-    @Test
-    public void testResListener() {
-        ELProcessor elp = new ELProcessor();
-        ELManager elm = elp.getELManager();
-        final ArrayList<String> msgs = new ArrayList<String>();
-        elm.addEvaluationListener(new EvaluationListener() {
-            @Override
-            public void propertyResolved(ELContext ctxt, Object b, Object p) {
-                System.out.println("Resolved: " + b + " " + p);
-                msgs.add("Resolved: " + b + " " + p);
-            }
-        });
-        elp.eval("x = 10");
-        elp.eval("[1,2,3][2]");
-        elp.eval("'abcd'.length()");
-        elp.eval("'xyz'.class");
-        String[] expected = {
-            "Resolved: null x",
-            "Resolved: [1, 2, 3] 2",
-            "Resolved: abcd length",
-            "Resolved: xyz class"
-        };
-        for (int i = 0; i < expected.length; i++) {
-            assertEquals(expected[i], msgs.get(i));
-        }
-    }
-}
diff --git a/src/test/java/org/glassfish/el/test/LambdaTest.java b/src/test/java/org/glassfish/el/test/LambdaTest.java
deleted file mode 100644
index 2734e0c..0000000
--- a/src/test/java/org/glassfish/el/test/LambdaTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import org.junit.Test;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import javax.el.ELProcessor;
-
-public class LambdaTest {
-    
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-    }
-    
-    @Before
-    public void setUp() {    
-    } 
-    
-    void testExpr(ELProcessor elp, String testname, String expr, Long expected) {
-        System.out.println("=== Test Lambda Expression:" + testname + " ===");
-        System.out.println(" ** " + expr);
-        Object result = elp.eval(expr);
-        System.out.println("    returns " + result);
-        assertEquals(expected, result);
-    }
-
-    @Test
-    public void testImmediate() {
-        ELProcessor elp = new ELProcessor();
-        testExpr(elp, "immediate", "(x->x+1)(10)", 11L);
-        testExpr(elp, "immediate0", "(()->1001)()", 1001L);
-        testExpr(elp, "immediate1", "((x,y)->x+y)(null, null)", 0L);
-        testExpr(elp, "immediate 2", "(((x,y)->x+y)(3,4))", 7L);
-        testExpr(elp, "immediate 3", "(x->(y=x)+1)(10) + y", 21L);
-    }
-
-    @Test
-    public void testAssignInvoke() {
-        ELProcessor elp = new ELProcessor();
-        testExpr(elp, "assign", "func = x->x+1; func(10)", 11L);
-        testExpr(elp, "assign 2", "func = (x,y)->x+y; func(3,4)", 7L);
-    }
-
-    @Test
-    public void testConditional() {
-        ELProcessor elp = new ELProcessor();
-        elp.eval("cond = true");
-        testExpr(elp, "conditional", "(x->cond? x+1: x+2)(10)", 11L);
-        elp.eval("cond = false");
-        testExpr(elp, "conditional 2",
-                 "func = cond? (x->x+1): (x->x+2); func(10)", 12L);
-    }
-
-    @Test
-    public void testFact() {
-        ELProcessor elp = new ELProcessor();        
-        testExpr(elp, "factorial", "fact = n->n==0? 1: n*fact(n-1); fact(5)", 120L);
-        testExpr(elp, "fibonacci", "f = n->n==0? 0: n==1? 1: f(n-1)+f(n-2); f(10)", 55L);
-    }
-
-    @Test
-    public void testVar() {
-        ELProcessor elp = new ELProcessor();
-        elp.setVariable("v", "x->x+1");
-        testExpr(elp, "assignment to variable", "v(10)", 11L);
-    }
-
-    @Test
-    public void testLambda() {
-        ELProcessor elp = new ELProcessor();
-        testExpr(elp, "Lambda Lambda", "f = ()->y->y+1; f()(100)", 101L);
-        testExpr(elp, "Lambda Lambda 2", "f = (x)->(tem=x; y->tem+y); f(1)(100)", 101L);
-        testExpr(elp, "Lambda Lambda 3", "(()->y->y+1)()(100)", 101L);
-        testExpr(elp, "Lambda Lambda 4", "(x->(y->x+y)(1))(100)", 101L);
-        testExpr(elp, "Lambda Lambda 5", "(x->(y->x+y))(1)(100)", 101L);
-        testExpr(elp, "Lambda Lambda 6"
-                , "(x->y->x(0)+y)(x->x+1)(100)", 101L);
-    }
-}
diff --git a/src/test/java/org/glassfish/el/test/OperatorTest.java b/src/test/java/org/glassfish/el/test/OperatorTest.java
deleted file mode 100644
index a9d512f..0000000
--- a/src/test/java/org/glassfish/el/test/OperatorTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import static org.junit.Assert.*;
-import javax.el.ELProcessor;
-import javax.el.ELManager;
-import javax.el.ExpressionFactory;
-import javax.el.ValueExpression;
-import javax.el.MethodExpression;
-
-/**
- *
- * @author Kin-man
- */
-public class OperatorTest {
-    
-    static ELProcessor elp;
-
-    public OperatorTest() {
-    }
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-        elp = new ELProcessor();
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws Exception {
-    }
-    
-    @Before
-    public void setUp() {
-    }
-    
-    void testExpr(String testname, String expr, Long expected) {
-        System.out.println("=== Test " + testname + " ===");
-        System.out.println(" ** " + expr);
-        Object result = elp.eval(expr);
-        System.out.println("    returns " + result);
-        assertEquals(expected, result);
-    }
-    
-    void testExpr(String testname, String expr, String expected) {
-        System.out.println("=== Test " + testname + " ===");
-        System.out.println(" ** " + expr);
-        Object result = elp.eval(expr);
-        System.out.println("    returns " + result);
-        assertEquals(expected, result);
-    }
-    
-    @Test
-    public void testConcat() {
-        testExpr("concat", "a = null; b = null; a + b", 0L);
-        testExpr("add", "10 + 11", 21L);
-        testExpr("concat", "'10' + 11", 21L);
-        testExpr("concat 2", "11 + '10'", 21L);
-        testExpr("concat 3", "100 += 10 ", "10010");
-        testExpr("concat 4", "'100' += 10", "10010");
-        testExpr("concat 5", "'100' + 10 + 1", 111L);
-        testExpr("concat 6", "'100' += 10 + 1", "10011");
-    }
-    
-    @Test
-    public void testAssign() {
-        elp.eval("vv = 10");
-        testExpr("assign", "vv+1", 11L);
-        elp.eval("vv = 100");
-        testExpr("assign 2", "vv", 100L);
-        testExpr("assign 3", "x = vv = vv+1; x + vv", 202L);
-        elp.eval("map = {'one':100, 'two':200}");
-        testExpr("assign 4", "map.two = 201; map.two", 201L);
-        testExpr("assign string", "x='string'; x += 1", "string1");
-    }
-    
-    @Test
-    public void testSemi() {
-        testExpr("semi", "10; 20", 20L);
-        testExpr("semi0", "10; 20; 30", 30L);
-        elp.eval("x = 10; 20");
-        testExpr("semi 2", "x", 10L);
-        testExpr("semi 3", "(x = 10; 20) + (x ; x+1)", 31L);
-        testExpr("semi 4", "(x = 10; y) = 11; x + y", 21L);
-    }
-    @Test
-    public void testMisc() {
-        testExpr("quote", "\"'\"", "'");
-        testExpr("quote", "'\"'", "\"");
-        ELManager elm = elp.getELManager();
-        ValueExpression v = elm.getExpressionFactory().createValueExpression(
-                elm.getELContext(), "#${1+1}", Object.class);
-        Object ret = v.getValue(elm.getELContext());
-        assertEquals(ret, "#2");
-        
-        elp.setVariable("debug", "true");
-        ret = elp.eval("debug == true");
-//        elp.eval("[1,2][true]"); // throws IllegalArgumentExpression
-/*        
-        elp.defineBean("date", new Date(2013, 1,2));
-        elp.eval("date.getYear()");
-        
-        elp.defineBean("href", null);
-        testExpr("space", "(empty href)?'#':href", "#");
-        MethodExpression m = elm.getExpressionFactory().createMethodExpression(
-                elm.getELContext(), "${name}", Object.class, new Class[] {});
-        m.invoke(elm.getELContext(), null);
-        */
-    }
-}
diff --git a/src/test/java/org/glassfish/el/test/Order.java b/src/test/java/org/glassfish/el/test/Order.java
deleted file mode 100644
index 6ebfeaf..0000000
--- a/src/test/java/org/glassfish/el/test/Order.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-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/src/test/java/org/glassfish/el/test/OverloadedMethodTest.java b/src/test/java/org/glassfish/el/test/OverloadedMethodTest.java
deleted file mode 100644
index c0a3aa4..0000000
--- a/src/test/java/org/glassfish/el/test/OverloadedMethodTest.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-import javax.el.*;
-
-/**
- *
- * @author Dongbin Nie
- */
-public class OverloadedMethodTest {
-
-    ELProcessor elp;
-    ExpressionFactory exprFactory;
-    ELContext elContext;
-
-    @Before
-    public void setUp() {
-        elp = new ELProcessor();
-        exprFactory = elp.getELManager().getExpressionFactory();
-        elContext = elp.getELManager().getELContext();
-        
-        elp.defineBean("foo", new MyBean());
-        
-        elp.defineBean("i1", new I1Impl());
-        elp.defineBean("i2", new I2Impl());
-        elp.defineBean("i12", new I1AndI2Impl());
-        elp.defineBean("i12s", new I1AndI2ImplSub());
-        
-    }
-
-    @After
-    public void tearDown() {
-    }
-    
-    @Test
-    public void testMethodWithNoArg() {
-        assertEquals("methodWithNoArg", elp.eval("foo.methodWithNoArg()"));
-    }
-    
-    @Test
-    public void testMethodNotExisted() {
-        try {
-            elp.eval("foo.methodNotExisted()");
-            fail("testNoExistedMethod Failed");
-        } catch (MethodNotFoundException e) {
-        }
-    }
-    
-    @Test
-    public void testMethodWithSingleArg() {
-        assertEquals("I1", elp.eval("foo.methodWithSingleArg(i1)"));
-        assertEquals("I2Impl", elp.eval("foo.methodWithSingleArg(i2)"));
-        assertEquals("I1AndI2Impl", elp.eval("foo.methodWithSingleArg(i12)"));
-    }
-    
-    @Test
-    public void testMethodWithDoubleArgs() {
-        assertEquals("I1Impl, I2", elp.eval("foo.methodWithDoubleArgs(i1, i2)"));
-        assertEquals("I1, I2", elp.eval("foo.methodWithDoubleArgs(i12, i2)"));
-        assertEquals("I1AndI2Impl, I1AndI2Impl", elp.eval("foo.methodWithDoubleArgs(i12, i12)"));
-        assertEquals("I1AndI2Impl, I1AndI2Impl", elp.eval("foo.methodWithDoubleArgs(i12s, i12)"));
-        assertEquals("I1AndI2Impl, I1AndI2Impl", elp.eval("foo.methodWithDoubleArgs(i12s, i12s)"));
-    }
-    
-    @Test
-    public void testMethodWithAmbiguousArgs() {
-        assertEquals("I1AndI2Impl, I2", elp.eval("foo.methodWithAmbiguousArgs(i12, i2)"));
-        assertEquals("I1, I1AndI2Impl", elp.eval("foo.methodWithAmbiguousArgs(i1, i12)"));
-        try {
-            elp.eval("foo.methodWithAmbiguousArgs(i12, i12)");
-            fail("testMethodWithAmbiguousArgs Failed");
-        } catch (MethodNotFoundException e) {
-        }
-    }
-    
-    @Test
-    public void testMethodWithCoercibleArgs() {
-        assertEquals("String, String", elp.eval("foo.methodWithCoercibleArgs('foo', 'bar')"));
-        assertEquals("String, String", elp.eval("foo.methodWithCoercibleArgs(i1, i12)"));
-        
-        assertEquals("String, String", elp.eval("foo.methodWithCoercibleArgs2(i1, 12345678)"));
-        assertEquals("Integer, Integer", elp.eval("foo.methodWithCoercibleArgs2(12345678, 12345678)"));
-    }
-    
-    @Test
-    public void testMethodWithVarArgs() {
-        assertEquals("I1, I1...", elp.eval("foo.methodWithVarArgs(i1)"));
-        assertEquals("I1, I1...", elp.eval("foo.methodWithVarArgs(i1, i1)"));
-        assertEquals("I1, I1...", elp.eval("foo.methodWithVarArgs(i12, i1, i12)"));
-        
-        assertEquals("I1, I1AndI2Impl...", elp.eval("foo.methodWithVarArgs2(i1)"));
-        assertEquals("I1, I1AndI2Impl...", elp.eval("foo.methodWithVarArgs2(i12)"));
-        assertEquals("I1, I1...", elp.eval("foo.methodWithVarArgs2(i1, i1)"));
-        assertEquals("I1, I1AndI2Impl...", elp.eval("foo.methodWithVarArgs2(i1, i12)"));
-    }
-    
-    @Test
-    public void testExactVarArgs() {
-        String[] args = {"foo", "bar", "hello"};
-        elp.defineBean("args", args);
-        assertEquals("foo,bar,hello,", elp.eval("foo.methodWithExactVarArgs('foo', 'bar', 'hello')"));
-        assertEquals("foo,foo,bar,hello,", elp.eval("foo.methodWithExactVarArgs('foo', args)"));
-    }
-    
-    @Test
-    public void testMethodInStdout() {
-        elp.defineBean("out", System.out);
-        elp.eval("out.println('hello!')");
-        elp.eval("out.println(12345678)");
-    }
-    
-    /**
-     * JSF may invoke MethodExpression which has parameter declared,
-     * but pass in no arguments (not null). 
-     */
-    @Test
-    public void testMethodExprInvokingWithoutArgs() {
-        MethodExpression methodExpr = exprFactory.createMethodExpression(
-                elContext, 
-                "${foo.methodForMethodExpr}", 
-                String.class, 
-                new Class<?>[]{String.class});
-        
-        assertNull(methodExpr.invoke(elContext, new Object[0]));
-    }
-    
-    @Test
-    public void testMethodExprInvoking() {
-        MethodExpression methodExpr = exprFactory.createMethodExpression(
-                elContext, 
-                "${foo.methodForMethodExpr2}", 
-                String.class, 
-                new Class<?>[]{Runnable.class});
-        assertEquals("Runnable", methodExpr.invoke(elContext, new Object[]{Thread.currentThread()}));
-        try {
-            methodExpr.invoke(elContext, new Object[]{"foo"});
-            fail("testMethodExprInvoking Failed");
-        } catch (ELException e) {
-            System.out.println("The following is an expected exception:");
-            e.printStackTrace(System.out);
-        }
-    }
-    
-    
-    public static interface I1 {
-    
-    }
-    
-    public static interface I2 {
-    
-    }
-    
-    public static class I1Impl implements I1 {
-    
-    }
-    
-    public static class I2Impl implements I2 {
-    
-    }
-    
-    public static class I1AndI2Impl implements I1, I2 {
-    
-    }
-    
-    public static class I1AndI2ImplSub extends I1AndI2Impl {
-    
-    }
-
-    static public class MyBean {
-
-        public String methodWithNoArg() {
-            return "methodWithNoArg";
-        }
-
-        public String methodWithSingleArg(I1 i1) {
-            return "I1";
-        }
-
-        public String methodWithSingleArg(I2 i2) {
-            return "I2";
-        }
-
-        public String methodWithSingleArg(I2Impl i2) {
-            return "I2Impl";
-        }
-
-        public String methodWithSingleArg(I1AndI2Impl i1) {
-            return "I1AndI2Impl";
-        }
-
-        public String methodWithDoubleArgs(I1 i1, I2 i2) {
-            return "I1, I2";
-        }
-
-        public String methodWithDoubleArgs(I1Impl i1, I2 i2) {
-            return "I1Impl, I2";
-        }
-
-        public String methodWithDoubleArgs(I1AndI2Impl i1, I1AndI2Impl i2) {
-            return "I1AndI2Impl, I1AndI2Impl";
-        }
-
-        public String methodWithAmbiguousArgs(I1AndI2Impl i1, I2 i2) {
-            return "I1AndI2Impl, I2";
-        }
-
-        public String methodWithAmbiguousArgs(I1 i1, I1AndI2Impl i2) {
-            return "I1, I1AndI2Impl";
-        }
-
-        public String methodWithCoercibleArgs(String s1, String s2) {
-            return "String, String";
-        }
-
-        public String methodWithCoercibleArgs2(String s1, String s2) {
-            return "String, String";
-        }
-
-        public String methodWithCoercibleArgs2(Integer s1, Integer s2) {
-            return "Integer, Integer";
-        }
-
-        public String methodWithVarArgs(I1 i1, I1... i2) {
-            return "I1, I1...";
-        }
-
-        public String methodWithVarArgs2(I1 i1, I1... i2) {
-            return "I1, I1...";
-        }
-
-        public String methodWithVarArgs2(I1 i1, I1AndI2Impl... i2) {
-            return "I1, I1AndI2Impl...";
-        }
-        
-        public String methodWithExactVarArgs(String arg1, String... args) {
-            StringBuilder sb = new StringBuilder();
-            sb.append(arg1).append(",");
-            for (String arg : args) {
-                sb.append(arg).append(",");
-            }
-            return sb.toString();
-        }
-        
-        public String methodForMethodExpr(String arg1) {
-            return arg1;
-        }
-        
-        public String methodForMethodExpr2(Runnable r) {
-            return "Runnable";
-        }
-        
-        public String methodForMethodExpr2(String s) {
-            return "String";
-        }
-
-    }
-    
-}
diff --git a/src/test/java/org/glassfish/el/test/Product.java b/src/test/java/org/glassfish/el/test/Product.java
deleted file mode 100644
index 72d9cd5..0000000
--- a/src/test/java/org/glassfish/el/test/Product.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-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/src/test/java/org/glassfish/el/test/StaticRefTest.java b/src/test/java/org/glassfish/el/test/StaticRefTest.java
deleted file mode 100644
index 4c8df7b..0000000
--- a/src/test/java/org/glassfish/el/test/StaticRefTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import static org.junit.Assert.*;
-
-import javax.el.*;
-
-/**
- *
- * @author kichung
- */
-public class StaticRefTest {
-
-    ELProcessor elp;
-
-    public StaticRefTest() {
-    }
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-    }
-
-    @AfterClass
-    public static void tearDownClass() throws Exception {
-    }
-
-    @Before
-    public void setUp() {
-        elp = new ELProcessor();
-    }
-
-    @After
-    public void tearDown() {
-    }
-
-    @Test
-    public void testStaticRef() {
-        // Pre imported java.lang classes
-//        assertTrue((Boolean)elp.eval("T(java.lang.Boolean).TRUE"));
-//        assertTrue((Boolean)elp.eval("T(Boolean).TRUE"));
-        assertTrue((Boolean)elp.eval("Boolean.TRUE"));
-        assertTrue((Boolean)elp.eval("Boolean.TRUE"));  // test caching Boolean
-    }
-
-/*
-    @Test
-    public void testClass() {
-        assertEquals(String.class, elp.eval("String.class"));
-    }
-*/
-
-    @Test
-    public void testConstructor() {
-//        assertEquals(new Integer(1001), elp.eval("T(Integer)(1001)"));
-        assertEquals(new Integer(1001), elp.eval("Integer(1001)"));
-    }
-
-    @Test
-    public void testStaticMethod() {
-        assertEquals(4, elp.eval("Integer.numberOfTrailingZeros(16)"));
-    }
-}
diff --git a/src/test/java/org/glassfish/el/test/StreamTest.java b/src/test/java/org/glassfish/el/test/StreamTest.java
deleted file mode 100644
index c37c71e..0000000
--- a/src/test/java/org/glassfish/el/test/StreamTest.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * 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 org.glassfish.el.test;
-
-import java.lang.reflect.Array;
-import java.util.List;
-import java.util.Map;
-import java.util.Iterator;
-
-import org.junit.Test;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import javax.el.ELProcessor;
-import javax.el.ELException;
-
-public class StreamTest {
-
-    static ELProcessor elp;
-    static DataBase database = null;
-
-    @BeforeClass
-    public static void setUpClass() throws Exception {
-        elp = new ELProcessor();
-        database = new DataBase();
-        database.init();
-        elp.defineBean("customers", database.getCustomers());
-        elp.defineBean("products", database.getProducts());
-        elp.defineBean("orders", database.getOrders());
-    }
-
-    @Before
-    public void setup() {
-    }
-
-    void p(String msg) {
-        System.out.println(msg);
-    }
-    /**
-     * Test a collection query that returns an array, list or Iterable.
-     * @param name of the test
-     * @param query The EL query string
-     * @param expected The expected result of the array, list or Iterable.
-     *     The array element should equal the elements in the array, list or
-     *     Iterable, when enumerated.
-     */
-    void testStream(String name, String query, String[] expected) {
-        p("=== Testing " + name + " ===");
-        p(query);
-        Object ret = elp.eval(query);
-        p(" = returns =");
-
-        if (ret.getClass().isArray()) {
-            int size = Array.getLength(ret);
-            assertTrue(size == expected.length);
-            for (int i = 0; i < size; i++) {
-                Object item = Array.get(ret, i);
-                p(" " + item.toString());
-                assertEquals(item.toString(), expected[i]);
-            }
-            return;
-        }
-
-        if (ret instanceof List) {
-            List<Object> list = (List<Object>) ret;
-            int i = 0;
-            for (Object item: list) {
-                p(" " + item.toString());
-                assertEquals(item.toString(), expected[i++]); 
-            }
-            assertTrue(i == expected.length);
-            return;
-        }
-
-        if (ret instanceof Iterator) {
-            int i = 0;
-            Iterator<Object> iter = (Iterator<Object>) ret;
-            while (iter.hasNext()) {
-                Object item = iter.next();
-                p(" " + item.toString());
-                assertEquals(item.toString(), expected[i++]);
-            }
-            assertTrue(i == expected.length);
-            return;
-        }
-
-        // unexpected return type
-        assertTrue(false);
-    }
-
-    void testStream(String name, String query, Object expected) {
-        p("=== Testing " + name + " ===");
-        p(query);
-        Object ret = elp.eval(query);
-        p(" = returns " + ret  + "(" + ret.getClass() + ")");
-        assertEquals(ret, expected);
-        p("");
-    }
-
-    static String[] exp0 = {"1", "2", "3", "4", "5", "6"};
-    static String[] exp1 = {"6", "5", "4", "3", "2", "1"};
-    static String[] exp2 = {"q", "z", "yz", "aaa", "abc", "xyz"};
-    static String[] exp3 = {"2", "3", "4"};
-    static String[] exp4 = {"20", "30", "40"};
-
-    @Test
-    public void testFilterMap() {
-        testStream("filter", "[1,2,3,4].stream().filter(i->i > 1).toList()", exp3);
-        testStream("map", "[2,3,4].stream().map(i->i*10).iterator()", exp4);
-        testStream("filtermap", "[1,2,3,4].stream().filter(i->i > 1)\n" +
-                                "                  .map(i->i*10).toArray()", exp4);
-    }
-
-    static String[] exp5 = {
-        "Product: 201, Coming Home, dvd, 8.0, 50",
-        "Product: 200, Eagle, book, 12.5, 100",
-        "Product: 202, Greatest Hits, cd, 6.5, 200",
-        "Product: 203, History of Golf, book, 11.0, 30",
-        "Product: 204, Toy Story, dvd, 10.0, 1000",
-        "Product: 205, iSee, book, 12.5, 150"};
-
-    static String[] exp6 = {
-        "Product: 203, History of Golf, book, 11.0, 30",
-        "Product: 200, Eagle, book, 12.5, 100",
-        "Product: 205, iSee, book, 12.5, 150",
-        "Product: 202, Greatest Hits, cd, 6.5, 200",
-        "Product: 201, Coming Home, dvd, 8.0, 50",
-        "Product: 204, Toy Story, dvd, 10.0, 1000"};
-
-    @Test
-    public void testSorted() {
-        testStream("distinct", "[2, 3, 2, 4, 4].stream().distinct().toList()", exp3);
-        testStream("sorted", "[1, 3, 5, 2, 4, 6].stream().sorted().toList()", exp0);
-        testStream("sorted", "[1, 3, 5, 2, 4, 6].stream().sorted((i,j)->i-j).toList()", exp0);
-        testStream("sorted", "[1, 3, 5, 2, 4, 6].stream().sorted((i,j)->i.compareTo(j)).toList()", exp0);
-        testStream("sorted", "['2', '4', '6', '5', '3', '1'].stream().sorted((s, t)->s.compareTo(t)).toList()", exp0);
-        testStream("sorted", "[1, 3, 5, 2, 4, 6].stream().sorted((i,j)->j.compareTo(i)).toList()", exp1);
-        testStream("sorted", "['xyz', 'yz', 'z', 'abc', 'aaa', 'q'].stream().sorted" +
-                "((s,t)->(s.length()== t.length()? s.compareTo(t): s.length() - t.length())).toList()",
-                exp2);
-        elp.eval("comparing = map->(x,y)->map(x).compareTo(map(y))");
-        testStream("sorted", "products.stream().sorted(" +
-            "(x,y)->x.name.compareTo(y.name)).toList()", exp5);
-        testStream("sorted", "products.stream().sorted(" +
-            "comparing(p->p.name)).toList()", exp5);
-        elp.eval("compose = (m1,m2)->(x,y)->(tx = m1(x).compareTo(m1(y)); "
-                + "tx!=0? tx: (m2(x).compareTo(m2(y))))");
-        testStream("sorted", "products.stream().sorted(" +
-                "compose(p->p.category, p->p.unitPrice)).toList()", exp6);
-    }
-
-    static String exp8[] = {"Eagle", "Coming Home", "Greatest Hits",
-                       "History of Golf", "Toy Story" , "iSee"};
-
-    String exp11[] = {"1","2","3","4"};
-    @Test
-    public void testForEach() {
-        testStream("forEach",
-            "lst = []; products.stream().forEach(p->lst.add(p.name)); lst", exp8);
-        testStream("peek",
-             "lst = []; [1,2,3,4].stream().peek(i->lst.add(i)).toList()", exp11);
-        testStream("peek2", "lst", exp11);
-    }
-
-    static String[] exp7 = {
-        "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"};
-    
-    static String[] exp9 = {"t","h","e","q","u","i","c","k","b","r","o","w","n","f","o","x"};
-
-    @Test
-    public void testFlapMap() {
-        testStream("flatMap",
-            "customers.stream().filter(c->c.country=='USA')\n" +
-            "                  .flatMap(c->c.orders.stream()).toList()",
-            exp7);
-        testStream("flatMap String",
-             "['the', 'quick', 'brown', 'fox']" +
-             ".stream().flatMap(s->s.toCharArray().stream()).toList()",
-             exp9);
-    }
-
-    static String exp10[] = {"0", "1", "2"};
-
-    @Test
-    public void testSubstream() {
-        testStream("limit", "[0,1,2,3,4,5].stream().limit(3).toList()", exp10);
-        testStream("substream", "[0,1,2,3,4].stream().substream(2).toList()", exp3);
-        testStream("substream", "[0,1,2,3,4,5,6].stream().substream(2,5).toList()", exp3);
-    }
-
-    @Test
-    public void testReduce() {
-        testStream("reduce", "[1,2,3,4,5].stream().reduce(0, (l,r)->l+r)", Long.valueOf(15));
-        testStream("reduce", "[1,2,3,4,5].stream().reduce((l,r)->l+r).get()", Long.valueOf(15));
-        testStream("reduce", "[].stream().reduce((l,r)->l+r).orElse(101)", Long.valueOf(101));
-        testStream("reduce", "[].stream().reduce((l,r)->l+r).orElseGet(()->101)", Long.valueOf(101));
-        testStream("reduce", "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));
-    }
-
-    @Test
-    public void testMatch() {
-        testStream("anyMatch", "[1,2,3,4].stream().anyMatch(e->e == 3)", Boolean.TRUE);
-        testStream("anyMatch", "[1,2,3,4].stream().anyMatch(e->e > 10)", Boolean.FALSE);
-        testStream("allMatch", "[1,2,3,4].stream().allMatch(e->e > 0)", Boolean.TRUE);
-        testStream("allMatch", "[1,2,3,4].stream().allMatch(e->e > 1)", Boolean.FALSE);
-        testStream("noneMatch", "[1,2,3,4].stream().noneMatch(e->e > 1)", Boolean.FALSE);
-        testStream("noneMatch", "[1,2,3,4].stream().noneMatch(e->e > 10)", Boolean.TRUE);
-    }
-
-    @Test
-    public void testToType() {
-        testStream("toArray", "[2,3,4].stream().map(i->i*10).toArray()", exp4);
-        testStream("toList", "[2,3,4].stream().map(i->i*10).toList()", exp4);
-        testStream("Iterator", "[2,3,4].stream().map(i->i*10).iterator()", exp4);
-    }
-
-    @Test
-    public void testFind() {
-        testStream("findFirst", "[101, 100].stream().findFirst().get()", Long.valueOf(101));
-        boolean caught = false;
-        try {
-            elp.eval("[].stream().findFirst().get()");
-        } catch (ELException ex) {
-            caught = true;
-        }
-        assertTrue(caught);
-        testStream("findFirst", "[101, 100].stream().findFirst().isPresent()", Boolean.TRUE);
-        testStream("findFirst", "[].stream().findFirst().isPresent()", Boolean.FALSE);
-    }
-
-    @Test
-    public void testArith() {
-        testStream("sum", "[1,2,3,4,5].stream().sum()", Long.valueOf(15)); 
-        testStream("sum", "[1.4,2,3,4,5.1].stream().sum()", Double.valueOf(15.5)); 
-        testStream("average", "[1,2,3,4,5].stream().average().get()", Double.valueOf(3.0)); 
-        testStream("average", "[1.4,2,3,4,5.1].stream().average().get()", Double.valueOf(3.1)); 
-        testStream("count", "[1,2,3,4,5].stream().count()", Long.valueOf(5));
-    }
-    
-    @Test
-    public void testMinMax() {
-        testStream("min", "[2,3,1,5].stream().min().get()", Long.valueOf(1));
-        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");
-        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");
-    }
-    
-    @Test
-    public void testMap() {
-        Object r = elp.eval("v = {'one':1, 'two':2}");
-        System.out.println(" "+ r);
-        r = elp.eval("{1,2,3}");
-        System.out.println(" "+ r);
-    }
-}
diff --git a/uel/.gitkeep b/uel/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/uel/.gitkeep
+++ /dev/null
