diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..dcd9d5a
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,47 @@
+# Contributing to Eclipse Project for Expression Language
+
+Thanks for your interest in this project.
+
+## Project description
+
+Expression Language (also referred to as the EL) provides an important mechanism
+for enabling the presentation layer (web pages) to communicate with the
+application logic (managed beans). The EL is used by several JavaEE
+technologies, such as JavaServer Faces technology, JavaServer Pages (JSP)
+technology, and Contexts and Dependency Injection for Java EE (CDI). The EL can
+also be used in stand-alone environments.
+
+* https://projects.eclipse.org/projects/ee4j.el
+
+## Developer resources
+
+Information regarding source code management, builds, coding standards, and
+more.
+
+* https://projects.eclipse.org/projects/ee4j.el/developer
+
+The project maintains the following source code repositories
+
+* https://github.com/eclipse-ee4j/el-ri
+
+## Eclipse Contributor Agreement
+
+Before your contribution can be accepted by the project team contributors must
+electronically sign the Eclipse Contributor Agreement (ECA).
+
+* http://www.eclipse.org/legal/ECA.php
+
+Commits that are provided by non-committers must have a Signed-off-by field in
+the footer indicating that the author is aware of the terms by which the
+contribution has been provided to the project. The non-committer must
+additionally have an Eclipse Foundation account and must have a signed Eclipse
+Contributor Agreement (ECA) on file.
+
+For more information, please see the Eclipse Committer Handbook:
+https://www.eclipse.org/projects/handbook/#resources-commit
+
+## Contact
+
+Contact the project developers via the project's "dev" list.
+
+* 
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..5de3d1b
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,637 @@
+# Eclipse Public License - v 2.0
+
+        THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+        PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
+        OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+    1. DEFINITIONS
+
+    "Contribution" means:
+
+      a) in the case of the initial Contributor, the initial content
+         Distributed under this Agreement, and
+
+      b) in the case of each subsequent Contributor: 
+         i) changes to the Program, and 
+         ii) additions to the Program;
+      where such changes and/or additions to the Program originate from
+      and are Distributed by that particular Contributor. A Contribution
+      "originates" from a Contributor if it was added to the Program by
+      such Contributor itself or anyone acting on such Contributor's behalf.
+      Contributions do not include changes or additions to the Program that
+      are not Modified Works.
+
+    "Contributor" means any person or entity that Distributes the Program.
+
+    "Licensed Patents" mean patent claims licensable by a Contributor which
+    are necessarily infringed by the use or sale of its Contribution alone
+    or when combined with the Program.
+
+    "Program" means the Contributions Distributed in accordance with this
+    Agreement.
+
+    "Recipient" means anyone who receives the Program under this Agreement
+    or any Secondary License (as applicable), including Contributors.
+
+    "Derivative Works" shall mean any work, whether in Source Code or other
+    form, that is based on (or derived from) the Program and for which the
+    editorial revisions, annotations, elaborations, or other modifications
+    represent, as a whole, an original work of authorship.
+
+    "Modified Works" shall mean any work in Source Code or other form that
+    results from an addition to, deletion from, or modification of the
+    contents of the Program, including, for purposes of clarity any new file
+    in Source Code form that contains any contents of the Program. Modified
+    Works shall not include works that contain only declarations,
+    interfaces, types, classes, structures, or files of the Program solely
+    in each case in order to link to, bind by name, or subclass the Program
+    or Modified Works thereof.
+
+    "Distribute" means the acts of a) distributing or b) making available
+    in any manner that enables the transfer of a copy.
+
+    "Source Code" means the form of a Program preferred for making
+    modifications, including but not limited to software source code,
+    documentation source, and configuration files.
+
+    "Secondary License" means either the GNU General Public License,
+    Version 2.0, or any later versions of that license, including any
+    exceptions or additional permissions as identified by the initial
+    Contributor.
+
+    2. GRANT OF RIGHTS
+
+      a) Subject to the terms of this Agreement, each Contributor hereby
+      grants Recipient a non-exclusive, worldwide, royalty-free copyright
+      license to reproduce, prepare Derivative Works of, publicly display,
+      publicly perform, Distribute and sublicense the Contribution of such
+      Contributor, if any, and such Derivative Works.
+
+      b) Subject to the terms of this Agreement, each Contributor hereby
+      grants Recipient a non-exclusive, worldwide, royalty-free patent
+      license under Licensed Patents to make, use, sell, offer to sell,
+      import and otherwise transfer the Contribution of such Contributor,
+      if any, in Source Code or other form. This patent license shall
+      apply to the combination of the Contribution and the Program if, at
+      the time the Contribution is added by the Contributor, such addition
+      of the Contribution causes such combination to be covered by the
+      Licensed Patents. The patent license shall not apply to any other
+      combinations which include the Contribution. No hardware per se is
+      licensed hereunder.
+
+      c) Recipient understands that although each Contributor grants the
+      licenses to its Contributions set forth herein, no assurances are
+      provided by any Contributor that the Program does not infringe the
+      patent or other intellectual property rights of any other entity.
+      Each Contributor disclaims any liability to Recipient for claims
+      brought by any other entity based on infringement of intellectual
+      property rights or otherwise. As a condition to exercising the
+      rights and licenses granted hereunder, each Recipient hereby
+      assumes sole responsibility to secure any other intellectual
+      property rights needed, if any. For example, if a third party
+      patent license is required to allow Recipient to Distribute the
+      Program, it is Recipient's responsibility to acquire that license
+      before distributing the Program.
+
+      d) Each Contributor represents that to its knowledge it has
+      sufficient copyright rights in its Contribution, if any, to grant
+      the copyright license set forth in this Agreement.
+
+      e) Notwithstanding the terms of any Secondary License, no
+      Contributor makes additional grants to any Recipient (other than
+      those set forth in this Agreement) as a result of such Recipient's
+      receipt of the Program under the terms of a Secondary License
+      (if permitted under the terms of Section 3).
+
+    3. REQUIREMENTS
+
+    3.1 If a Contributor Distributes the Program in any form, then:
+
+      a) the Program must also be made available as Source Code, in
+      accordance with section 3.2, and the Contributor must accompany
+      the Program with a statement that the Source Code for the Program
+      is available under this Agreement, and informs Recipients how to
+      obtain it in a reasonable manner on or through a medium customarily
+      used for software exchange; and
+
+      b) the Contributor may Distribute the Program under a license
+      different than this Agreement, provided that such license:
+         i) effectively disclaims on behalf of all other Contributors all
+         warranties and conditions, express and implied, including
+         warranties or conditions of title and non-infringement, and
+         implied warranties or conditions of merchantability and fitness
+         for a particular purpose;
+
+         ii) effectively excludes on behalf of all other Contributors all
+         liability for damages, including direct, indirect, special,
+         incidental and consequential damages, such as lost profits;
+
+         iii) does not attempt to limit or alter the recipients' rights
+         in the Source Code under section 3.2; and
+
+         iv) requires any subsequent distribution of the Program by any
+         party to be under a license that satisfies the requirements
+         of this section 3.
+
+    3.2 When the Program is Distributed as Source Code:
+
+      a) it must be made available under this Agreement, or if the
+      Program (i) is combined with other material in a separate file or
+      files made available under a Secondary License, and (ii) the initial
+      Contributor attached to the Source Code the notice described in
+      Exhibit A of this Agreement, then the Program may be made available
+      under the terms of such Secondary Licenses, and
+
+      b) a copy of this Agreement must be included with each copy of
+      the Program.
+
+    3.3 Contributors may not remove or alter any copyright, patent,
+    trademark, attribution notices, disclaimers of warranty, or limitations
+    of liability ("notices") contained within the Program from any copy of
+    the Program which they Distribute, provided that Contributors may add
+    their own appropriate notices.
+
+    4. COMMERCIAL DISTRIBUTION
+
+    Commercial distributors of software may accept certain responsibilities
+    with respect to end users, business partners and the like. While this
+    license is intended to facilitate the commercial use of the Program,
+    the Contributor who includes the Program in a commercial product
+    offering should do so in a manner which does not create potential
+    liability for other Contributors. Therefore, if a Contributor includes
+    the Program in a commercial product offering, such Contributor
+    ("Commercial Contributor") hereby agrees to defend and indemnify every
+    other Contributor ("Indemnified Contributor") against any losses,
+    damages and costs (collectively "Losses") arising from claims, lawsuits
+    and other legal actions brought by a third party against the Indemnified
+    Contributor to the extent caused by the acts or omissions of such
+    Commercial Contributor in connection with its distribution of the Program
+    in a commercial product offering. The obligations in this section do not
+    apply to any claims or Losses relating to any actual or alleged
+    intellectual property infringement. In order to qualify, an Indemnified
+    Contributor must: a) promptly notify the Commercial Contributor in
+    writing of such claim, and b) allow the Commercial Contributor to control,
+    and cooperate with the Commercial Contributor in, the defense and any
+    related settlement negotiations. The Indemnified Contributor may
+    participate in any such claim at its own expense.
+
+    For example, a Contributor might include the Program in a commercial
+    product offering, Product X. That Contributor is then a Commercial
+    Contributor. If that Commercial Contributor then makes performance
+    claims, or offers warranties related to Product X, those performance
+    claims and warranties are such Commercial Contributor's responsibility
+    alone. Under this section, the Commercial Contributor would have to
+    defend claims against the other Contributors related to those performance
+    claims and warranties, and if a court requires any other Contributor to
+    pay any damages as a result, the Commercial Contributor must pay
+    those damages.
+
+    5. NO WARRANTY
+
+    EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+    PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
+    BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+    IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
+    TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+    PURPOSE. Each Recipient is solely responsible for determining the
+    appropriateness of using and distributing the Program and assumes all
+    risks associated with its exercise of rights under this Agreement,
+    including but not limited to the risks and costs of program errors,
+    compliance with applicable laws, damage to or loss of data, programs
+    or equipment, and unavailability or interruption of operations.
+
+    6. DISCLAIMER OF LIABILITY
+
+    EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+    PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
+    SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+    PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+    ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+    EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGES.
+
+    7. GENERAL
+
+    If any provision of this Agreement is invalid or unenforceable under
+    applicable law, it shall not affect the validity or enforceability of
+    the remainder of the terms of this Agreement, and without further
+    action by the parties hereto, such provision shall be reformed to the
+    minimum extent necessary to make such provision valid and enforceable.
+
+    If Recipient institutes patent litigation against any entity
+    (including a cross-claim or counterclaim in a lawsuit) alleging that the
+    Program itself (excluding combinations of the Program with other software
+    or hardware) infringes such Recipient's patent(s), then such Recipient's
+    rights granted under Section 2(b) shall terminate as of the date such
+    litigation is filed.
+
+    All Recipient's rights under this Agreement shall terminate if it
+    fails to comply with any of the material terms or conditions of this
+    Agreement and does not cure such failure in a reasonable period of
+    time after becoming aware of such noncompliance. If all Recipient's
+    rights under this Agreement terminate, Recipient agrees to cease use
+    and distribution of the Program as soon as reasonably practicable.
+    However, Recipient's obligations under this Agreement and any licenses
+    granted by Recipient relating to the Program shall continue and survive.
+
+    Everyone is permitted to copy and distribute copies of this Agreement,
+    but in order to avoid inconsistency the Agreement is copyrighted and
+    may only be modified in the following manner. The Agreement Steward
+    reserves the right to publish new versions (including revisions) of
+    this Agreement from time to time. No one other than the Agreement
+    Steward has the right to modify this Agreement. The Eclipse Foundation
+    is the initial Agreement Steward. The Eclipse Foundation may assign the
+    responsibility to serve as the Agreement Steward to a suitable separate
+    entity. Each new version of the Agreement will be given a distinguishing
+    version number. The Program (including Contributions) may always be
+    Distributed subject to the version of the Agreement under which it was
+    received. In addition, after a new version of the Agreement is published,
+    Contributor may elect to Distribute the Program (including its
+    Contributions) under the new version.
+
+    Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
+    receives no rights or licenses to the intellectual property of any
+    Contributor under this Agreement, whether expressly, by implication,
+    estoppel or otherwise. All rights in the Program not expressly granted
+    under this Agreement are reserved. Nothing in this Agreement is intended
+    to be enforceable by any entity that is not a Contributor or Recipient.
+    No third-party beneficiary rights are created under this Agreement.
+
+    Exhibit A - Form of Secondary Licenses Notice
+
+    "This Source Code may also be made available under the following 
+    Secondary Licenses when the conditions for such availability set forth 
+    in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
+    version(s), and exceptions or additional permissions here}."
+
+      Simply including a copy of this Agreement, including this Exhibit A
+      is not sufficient to license the Source Code under Secondary Licenses.
+
+      If it is not possible or desirable to put the notice in a particular
+      file, then You may include the notice in a location (such as a LICENSE
+      file in a relevant directory) where a recipient would be likely to
+      look for such a notice.
+
+      You may add additional accurate notices of copyright ownership.
+
+---
+
+##    The GNU General Public License (GPL) Version 2, June 1991
+
+    Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+    51 Franklin Street, Fifth Floor
+    Boston, MA 02110-1335
+    USA
+
+    Everyone is permitted to copy and distribute verbatim copies
+    of this license document, but changing it is not allowed.
+
+    Preamble
+
+    The licenses for most software are designed to take away your freedom to
+    share and change it. By contrast, the GNU General Public License is
+    intended to guarantee your freedom to share and change free software--to
+    make sure the software is free for all its users. This General Public
+    License applies to most of the Free Software Foundation's software and
+    to any other program whose authors commit to using it. (Some other Free
+    Software Foundation software is covered by the GNU Library General
+    Public License instead.) You can apply it to your programs, too.
+
+    When we speak of free software, we are referring to freedom, not price.
+    Our General Public Licenses are designed to make sure that you have the
+    freedom to distribute copies of free software (and charge for this
+    service if you wish), that you receive source code or can get it if you
+    want it, that you can change the software or use pieces of it in new
+    free programs; and that you know you can do these things.
+
+    To protect your rights, we need to make restrictions that forbid anyone
+    to deny you these rights or to ask you to surrender the rights. These
+    restrictions translate to certain responsibilities for you if you
+    distribute copies of the software, or if you modify it.
+
+    For example, if you distribute copies of such a program, whether gratis
+    or for a fee, you must give the recipients all the rights that you have.
+    You must make sure that they, too, receive or can get the source code.
+    And you must show them these terms so they know their rights.
+
+    We protect your rights with two steps: (1) copyright the software, and
+    (2) offer you this license which gives you legal permission to copy,
+    distribute and/or modify the software.
+
+    Also, for each author's protection and ours, we want to make certain
+    that everyone understands that there is no warranty for this free
+    software. If the software is modified by someone else and passed on, we
+    want its recipients to know that what they have is not the original, so
+    that any problems introduced by others will not reflect on the original
+    authors' reputations.
+
+    Finally, any free program is threatened constantly by software patents.
+    We wish to avoid the danger that redistributors of a free program will
+    individually obtain patent licenses, in effect making the program
+    proprietary. To prevent this, we have made it clear that any patent must
+    be licensed for everyone's free use or not licensed at all.
+
+    The precise terms and conditions for copying, distribution and
+    modification follow.
+
+    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+    0. This License applies to any program or other work which contains a
+    notice placed by the copyright holder saying it may be distributed under
+    the terms of this General Public License. The "Program", below, refers
+    to any such program or work, and a "work based on the Program" means
+    either the Program or any derivative work under copyright law: that is
+    to say, a work containing the Program or a portion of it, either
+    verbatim or with modifications and/or translated into another language.
+    (Hereinafter, translation is included without limitation in the term
+    "modification".) Each licensee is addressed as "you".
+
+    Activities other than copying, distribution and modification are not
+    covered by this License; they are outside its scope. The act of running
+    the Program is not restricted, and the output from the Program is
+    covered only if its contents constitute a work based on the Program
+    (independent of having been made by running the Program). Whether that
+    is true depends on what the Program does.
+
+    1. You may copy and distribute verbatim copies of the Program's source
+    code as you receive it, in any medium, provided that you conspicuously
+    and appropriately publish on each copy an appropriate copyright notice
+    and disclaimer of warranty; keep intact all the notices that refer to
+    this License and to the absence of any warranty; and give any other
+    recipients of the Program a copy of this License along with the Program.
+
+    You may charge a fee for the physical act of transferring a copy, and
+    you may at your option offer warranty protection in exchange for a fee.
+
+    2. You may modify your copy or copies of the Program or any portion of
+    it, thus forming a work based on the Program, and copy and distribute
+    such modifications or work under the terms of Section 1 above, provided
+    that you also meet all of these conditions:
+
+        a) You must cause the modified files to carry prominent notices
+        stating that you changed the files and the date of any change.
+
+        b) You must cause any work that you distribute or publish, that in
+        whole or in part contains or is derived from the Program or any part
+        thereof, to be licensed as a whole at no charge to all third parties
+        under the terms of this License.
+
+        c) If the modified program normally reads commands interactively
+        when run, you must cause it, when started running for such
+        interactive use in the most ordinary way, to print or display an
+        announcement including an appropriate copyright notice and a notice
+        that there is no warranty (or else, saying that you provide a
+        warranty) and that users may redistribute the program under these
+        conditions, and telling the user how to view a copy of this License.
+        (Exception: if the Program itself is interactive but does not
+        normally print such an announcement, your work based on the Program
+        is not required to print an announcement.)
+
+    These requirements apply to the modified work as a whole. If
+    identifiable sections of that work are not derived from the Program, and
+    can be reasonably considered independent and separate works in
+    themselves, then this License, and its terms, do not apply to those
+    sections when you distribute them as separate works. But when you
+    distribute the same sections as part of a whole which is a work based on
+    the Program, the distribution of the whole must be on the terms of this
+    License, whose permissions for other licensees extend to the entire
+    whole, and thus to each and every part regardless of who wrote it.
+
+    Thus, it is not the intent of this section to claim rights or contest
+    your rights to work written entirely by you; rather, the intent is to
+    exercise the right to control the distribution of derivative or
+    collective works based on the Program.
+
+    In addition, mere aggregation of another work not based on the Program
+    with the Program (or with a work based on the Program) on a volume of a
+    storage or distribution medium does not bring the other work under the
+    scope of this License.
+
+    3. You may copy and distribute the Program (or a work based on it,
+    under Section 2) in object code or executable form under the terms of
+    Sections 1 and 2 above provided that you also do one of the following:
+
+        a) Accompany it with the complete corresponding machine-readable
+        source code, which must be distributed under the terms of Sections 1
+        and 2 above on a medium customarily used for software interchange; or,
+
+        b) Accompany it with a written offer, valid for at least three
+        years, to give any third party, for a charge no more than your cost
+        of physically performing source distribution, a complete
+        machine-readable copy of the corresponding source code, to be
+        distributed under the terms of Sections 1 and 2 above on a medium
+        customarily used for software interchange; or,
+
+        c) Accompany it with the information you received as to the offer to
+        distribute corresponding source code. (This alternative is allowed
+        only for noncommercial distribution and only if you received the
+        program in object code or executable form with such an offer, in
+        accord with Subsection b above.)
+
+    The source code for a work means the preferred form of the work for
+    making modifications to it. For an executable work, complete source code
+    means all the source code for all modules it contains, plus any
+    associated interface definition files, plus the scripts used to control
+    compilation and installation of the executable. However, as a special
+    exception, the source code distributed need not include anything that is
+    normally distributed (in either source or binary form) with the major
+    components (compiler, kernel, and so on) of the operating system on
+    which the executable runs, unless that component itself accompanies the
+    executable.
+
+    If distribution of executable or object code is made by offering access
+    to copy from a designated place, then offering equivalent access to copy
+    the source code from the same place counts as distribution of the source
+    code, even though third parties are not compelled to copy the source
+    along with the object code.
+
+    4. You may not copy, modify, sublicense, or distribute the Program
+    except as expressly provided under this License. Any attempt otherwise
+    to copy, modify, sublicense or distribute the Program is void, and will
+    automatically terminate your rights under this License. However, parties
+    who have received copies, or rights, from you under this License will
+    not have their licenses terminated so long as such parties remain in
+    full compliance.
+
+    5. You are not required to accept this License, since you have not
+    signed it. However, nothing else grants you permission to modify or
+    distribute the Program or its derivative works. These actions are
+    prohibited by law if you do not accept this License. Therefore, by
+    modifying or distributing the Program (or any work based on the
+    Program), you indicate your acceptance of this License to do so, and all
+    its terms and conditions for copying, distributing or modifying the
+    Program or works based on it.
+
+    6. Each time you redistribute the Program (or any work based on the
+    Program), the recipient automatically receives a license from the
+    original licensor to copy, distribute or modify the Program subject to
+    these terms and conditions. You may not impose any further restrictions
+    on the recipients' exercise of the rights granted herein. You are not
+    responsible for enforcing compliance by third parties to this License.
+
+    7. If, as a consequence of a court judgment or allegation of patent
+    infringement or for any other reason (not limited to patent issues),
+    conditions are imposed on you (whether by court order, agreement or
+    otherwise) that contradict the conditions of this License, they do not
+    excuse you from the conditions of this License. If you cannot distribute
+    so as to satisfy simultaneously your obligations under this License and
+    any other pertinent obligations, then as a consequence you may not
+    distribute the Program at all. For example, if a patent license would
+    not permit royalty-free redistribution of the Program by all those who
+    receive copies directly or indirectly through you, then the only way you
+    could satisfy both it and this License would be to refrain entirely from
+    distribution of the Program.
+
+    If any portion of this section is held invalid or unenforceable under
+    any particular circumstance, the balance of the section is intended to
+    apply and the section as a whole is intended to apply in other
+    circumstances.
+
+    It is not the purpose of this section to induce you to infringe any
+    patents or other property right claims or to contest validity of any
+    such claims; this section has the sole purpose of protecting the
+    integrity of the free software distribution system, which is implemented
+    by public license practices. Many people have made generous
+    contributions to the wide range of software distributed through that
+    system in reliance on consistent application of that system; it is up to
+    the author/donor to decide if he or she is willing to distribute
+    software through any other system and a licensee cannot impose that choice.
+
+    This section is intended to make thoroughly clear what is believed to be
+    a consequence of the rest of this License.
+
+    8. If the distribution and/or use of the Program is restricted in
+    certain countries either by patents or by copyrighted interfaces, the
+    original copyright holder who places the Program under this License may
+    add an explicit geographical distribution limitation excluding those
+    countries, so that distribution is permitted only in or among countries
+    not thus excluded. In such case, this License incorporates the
+    limitation as if written in the body of this License.
+
+    9. The Free Software Foundation may publish revised and/or new
+    versions of the General Public License from time to time. Such new
+    versions will be similar in spirit to the present version, but may
+    differ in detail to address new problems or concerns.
+
+    Each version is given a distinguishing version number. If the Program
+    specifies a version number of this License which applies to it and "any
+    later version", you have the option of following the terms and
+    conditions either of that version or of any later version published by
+    the Free Software Foundation. If the Program does not specify a version
+    number of this License, you may choose any version ever published by the
+    Free Software Foundation.
+
+    10. If you wish to incorporate parts of the Program into other free
+    programs whose distribution conditions are different, write to the
+    author to ask for permission. For software which is copyrighted by the
+    Free Software Foundation, write to the Free Software Foundation; we
+    sometimes make exceptions for this. Our decision will be guided by the
+    two goals of preserving the free status of all derivatives of our free
+    software and of promoting the sharing and reuse of software generally.
+
+    NO WARRANTY
+
+    11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+    WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+    EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+    OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
+    EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+    ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+    YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+    NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+    12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+    WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+    AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
+    DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
+    DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
+    (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+    INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
+    THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR
+    OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+    END OF TERMS AND CONDITIONS
+
+    How to Apply These Terms to Your New Programs
+
+    If you develop a new program, and you want it to be of the greatest
+    possible use to the public, the best way to achieve this is to make it
+    free software which everyone can redistribute and change under these terms.
+
+    To do so, attach the following notices to the program. It is safest to
+    attach them to the start of each source file to most effectively convey
+    the exclusion of warranty; and each file should have at least the
+    "copyright" line and a pointer to where the full notice is found.
+
+        One line to give the program's name and a brief idea of what it does.
+        Copyright (C) <year> <name of author>
+
+        This program is free software; you can redistribute it and/or modify
+        it under the terms of the GNU General Public License as published by
+        the Free Software Foundation; either version 2 of the License, or
+        (at your option) any later version.
+
+        This program is distributed in the hope that it will be useful, but
+        WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+        General Public License for more details.
+
+        You should have received a copy of the GNU General Public License
+        along with this program; if not, write to the Free Software
+        Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+
+    Also add information on how to contact you by electronic and paper mail.
+
+    If the program is interactive, make it output a short notice like this
+    when it starts in an interactive mode:
+
+        Gnomovision version 69, Copyright (C) year name of author
+        Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type
+        `show w'. This is free software, and you are welcome to redistribute
+        it under certain conditions; type `show c' for details.
+
+    The hypothetical commands `show w' and `show c' should show the
+    appropriate parts of the General Public License. Of course, the commands
+    you use may be called something other than `show w' and `show c'; they
+    could even be mouse-clicks or menu items--whatever suits your program.
+
+    You should also get your employer (if you work as a programmer) or your
+    school, if any, to sign a "copyright disclaimer" for the program, if
+    necessary. Here is a sample; alter the names:
+
+        Yoyodyne, Inc., hereby disclaims all copyright interest in the
+        program `Gnomovision' (which makes passes at compilers) written by
+        James Hacker.
+
+        signature of Ty Coon, 1 April 1989
+        Ty Coon, President of Vice
+
+    This General Public License does not permit incorporating your program
+    into proprietary programs. If your program is a subroutine library, you
+    may consider it more useful to permit linking proprietary applications
+    with the library. If this is what you want to do, use the GNU Library
+    General Public License instead of this License.
+
+---
+
+## CLASSPATH EXCEPTION
+
+    Linking this library statically or dynamically with other modules is
+    making a combined work based on this library.  Thus, the terms and
+    conditions of the GNU General Public License version 2 cover the whole
+    combination.
+
+    As a special exception, the copyright holders of this library give you
+    permission to link this library with independent modules to produce an
+    executable, regardless of the license terms of these independent
+    modules, and to copy and distribute the resulting executable under
+    terms of your choice, provided that you also meet, for each linked
+    independent module, the terms and conditions of the license of that
+    module.  An independent module is a module which is not derived from or
+    based on this library.  If you modify this library, you may extend this
+    exception to your version of the library, but you are not obligated to
+    do so.  If you do not wish to do so, delete this exception statement
+    from your version.
diff --git a/NOTICE.md b/NOTICE.md
new file mode 100644
index 0000000..bf84fa8
--- /dev/null
+++ b/NOTICE.md
@@ -0,0 +1,46 @@
+# Notices for Eclipse Project for Expression Language
+
+This content is produced and maintained by the Eclipse Project for Expression
+Language project.
+
+* Project home: https://projects.eclipse.org/projects/ee4j.el
+
+## Trademarks
+
+Eclipse Project for Expression Language is a trademark of the Eclipse
+Foundation.
+
+## Copyright
+
+All content is the property of the respective authors or their employers. For
+more information regarding authorship of content, please consult the listed
+source code repository logs.
+
+## Declared Project Licenses
+
+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
+
+## Source Code
+
+The project maintains the following source code repositories:
+
+* https://github.com/eclipse-ee4j/el-ri
+
+## Third-party Content
+
+## Cryptography
+
+Content may contain encryption software. The country in which you are currently
+may have restrictions on the import, possession, and use, and/or re-export to
+another country, of encryption software. BEFORE using any encryption software,
+please check the country's laws, regulations and policies concerning the import,
+possession, or use, and re-export of encryption software, to see if this is
+permitted.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4259f5d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+# Prerequisites
+
+Oracle JDK 1.7
+
+Apache Maven 3.3.9 or later in order to build and run the tests.
+
+# Licenses
+
+Applicable licenses for this project are documented in LICENSE.md available at the root of this repository.
diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 0000000..df1e03c
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,259 @@
+<?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">
+    <parent>
+      <groupId>org.eclipse.ee4j</groupId>
+      <artifactId>project</artifactId>
+      <version>1.0</version>
+      <relativePath/>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>javax.el</groupId>
+    <artifactId>javax.el-api</artifactId>
+    <packaging>jar</packaging>
+    <version>3.0.1-b07-SNAPSHOT</version>
+    <name>Expression Language 3.0 API</name>
+
+    <properties>
+        <!-- Make sure the two versions are in sync with the maven version -->
+        <spec.version>3.0</spec.version>
+        <bundle.version>3.0.0</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>
+    
+    <url>https://projects.eclipse.org/projects/ee4j.el</url>
+
+    <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>EL 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>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>1.4.3</version>
+                <configuration>
+                    <supportedProjectTypes>
+                        <supportedProjectType>jar</supportedProjectType>
+                    </supportedProjectTypes>
+                    <instructions>
+                        <Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName>
+                        <Bundle-Description>
+                            Expression Language ${spec.version} API
+                        </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>
+                    </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>
+                    <excludes>
+                        <exclude>**/*.java</exclude>
+                    </excludes>
+                </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-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>
+                <version>2.8.1</version>
+                <executions>
+                    <execution>
+                        <id>attach-javadocs</id>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        <configuration>
+                            <groups>
+                                <group>
+                                    <title>Expresion Language API Documentation</title>
+                                    <packages>javax.el</packages>
+                                </group>
+                            </groups>
+                            <bottom>
+<![CDATA[Copyright &#169; 2013,
+    <a href="http://www.oracle.com">Oracle</a>
+    and/or its affiliates. All Rights Reserved.
+    Use is subject to
+  <a href="{@docRoot}/doc-files/final-spec-license.html" target="_top">license terms</a>.
+]]>
+                            </bottom>
+                        </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>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-remote-resources-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                  <execution>
+                    <goals>
+                      <goal>process</goal>
+                    </goals>
+                    <configuration>
+                      <resourceBundles>
+                        <resourceBundle>org.glassfish:legal:1.1</resourceBundle>
+                      </resourceBundles>
+                    </configuration>
+                  </execution>
+                </executions>
+            </plugin>
+    	</plugins>
+        <resources>
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                </includes>
+            </resource>
+        </resources>
+    </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
new file mode 100644
index 0000000..11c5c8c
--- /dev/null
+++ b/api/src/main/java/javax/el/ArrayELResolver.java
@@ -0,0 +1,344 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.lang.reflect.Array;
+import java.util.List;
+import java.util.Iterator;
+import java.beans.FeatureDescriptor;
+
+/**
+ * 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 JSP 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.
+     */
+    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.
+     */
+    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.
+     */
+    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.
+     */
+    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>.
+     */
+    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>.
+     */
+    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
new file mode 100644
index 0000000..ea4418a
--- /dev/null
+++ b/api/src/main/java/javax/el/BeanELResolver.java
@@ -0,0 +1,654 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.ref.SoftReference;
+import java.lang.ref.ReferenceQueue;
+import java.beans.FeatureDescriptor;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.beans.IntrospectionException;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+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 JSP 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 int CACHE_INIT_SIZE = 1024;
+        private ConcurrentHashMap<Class<?>, BPSoftReference> map =
+            new ConcurrentHashMap<Class<?>, BPSoftReference>(CACHE_INIT_SIZE);
+        private ReferenceQueue<BeanProperties> refQ =
+                        new ReferenceQueue<BeanProperties>();
+
+        // 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<String, BeanProperty>();
+                                                                                
+        public BeanProperties(Class<?> baseClass) {
+            PropertyDescriptor[] descriptors;
+            try {
+                BeanInfo info = Introspector.getBeanInfo(baseClass);
+                descriptors = info.getPropertyDescriptors();
+            } catch (IntrospectionException ie) {
+                throw new ELException(ie);
+            }
+            for (PropertyDescriptor pd: descriptors) {
+                propertyMap.put(pd.getName(),
+                                new BeanProperty(baseClass, pd));
+            }
+        }
+                                                                                
+        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.
+     */
+    public Class<?> getType(ELContext context,
+                         Object base,
+                         Object property) {
+
+        if (context == null) {
+            throw new NullPointerException();
+        }
+
+        if (base == null || property == null){
+            return null;
+        }
+
+        BeanProperty bp = getBeanProperty(context, base, property);
+        context.setPropertyResolved(true);
+        return bp.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.
+     */
+    public Object getValue(ELContext context,
+                           Object base,
+                           Object property) {
+
+        if (context == null) {
+            throw new NullPointerException();
+        }
+
+        if (base == null || property == null){
+            return null;
+        }
+
+        BeanProperty bp = getBeanProperty(context, base, property);
+        Method method = bp.getReadMethod();
+        if (method == null) {
+            throw new PropertyNotFoundException(
+                        ELUtil.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.
+     */
+    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(
+                        ELUtil.getExceptionMessageString(context,
+                            "resolverNotwritable",
+                            new Object[] { base.getClass().getName() }));
+        } 
+
+        BeanProperty bp = getBeanProperty(context, base, property);
+        Method method = bp.getWriteMethod();
+        if (method == null) {
+            throw new PropertyNotWritableException(
+                        ELUtil.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 = ELUtil.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 method 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 EL 2.2
+     */
+
+    public Object invoke(ELContext context,
+                         Object base,
+                         Object method,
+                         Class<?>[] paramTypes,
+                         Object[] params) {
+
+        if (base == null || method == null) {
+            return null;
+        }
+        Method m = ELUtil.findMethod(base.getClass(), method.toString(),
+                                    paramTypes,params, false);
+        for (Object p: params) {
+            // If the parameters is a LambdaExpression, set the ELContext
+            // for its evaluation
+            if (p instanceof javax.el.LambdaExpression) {
+                ((javax.el.LambdaExpression) p).setELContext(context);
+            }
+        }
+        Object ret = ELUtil.invokeMethod(context, m, base, params);
+        context.setPropertyResolved(base, method);
+        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.
+     */
+    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;
+        }
+
+        BeanProperty bp = getBeanProperty(context, base, property);
+        return bp.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:
+     * <dl>
+     *     <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>
+     * </dl>
+     * </p>
+     * 
+     * @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>.
+     */
+    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> list = new ArrayList<FeatureDescriptor>(
+                info.getPropertyDescriptors().length);
+        for (PropertyDescriptor pd: info.getPropertyDescriptors()) {
+            pd.setValue("type", pd.getPropertyType());
+            pd.setValue("resolvableAtDesignTime", Boolean.TRUE);
+            list.add(pd);
+        }
+        return list.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>.
+     */
+    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 bps = properties.get(baseClass);
+        if (bps == null) {
+            bps = new BeanProperties(baseClass);
+            properties.put(baseClass, bps);
+        }
+        BeanProperty bp = bps.getBeanProperty(property);
+        if (bp == null) {
+            throw new PropertyNotFoundException(
+                        ELUtil.getExceptionMessageString(context,
+                            "propertyNotFound",
+                            new Object[] { baseClass.getName(),
+                                           property}));
+        }
+        return bp;
+    }
+}
+
diff --git a/api/src/main/java/javax/el/BeanNameELResolver.java b/api/src/main/java/javax/el/BeanNameELResolver.java
new file mode 100644
index 0000000..2fc92f8
--- /dev/null
+++ b/api/src/main/java/javax/el/BeanNameELResolver.java
@@ -0,0 +1,233 @@
+/*
+ * 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 javax.el;
+
+import java.util.Iterator;
+import java.beans.FeatureDescriptor;
+
+/**
+ * <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.
+ * <blockquote>
+ * <pre>
+ * 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;
+ *    }
+ * });
+ * </pre>
+ * </blockquote>
+ * </p>
+ * @since EL 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>.
+     */
+    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
new file mode 100644
index 0000000..3541173
--- /dev/null
+++ b/api/src/main/java/javax/el/BeanNameResolver.java
@@ -0,0 +1,83 @@
+/*
+ * 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 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 EL 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
new file mode 100644
index 0000000..2c46e33
--- /dev/null
+++ b/api/src/main/java/javax/el/CompositeELResolver.java
@@ -0,0 +1,592 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.beans.FeatureDescriptor;
+
+/**
+ * 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 JSP 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>
+     *
+     * <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>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>
+     *
+     * <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 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 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;
+    }
+
+    /**
+     * Attemps 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>
+     *
+     * <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 EL 2.2
+     */
+    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>
+     *
+     * <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.
+     */
+    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>
+     *
+     * <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>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>
+     *
+     * <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>.
+     *
+     * <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 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.
+     */
+    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>
+     *
+     * <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.
+     */
+    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
+     */
+    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.</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 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 EL 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 EL 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;
+        }
+
+        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();
+        }
+
+        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();
+        }
+
+        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
new file mode 100644
index 0000000..e8f5d93
--- /dev/null
+++ b/api/src/main/java/javax/el/ELClass.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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 javax.el;
+
+/**
+ * <p>A runtime representation of a Class in the EL expressions.
+ * It encapsulates the java.lang.Class instance.</p>
+ * 
+ * <p>This class is used only in {@link StaticFieldELResolver} and will
+ * probably only be of interest to EL implementors, and not EL users.
+ *
+ * @since EL 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
new file mode 100644
index 0000000..7bc26da
--- /dev/null
+++ b/api/src/main/java/javax/el/ELContext.java
@@ -0,0 +1,446 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.util.Map;
+import java.util.Stack;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Locale;
+
+/**
+ * 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 EL Functions.  This is used only in parsing.</li>
+ *   <li>a reference to {@link VariableMapper} that will be used
+ *       to resolve EL 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>
+ *
+ * <p>The collection of context objects is necessary because each 
+ * <code>ELResolver</code> may need access to a different context object.
+ * For example, JSP and Faces resolvers need access to a 
+ * {@link javax.servlet.jsp.JspContext} and a
+ * {@link javax.faces.context.FacesContext}, respectively.</p>
+ *
+ * <p>When used in a web container, the creation of
+ * <code>ELContext</code> objects is controlled through 
+ * the underlying technology.  For example, in JSP 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>
+ *
+ * <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.</p>
+ *
+ * @see ELContextListener
+ * @see ELContextEvent
+ * @see ELResolver
+ * @see FunctionMapper
+ * @see VariableMapper
+ * @see ImportHandler
+ * @see LambdaExpression
+ * @see StandardELContext
+ * @see javax.servlet.jsp.JspContext
+ * @since EL 2.1 and EL 3.0
+ */
+public abstract class ELContext {
+
+    /**
+     * 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.</p>
+     *
+     * @see CompositeELResolver
+     * @param base The base object
+     * @param property The property object
+     *
+     * @since EL 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.</p>
+     *
+     * @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 EL 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
+     * EL functions.
+     */
+    public abstract FunctionMapper getFunctionMapper();
+    
+    /**
+     * Holds value of property locale.
+     */
+    private Locale locale;
+    
+    /**
+     * 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 this.locale;
+    }
+
+    /**
+     * Sets the <code>Locale</code> for this instance.  This method may be 
+     * called by the party creating the instance, such as JavaServer
+     * Faces or JSP, to enable the EL implementation to provide localized
+     * messages to the user.  If no <code>Locale</code> is set, the implementation
+     * must use the locale returned by <code>Locale.getDefault( )</code>.
+     */
+    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
+     * EL variables.
+     */
+    public abstract VariableMapper getVariableMapper();
+
+    /**
+     * Registers an evaluation listener to the ELContext.
+     *
+     * @param listener The listener to be added.
+     *
+     * @since EL 3.0
+     */
+    public void addEvaluationListener(EvaluationListener listener) {
+        if (listeners == null) {
+            listeners = new ArrayList<EvaluationListener>();
+        }
+        listeners.add(listener);
+    }
+
+    /**
+     * Returns the list of registered evaluation listeners.
+     * @return The list of registered evaluation listeners.
+     *
+     * @since EL 3.0
+     */
+    public List<EvaluationListener> getEvaluationListeners() {
+        return listeners;
+    }
+
+    /**
+     * Notifies the listeners before an EL expression is evaluated
+     * @param expr The EL 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 EL expression is evaluated
+     * @param expr The EL 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 EL 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 EL 3.0
+     */
+    public void enterLambdaScope(Map<String,Object> args) {
+        if (lambdaArgs == null) {
+            lambdaArgs = new Stack<Map<String,Object>>();
+        }
+        lambdaArgs.push(args);
+    }
+
+    /**
+     * Exits the Lambda expression evaluation. The Lambda argument map that
+     * was previously installed is removed.
+     * @since EL 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.</p>
+     *
+     * @param obj The object to convert.
+     * @param targetType The target type for the conversion.
+     * @throws ELException thrown if errors occur.
+     *
+     * @since EL 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);
+    }
+
+    private boolean resolved;
+    private HashMap<Class<?>, Object> map = new HashMap<Class<?>, Object>();
+    private transient List<EvaluationListener> listeners = null;
+    private Stack<Map<String,Object>> lambdaArgs;
+    private ImportHandler importHandler;
+}
+
diff --git a/api/src/main/java/javax/el/ELContextEvent.java b/api/src/main/java/javax/el/ELContextEvent.java
new file mode 100644
index 0000000..2af7b92
--- /dev/null
+++ b/api/src/main/java/javax/el/ELContextEvent.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+/**
+ * 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 JSP 2.1
+ */
+public class ELContextEvent extends java.util.EventObject {
+
+    /**
+     * 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
new file mode 100644
index 0000000..b4df47b
--- /dev/null
+++ b/api/src/main/java/javax/el/ELContextListener.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+/**
+ * The listener interface for receiving notification when an
+ * {@link ELContext} is created.
+ *
+ * @see ELContext
+ * @see ELContextEvent
+ * @since JSP 2.1
+ */
+public interface ELContextListener extends java.util.EventListener {
+
+    /**
+     * Invoked when a new <code>ELContext</code> has been created.
+     *
+     * @param ece the notification event.
+     */
+    public void contextCreated(ELContextEvent ece);
+
+}
diff --git a/api/src/main/java/javax/el/ELException.java b/api/src/main/java/javax/el/ELException.java
new file mode 100644
index 0000000..3f39601
--- /dev/null
+++ b/api/src/main/java/javax/el/ELException.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+/**
+ * Represents any of the exception conditions that can arise during
+ * expression evaluation.
+ *
+ * @since JSP 2.1
+ */
+public class ELException extends RuntimeException {
+
+    //-------------------------------------
+    /**
+     * 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
new file mode 100644
index 0000000..5d06e22
--- /dev/null
+++ b/api/src/main/java/javax/el/ELManager.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2013, 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 javax.el;
+
+import java.lang.reflect.Method;
+
+/**
+ * <p>Manages EL parsing and evaluation environment.  The ELManager maintains an
+ * instance of ExpressionFactory and StandardELContext, for
+ * parsing and evaluating EL expressions.</p>
+ *
+ * @since EL 3.0
+ */
+public class ELManager {
+
+    private StandardELContext elContext;
+
+    /**
+     * Return the ExpressionFactory instance used for EL evaluations.
+     * @return The ExpressionFactory
+     */
+    public static ExpressionFactory getExpressionFactory() {
+        return ELUtil.getExpressionFactory();
+    }
+
+    /**
+     * Return the ELContext used for parsing and evaluating EL expressions.
+     * If there is currently no ELContext, a default instance of
+     * StandardELContext is returned.
+     *
+     * @return The ELContext used for parsing and evaluating EL expressions..
+     */
+    public StandardELContext getELContext() {
+        if (elContext == null) {
+            elContext = new StandardELContext(getExpressionFactory());
+        }
+        return elContext;
+    }
+
+    /**
+     * Set the ELContext used for parsing and evaluating EL 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 prev = elContext;
+        elContext = new StandardELContext(context);
+        return prev;
+    }
+
+    /**
+     * 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 bnr The BeanNameResolver to be registered.
+     */
+    public void addBeanNameResolver(BeanNameResolver bnr) {
+        getELContext().addELResolver(new BeanNameELResolver(bnr));
+    }
+
+    /**
+     * 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 elr The ELResolver to be added to the list of ELResolvers in
+     *     ELContext.
+     * @see StandardELContext#addELResolver
+     */
+    public void addELResolver(ELResolver elr) {
+        getELContext().addELResolver(elr);
+    }
+
+    /**
+     * Maps a static method to an EL function.
+     * @param prefix The namespace of the functions, can be "".
+     * @param function The name of the function.  
+     * @param meth The static method to be invoked when the function is used.
+     */
+    public void mapFunction(String prefix, String function, Method meth) {
+        getELContext().getFunctionMapper().mapFunction(prefix, function, meth);
+    }
+
+    /** 
+     * Assign a ValueExpression to an EL variable, replacing
+     * any previous assignment to the same variable.
+     * The assignment for the variable is removed if
+     * the expression is <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.
+     */
+    public Object defineBean(String name, Object bean) {
+        Object ret = getELContext().getBeans().get(name);
+        getELContext().getBeans().put(name, bean);
+        return ret;
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..587c7fd
--- /dev/null
+++ b/api/src/main/java/javax/el/ELProcessor.java
@@ -0,0 +1,312 @@
+/*
+ * 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 javax.el;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * <p>Provides an API for using EL in a stand-alone environment.</p>
+ * 
+ * <p>This class provides a direct and simple interface for
+ * <ul>
+ *   <li>Evaluating EL expressions.</li>
+ *   <li>Assigning values to beans or setting a bean property.</li>
+ *   <li>Setting a {@link ValueExpression} to a EL variable.</li>
+ *   <li>Defining a static method as an EL function.</li>
+ *   <li>Defining an object instance as an EL name.
+ * </ul>
+ * 
+ * <p>This API is not a replacement for the APIs in EL 2.2.  Containers that
+ * maintains EL environments can continue to do so, without using this API.</p>
+ * 
+ * <p>For EL users who want to manipulate EL environments, like adding custom
+ * {@link ELResolver}s, {@link ELManager} can be used.</p>
+ *
+ * <h3>Scope and Life Cycle</h3>
+ * <p>Since it maintains the state of the EL environments,
+ * <code>ELProcessor</code> is not thread safe.  In the simplest case,
+ * an instance can be created and destroyed before and after evaluating
+ * EL expressions.  A more general usage is to use an instance of
+ * <code>ELProcessor</code> for a session, so that the user can configure the
+ * EL evaluation environment for that session.</p>
+ *
+ * <h3>Automatic Bracketing of Expressions</h3>
+ * <p>A note about the EL 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 EL 3.0
+ */
+
+public class ELProcessor {
+
+    private ELManager elManager = new ELManager();
+    private ExpressionFactory factory = elManager.getExpressionFactory();
+
+    /**
+     * Return the ELManager used for EL processing.
+     * @return The ELManager used for EL processing.
+     */
+    public ELManager getELManager() {
+        return elManager;
+    }
+
+    /**
+     * Evaluates an EL expression.
+     * @param expression The EL expression to be evaluated.
+     * @return The result of the expression evaluation.
+     */
+    public Object eval(String expression) {
+        return getValue(expression, Object.class);
+    }
+
+    /**
+     * Evaluates an EL expression, and coerces the result to the specified type.
+     * @param expression The EL 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 an EL expression to an EL variable.  The expression is parsed,
+     * but not evaluated, and the parsed expression is mapped to the EL
+     * variable in the local variable map.
+     * Any previously assigned expression to the same variable will be replaced.
+     * If the expression is <code>null</code>, the variable will be removed.
+     * @param var The name of the variable.
+     * @param expression The EL 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 an EL 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 an EL 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 java.lang.reflect.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
new file mode 100644
index 0000000..29a74f9
--- /dev/null
+++ b/api/src/main/java/javax/el/ELResolver.java
@@ -0,0 +1,413 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.util.Iterator;
+import java.beans.FeatureDescriptor;
+
+/**
+ * Enables customization of variable, property, method call, and type
+ * conversion resolution behavior for EL 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 EL 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>
+ *
+ * <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>
+ *
+ * <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>
+ *
+ * <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>
+ *
+ * <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>
+ * 
+ * <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.</p>
+ *
+ * @see CompositeELResolver
+ * @see ELContext#getELResolver
+ * @since JSP 2.1
+ */
+public abstract class ELResolver {
+    
+    // --------------------------------------------------------- Constants
+
+    /**
+     * <p>The attribute name of the named attribute in the
+     * <code>FeatureDescriptor</code> that specifies the runtime type of
+     * the variable or property.</p>
+     */
+
+    public static final String TYPE = "type";
+
+    /**
+     * <p>The attribute name of the named attribute in the
+     * <code>FeatureDescriptor</code> that specifies whether the
+     * variable or property can be resolved at runtime.</p>
+     */
+
+    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>
+     *
+     * <p>A default implementation is provided that returns null so that
+     * existing classes that extend ELResolver can continue to function.</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).
+     * @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 EL 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>
+     *
+     * <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>
+     *
+     * <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>
+     *
+     * <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.</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
+     * @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 convertion.
+     * @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
new file mode 100644
index 0000000..65751b3
--- /dev/null
+++ b/api/src/main/java/javax/el/ELUtil.java
@@ -0,0 +1,858 @@
+/*
+ * 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.
+ */
+
+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;
+
+/**
+ *
+ * <p>Utility methods for this portion of the EL implementation</p>
+ *
+ * <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.</p>
+ *
+ * @author edburns
+ * @author Kin-man Chung
+ * @author Dongbin Nie
+ */
+class ELUtil {
+    
+    /**
+     * <p>This class may not be constructed.</p>
+     */
+    
+    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
+     * {@link javax.faces.context.FacesContext} instance for each
+     * processing thread.</p>
+     */
+    private static ThreadLocal<Map<String, ResourceBundle>> instance =
+                new ThreadLocal<Map<String, ResourceBundle>>() {
+            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 (null == result) {
+            result = new HashMap<String, ResourceBundle>();
+            setCurrentInstance(result);
+        }
+        return result;
+
+    }
+    
+    /**
+     * <p>Replace the Map with the argument context.</p>
+     *
+     * @param context the Map to be stored in ThreadLocal storage.
+     */
+
+    private static void setCurrentInstance(Map<String, ResourceBundle> context) {
+
+        instance.set(context);
+
+    }
+    
+    /*
+     * <p>Convenience method, calls through to 
+     * {@link #getExceptionMessageString(javax.el.ELContext,java.lang.String,Object []).
+     * </p>
+     *
+     * @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 EL 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 (null != locale) {
+            Map<String, ResourceBundle> threadMap = getCurrentInstance();
+            ResourceBundle rb = null;
+            if (null == (rb = (ResourceBundle)
+                    threadMap.get(locale.toString()))) {
+                rb = ResourceBundle.getBundle("javax.el.PrivateMessages",
+                                              locale);
+                threadMap.put(locale.toString(), rb);
+            }
+            if (null != rb) {
+                try {
+                    result = rb.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 EL implementation: ???" + messageId + "???";
+                } catch (Exception e) {
+                    result = "Exception resolving message in EL 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<?> c,
+                                    Object[] params) {
+        Object[] parameters = buildParameters(
+                context, c.getParameterTypes(), c.isVarArgs(), params);;
+        try {
+            return c.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 method,
+                             Class<?>[] paramTypes,
+                             Object[] params,
+                             boolean staticOnly) {
+        Method m = findMethod(klass, method, paramTypes, params);
+        if (staticOnly && !Modifier.isStatic(m.getModifiers())) {
+            throw new MethodNotFoundException("Method " + method + "for class "
+                    + klass + " not found or accessible");
+        }
+
+        return m;
+    }
+
+    /*
+     * This method duplicates code in com.sun.el.util.ReflectionUtil. When
+     * making changes keep the code in sync.
+     */
+    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 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.
+     */
+    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 = "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<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 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;
+            } 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 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 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 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.
+     */
+    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
new file mode 100644
index 0000000..a26c9d9
--- /dev/null
+++ b/api/src/main/java/javax/el/EvaluationListener.java
@@ -0,0 +1,52 @@
+/*
+ * 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 javax.el;
+
+/**
+ * The listener interface for receiving notification when an
+ * EL expression is evaluated.
+ *
+ * @since EL 3.0
+ */
+public abstract class EvaluationListener {
+
+    /**
+     * Receives notification before an EL expression is evaluated
+     * @param context The ELContext
+     * @param expression The EL expression string to be evaluated
+     */
+    public void beforeEvaluation(ELContext context, String expression) {
+    }
+
+    /**
+     * Receives notification after an EL expression is evaluated
+     * @param context The ELContext
+     * @param expression The EL 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
new file mode 100644
index 0000000..dd6ba50
--- /dev/null
+++ b/api/src/main/java/javax/el/Expression.java
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+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 JSP 2.1
+ */
+public abstract class Expression
+        implements Serializable {
+    // Debugging
+    
+    /**
+     * 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)
+     */
+    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()
+     */
+    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 EL delimeters (<code>${...}</code> or
+     * <code>#{...}</code>).</p>
+     *
+     * @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
new file mode 100644
index 0000000..8f0e191
--- /dev/null
+++ b/api/src/main/java/javax/el/ExpressionFactory.java
@@ -0,0 +1,329 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.util.Map;
+import java.lang.reflect.Method;
+
+import java.util.Properties;
+
+/**
+ * Provides an implementation for creating and evaluating EL expressions.
+ *
+ * <p>Classes that implement the EL 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>
+ * <p>The {@link #newInstance} method can be used to obtain an
+ * instance of the implementation.
+ * Technologies such as
+ * JavaServer Pages and JavaServer Faces provide access to an
+ * implementation via factory methods.</p>
+ *
+ * <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>
+ *
+ * <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>
+ *
+ * <p>The ELContext object also provides access to the {@link FunctionMapper}
+ * and {@link VariableMapper} to be used when parsing the expression.
+ * EL 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>
+ *
+ * <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>
+ *
+ * <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>
+ *
+ * <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></p>
+ *
+ * @since JSP 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>
+     */
+    public static ExpressionFactory newInstance() {
+        return ExpressionFactory.newInstance(null);
+    }
+
+    /**
+     * <p>Create a new instance of a <code>ExpressionFactory</code>, with
+     * optional properties.
+     * This method uses the same lookup procedure as the one used in
+     * <code>newInstance()</code>.
+     * </p>
+     * <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>
+     * <p>
+     * Properties are optional and can be ignored by an implementation.
+     * </p>
+     * <p>The name of a property should start with "javax.el."</p>
+     * <p>
+     * The following are some suggested names for properties.
+     * <ul>
+     * <li>javax.el.cacheSize</li>
+     * </ul></p>
+     *
+     * @param properties Properties passed to the implementation.
+     *     If null, then no properties.
+     */
+    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>.</p>
+     *
+     * @param context The EL 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>.
+     *     <p>
+     *     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.</p>
+     * @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.  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.
+     *
+     * @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.
+     */
+    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>
+     * <p>This method should perform syntactic validation of the expression.
+     * If in doing so it detects errors, it should raise an
+     * <code>ELException</code>.</p>
+     *
+     * @param context The EL 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>.
+     *     <p>
+     *     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.</p>
+     *
+     * @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 arugments in the EL
+     *     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
+     * EL 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.
+     * </p>
+     *
+     * @param obj The object to coerce.
+     * @param targetType The target type for the coercion.
+     * @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 EL.2 for detailed descriptions of these operators, their
+     * arguments, and return values.</p>
+     *
+     * @return The <code>ELResolver</code> that implements the Query Operators.
+     *
+     * @since EL 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 EL 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
new file mode 100644
index 0000000..6a6e6f2
--- /dev/null
+++ b/api/src/main/java/javax/el/FactoryFinder.java
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.lang.reflect.Constructor;
+import java.io.InputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Properties;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+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 rd =
+                    new BufferedReader(new InputStreamReader(is, "UTF-8"));
+        
+                String factoryClassName = rd.readLine();
+                rd.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 configFile = javah + File.separator +
+                "lib" + File.separator + "el.properties";
+            File f=new File( configFile );
+            if( f.exists()) {
+                Properties props=new Properties();
+                props.load( new FileInputStream(f));
+                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
new file mode 100644
index 0000000..c3999c0
--- /dev/null
+++ b/api/src/main/java/javax/el/FunctionMapper.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.lang.reflect.Method;
+
+/**
+ * The interface to a map between EL 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.</p>
+ *
+ * @since JSP 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 EL 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
new file mode 100644
index 0000000..738031f
--- /dev/null
+++ b/api/src/main/java/javax/el/ImportHandler.java
@@ -0,0 +1,166 @@
+/*
+ * 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 javax.el;
+
+import java.util.Map;
+import java.util.List;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.lang.reflect.Modifier;
+
+/**
+ * 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<String, String>();
+    private Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
+    private Map<String, String> staticNameMap = new HashMap<String, String>();
+    private HashSet<String> notAClass = new HashSet<String>();
+    private List<String> packages = new ArrayList<String>();
+
+    {
+        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 (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)
+                || ! Modifier.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
new file mode 100644
index 0000000..5810002
--- /dev/null
+++ b/api/src/main/java/javax/el/LambdaExpression.java
@@ -0,0 +1,158 @@
+/*
+ * 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 javax.el;
+
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+/**
+ * <p>Encapsulates a parameterized {@link ValueExpression}.</p>
+ *
+ * <p>A <code>LambdaExpression</code> is a representation of the EL 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 EL expression containing
+ * a Lambda expression is evaluated.</p>
+ * <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.</p>
+ * @see ELContext#getLambdaArgument
+ * @see ELContext#enterLambdaScope
+ * @see ELContext#exitLambdaScope
+ */
+
+public class LambdaExpression {
+
+    private List<String> formalParameters = new ArrayList<String>();
+    private ValueExpression expression;
+    private ELContext context;
+    // Arguments from nesting lambdas, when the body is another lambda
+    private Map<String, Object> envirArgs = null;
+
+    /**
+     * 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<String, Object>();
+    }
+
+    /**
+     * 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<String, Object>();
+
+        // 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(this.context, args);
+    }
+}
diff --git a/api/src/main/java/javax/el/ListELResolver.java b/api/src/main/java/javax/el/ListELResolver.java
new file mode 100644
index 0000000..0b5ee1e
--- /dev/null
+++ b/api/src/main/java/javax/el/ListELResolver.java
@@ -0,0 +1,375 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.util.List;
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.ArrayList;
+import java.beans.FeatureDescriptor;
+
+
+/**
+ * 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 JSP 2.1
+ */
+public class ListELResolver extends ELResolver {
+
+    /**
+     * Creates a new read/write <code>ListELResolver</code>.
+     */
+    public ListELResolver() {
+        this.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.
+     */
+    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.
+     */
+    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.
+     */
+    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) 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;
+            }
+        }
+    }
+
+    static private Class<?> theUnmodifiableListClass =
+        Collections.unmodifiableList(new ArrayList<Object>()).getClass();
+
+    /**
+     * 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.
+     */
+    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>.
+     */
+    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>.
+     */
+    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();
+    }
+
+    private boolean isReadOnly;
+}
+
diff --git a/api/src/main/java/javax/el/MapELResolver.java b/api/src/main/java/javax/el/MapELResolver.java
new file mode 100644
index 0000000..bb2d9da
--- /dev/null
+++ b/api/src/main/java/javax/el/MapELResolver.java
@@ -0,0 +1,377 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * 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 JSP 2.1
+ */
+public class MapELResolver extends ELResolver {
+
+    /**
+     * Creates a new read/write <code>MapELResolver</code>.
+     */
+    public MapELResolver() {
+        this.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.
+     */
+    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.
+     */
+    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;
+    }
+
+    static private Class<?> theUnmodifiableMapClass =
+        Collections.unmodifiableMap(new HashMap<Object, Object>()).getClass();
+
+    /**
+     * 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.
+     */
+    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)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.
+     */
+    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:
+     * <dl>
+     *     <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>
+     * </dl>
+     * In addition, the following named attributes must be set in the
+     * returned <code>FeatureDescriptor</code>s:
+     * <dl>
+     *     <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>
+     * </dl>
+     * </p>
+     * 
+     * @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.
+     */
+    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<FeatureDescriptor>();
+            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", Boolean.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>.
+     */
+    public Class<?> getCommonPropertyType(ELContext context,
+                                       Object base) {
+        if (base != null && base instanceof Map) {
+            return Object.class;
+        }
+        return null;
+    }
+
+    private boolean isReadOnly;
+}
+
diff --git a/api/src/main/java/javax/el/MethodExpression.java b/api/src/main/java/javax/el/MethodExpression.java
new file mode 100644
index 0000000..d6928ab
--- /dev/null
+++ b/api/src/main/java/javax/el/MethodExpression.java
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+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 JSP 2.1
+ */
+public abstract class MethodExpression extends Expression
+{
+    // 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 EL specification).
+     * 
+     * If not a String literal, evaluates the expression 
+     * relative to the provided context, invokes the method that was 
+     * found using the supplied parameters, and returns the result of 
+     * the method invocation.
+     *
+     * Any parameters passed to this method is ignored if isLiteralText()
+     * or isParmetersProvided() is true.
+     *
+     * @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.</p>
+     *
+     * @return <code>true</code> if the MethodExpression was created with
+     *    parameters, <code>false</code> otherwise.
+     * @since EL 2.2
+     */
+    public boolean isParametersProvided() {
+        return false;
+    }
+
+    /**
+     * Use isParametersProvided instead.
+     */
+    @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
new file mode 100644
index 0000000..67273ff
--- /dev/null
+++ b/api/src/main/java/javax/el/MethodInfo.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+/**
+ * Holds information about a method that a {@link MethodExpression} 
+ * evaluated to.
+ *
+ * @since JSP 2.1
+ */
+public class MethodInfo {
+    
+    /** 
+     * 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 this.name;
+    }
+    
+    /**
+     * Returns the return type of the method
+     *
+     * @return the return type of the method
+     */
+    public Class<?> getReturnType() {
+        return this.returnType;
+    }
+    
+    /**
+     * Returns the parameter types of the method
+     *
+     * @return the parameter types of the method
+     */
+    public Class<?>[] getParamTypes() {
+        return this.paramTypes;
+    }
+    
+    private String name;
+    private Class<?> returnType;
+    private Class<?>[] paramTypes;
+}
diff --git a/api/src/main/java/javax/el/MethodNotFoundException.java b/api/src/main/java/javax/el/MethodNotFoundException.java
new file mode 100644
index 0000000..f708088
--- /dev/null
+++ b/api/src/main/java/javax/el/MethodNotFoundException.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+/**
+ * Thrown when a method could not be found while evaluating a
+ * {@link MethodExpression}.
+ *
+ * @see MethodExpression
+ * @since JSP 2.1
+ */
+public class MethodNotFoundException extends ELException {
+
+    /**
+     * 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
new file mode 100644
index 0000000..e628977
--- /dev/null
+++ b/api/src/main/java/javax/el/PrivateMessages.properties
@@ -0,0 +1,27 @@
+#
+# 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
new file mode 100644
index 0000000..5232feb
--- /dev/null
+++ b/api/src/main/java/javax/el/PropertyNotFoundException.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+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 JSP 2.1
+ */
+public class PropertyNotFoundException extends ELException {
+
+    //-------------------------------------
+    /**
+     * 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
new file mode 100644
index 0000000..1d17cf2
--- /dev/null
+++ b/api/src/main/java/javax/el/PropertyNotWritableException.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+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 JSP 2.1
+ */
+public class PropertyNotWritableException extends ELException {
+
+    //-------------------------------------
+    /**
+     * 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
new file mode 100644
index 0000000..233d648
--- /dev/null
+++ b/api/src/main/java/javax/el/ResourceBundleELResolver.java
@@ -0,0 +1,287 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+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>
+ * 
+ * <p>
+ * This resolver is read only and will throw a
+ * {@link PropertyNotWritableException} if <code>setValue</code> is called.
+ * </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.ResourceBundle
+ * @since JSP 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.
+     * </p>
+     * @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.
+     */
+    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>
+     */
+    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.
+     */
+    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 instanceof {@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>
+     */
+    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:
+     * <dl>
+     * <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>
+     * </dl>
+     * In addition, the following named attributes must be set in the returned
+     * <code>FeatureDescriptor</code>s:
+     * <dl>
+     * <li>{@link ELResolver#TYPE} - <code>String.class</code></li>
+     * <li>{@link ELResolver#RESOLVABLE_AT_DESIGN_TIME} - <code>true</code></li>
+     * </dl>
+     * </p>
+     * 
+     * @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.
+     */
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
+        if (base instanceof ResourceBundle) {
+            ResourceBundle bundle = (ResourceBundle) base;
+            List<FeatureDescriptor> features = new ArrayList<FeatureDescriptor>();
+            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, Boolean.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>.
+     */
+    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
new file mode 100644
index 0000000..fa901fc
--- /dev/null
+++ b/api/src/main/java/javax/el/StandardELContext.java
@@ -0,0 +1,284 @@
+/*
+ * 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 javax.el;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.reflect.Method;
+
+/**
+ * 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 EL 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-confured 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 = null;
+ 
+    /**
+     * A bean repository local to this context
+     */
+    private Map<String, Object> beans = new HashMap<String, Object>();
+
+    /**
+     * Construct a default ELContext for a stand-alone environment.
+     * @param factory The ExpressionFactory 
+     */
+    public StandardELContext(ExpressionFactory factory) {
+        this.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) {
+        this.delegate = context;
+        // Copy all attributes except map and resolved
+        CompositeELResolver elr = new CompositeELResolver();
+        elr.add(new BeanNameELResolver(new LocalBeanNameResolver()));
+        customResolvers = new CompositeELResolver();
+        elr.add(customResolvers);
+        elr.add(context.getELResolver());
+        elResolver = elr;
+
+        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 delegate.getContext(key);
+        } else {
+            return super.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>
+     * </p>
+     * @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 = null;
+
+        DefaultFunctionMapper(Map<String, Method> initMap){
+            functions = (initMap == null)?
+                               new HashMap<String, Method>():
+                               new HashMap<String, Method>(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 = null;
+
+        @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<String, ValueExpression>();
+            }
+            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
new file mode 100644
index 0000000..173b6ee
--- /dev/null
+++ b/api/src/main/java/javax/el/StaticFieldELResolver.java
@@ -0,0 +1,294 @@
+/*
+ * 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 javax.el;
+
+import java.util.Iterator;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Constructor;
+
+import java.beans.FeatureDescriptor;
+
+/**
+ * <p>An {@link ELResolver} for resolving static fields, enum constants and 
+ * static methods.  Also handles constructor calls as a special case.</p>
+ * <p>The resolver handles base objects of the type {@link ELClass}, which
+ * is usually generated by an EL implementation.</p>
+ *
+ * @see ELClass
+ * @since EL 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
+     */
+    @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(
+                        ELUtil.getExceptionMessageString(context,
+                            "staticFieldWriteError",
+                            new Object[] { klass.getName(), fieldName}));
+        }
+    }
+
+    /**
+     * <p>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>
+     * <p>Invoke the public static method specified by <code>method</code>.</p>
+     * <p>The process involved in the method selection is
+     * the same as that used in {@link BeanELResolver}.</p>
+     *
+     * <p>As a special case, if the name of the method is "&lt;init>", the
+     * constructor for the class will be invoked.</p>
+     *
+     * @param base An <code>ELClass</code>
+     * @param method 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 method,
+                         Class<?>[] paramTypes,
+                         Object[] params) {
+
+        if (context == null) {
+            throw new NullPointerException();
+        }
+
+        if (!(base instanceof ELClass && method instanceof String)) {
+            return null;
+        }
+
+        Class<?> klass = ((ELClass)base).getKlass();
+        String name = (String) method;
+
+        Object ret;
+        if ("<init>".equals(name)) {
+            Constructor<?> constructor =
+                ELUtil.findConstructor(klass, paramTypes, params);
+            ret = ELUtil.invokeConstructor(context, constructor, params);
+        } else {
+            Method meth =
+                ELUtil.findMethod(klass, name, paramTypes, params, true);
+            ret = ELUtil.invokeMethod(context, meth, null, params);
+        }
+        context.setPropertyResolved(base, method);
+        return ret;
+    }
+
+    /**
+     * <p>Returns the type of a static field.</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>
+     *
+     * If the property string is a public static field of class specified in
+     * ELClass, return the type of the static field.</p>
+     * @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 (Modifier.isPublic(mod) && Modifier.isStatic(mod)) {
+                    return field.getType();
+                }
+            } catch (NoSuchFieldException ex) {
+            }
+            throw new PropertyNotFoundException(
+                        ELUtil.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) {
+            Class<?> klass = ((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
new file mode 100644
index 0000000..8a6d86f
--- /dev/null
+++ b/api/src/main/java/javax/el/TypeConverter.java
@@ -0,0 +1,100 @@
+/*
+ * 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 javax.el;
+
+import java.util.Iterator;
+import java.beans.FeatureDescriptor;
+
+/**
+ * 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
+ * <blockquote><pre>
+ *     ELProcessor elp = new ELProcessor();
+ *     elp.getELManager().addELResolver(new TypeConverter() {
+ *         Object convertToType(ELContext context, Object obj, Class<?> type) {
+ *             if ((obj instanceof String) && type == MyDate.class) {
+ *                 context.setPropertyResolved(obj, type);
+ *                 return (obj == null)? null: new MyDate(obj.toString());
+ *             }
+ *             return null;
+ *         }
+ *      };
+ * </pre></blockquote>
+ *
+ * @since EL 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
new file mode 100644
index 0000000..433c210
--- /dev/null
+++ b/api/src/main/java/javax/el/ValueExpression.java
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+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 JSP 2.1
+ */
+public abstract class ValueExpression
+    extends Expression
+{
+    
+    /**
+     * 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.</p>
+     *
+     * @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.</p>
+     *
+     * @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 EL variable, return
+     * the <code>ValueReference</code> for the
+     * <code>ValueExpression</code> associated with this EL variable.
+     *
+     * @since EL 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
new file mode 100644
index 0000000..b5e5ce7
--- /dev/null
+++ b/api/src/main/java/javax/el/ValueReference.java
@@ -0,0 +1,46 @@
+/*
+ * 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
+ */
+
+package javax.el;
+
+import java.io.Serializable;
+
+/**
+ * This encapsulates a base model object and one of its properties.
+ *
+ * @since EL 2.2
+ */
+
+public class ValueReference implements Serializable {
+
+    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
new file mode 100644
index 0000000..0aae995
--- /dev/null
+++ b/api/src/main/java/javax/el/VariableMapper.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+package javax.el;
+
+/**
+ * The interface to a map between EL variables and the EL expressions
+ * they are associated with.
+ *
+ * @since JSP 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 EL 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
new file mode 100644
index 0000000..d66fe00
--- /dev/null
+++ b/api/src/main/java/javax/el/package.html
@@ -0,0 +1,243 @@
+<!--
+
+    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 the <strong>Unified Expression Language 3.0</strong>
+
+<p>The Expression Language (EL) is a simple language originally designed to
+satisfy the specific needs of web application developers. It has evloved
+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 Expression Language engine. The API
+is logically partitioned as follows:
+
+<ul>
+  <li><a href="#Context">EL 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">EL Functions</a></li>
+  <li><a href="#Variables">EL Variables</a></li>
+  <li><a href="#Standalone">EL in Stand-alone environment</li>
+</ul>
+
+<h3><a name="Context">EL Context</a></h3>
+
+<p>An important goal of the EL 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 EL 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 EL used in a web container, the creation of <code>ELContext
+</code> objects is controlled through the underlying technology.
+For example, in JSP, 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 the EL: <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 EL expression can represent a method
+invocation, such as <code>${trader.buy("JAVA")}</code>, where the arugments 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>. Morevover, 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 the EL.</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 an EL function 
+(for example <code>${fn:toUpperCase(customer.name)}</code>) or an
+EL variable, then  
+{@link javax.el.FunctionMapper} and {@link javax.el.VariableMapper}
+objects must be available within the <code>ELContext</code> so that EL functions and
+EL 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 JSF request processing life cycle, EL 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 EL 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, the EL 
+features a pluggable mechanism 
+to resolve model object references as well as properties and method
+invocations of these objects.</p>
+
+<p>The EL 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">EL Functions</a></h3>
+
+<p>If an EL 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">EL Variables</a></h3>
+
+<p>Just like {@link javax.el.FunctionMapper} provides
+a flexible mechanism to add functions to the EL, {@link javax.el.VariableMapper}
+provides a flexible mechanism to support the notion of 
+<strong>EL variables</strong>.
+</p>
+ 
+<p>
+An EL variable does not directly refer to a model object that can then
+be resolved by an <code>ELResolver</code>. Instead, it refers to an EL
+expression. The evaluation of that EL expression gives the EL 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 an EL 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 an EL variable because it does not refer directly to a model
+object.  Instead, it refers to another EL expression, namely a
+specific item in the collection referred to by the EL 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 an EL variable to the EL expression from which it gets its value.
+</p>
+
+<h3><a name="Standalone">EL in Stand-alone environment</a></h3>
+<p>EL 3.0 includes APIs for using EL 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 a beans locally.</p>
+
+<p>{@link javax.el.ELManager} provides a lower level APIs for managing the EL
+parsing and evaluation environment.  It contains a default ELContext
+{@link javax.el.StandardELContext}.</p>
+
+</body>
+</html>
+
diff --git a/exclude.xml b/exclude.xml
new file mode 100644
index 0000000..e25e681
--- /dev/null
+++ b/exclude.xml
@@ -0,0 +1,35 @@
+<!--
+
+    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
+
+-->
+
+<FindBugsFilter>
+    <Match>
+        <Class name="com.sun.el.parser.SimpleCharStream"/>
+    </Match>
+    <Match>
+        <Class name="com.sun.el.parser.ELParser"/>
+    </Match>
+    <Match>
+        <Class name="com.sun.el.parser.ELParserTokenManager"/>
+    </Match>
+    <Match>
+        <Class name="com.sun.el.parser.ELParserConstants"/>
+    </Match>
+    <Match>
+        <Class name="com.sun.el.parser.TokenMgrError"/>
+    </Match>
+</FindBugsFilter>
diff --git a/impl/build.xml b/impl/build.xml
new file mode 100644
index 0000000..2ed734c
--- /dev/null
+++ b/impl/build.xml
@@ -0,0 +1,45 @@
+<!--
+
+    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/src/main/java/com/sun/el/ExpressionFactoryImpl.java b/impl/src/main/java/com/sun/el/ExpressionFactoryImpl.java
new file mode 100644
index 0000000..24d1dc6
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/ExpressionFactoryImpl.java
@@ -0,0 +1,118 @@
+/*
+ * 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.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.lang.reflect.Method;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ExpressionFactory;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+import javax.el.ELResolver;
+
+import com.sun.el.lang.ExpressionBuilder;
+import com.sun.el.lang.ELSupport;
+import com.sun.el.util.MessageFactory;
+import com.sun.el.stream.StreamELResolver;
+
+/**
+ * @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 {
+
+    /**
+     * 
+     */
+    public ExpressionFactoryImpl() {
+        super();
+    }
+
+    public ExpressionFactoryImpl(Properties properties) {
+        super();
+        this.properties = properties;
+        this.isBackwardCompatible22 = "true".equals(getProperty("javax.el.bc2.2"));
+    }
+
+    public Object coerceToType(Object obj, Class type) {
+        Object ret;
+        try {
+            ret = ELSupport.coerceToType(obj, type, isBackwardCompatible22);
+        } catch (IllegalArgumentException ex) {
+            throw new ELException(ex);
+        }
+        return ret;
+    }
+
+    public MethodExpression createMethodExpression(ELContext context,
+            String expression, Class expectedReturnType,
+            Class[] expectedParamTypes) {
+        ExpressionBuilder builder = new ExpressionBuilder(expression, context);
+        MethodExpression me = builder.createMethodExpression(expectedReturnType,
+                expectedParamTypes);
+        if (expectedParamTypes == null && !me.isParametersProvided()) {
+            throw new NullPointerException(MessageFactory
+                    .get("error.method.nullParms"));
+        }
+        return me;
+    }
+
+    public ValueExpression createValueExpression(ELContext context,
+            String expression, Class expectedType) {
+        if (expectedType == null) {
+            throw new NullPointerException(MessageFactory
+                    .get("error.value.expectedType"));
+        }
+        ExpressionBuilder builder = new ExpressionBuilder(expression, context);
+        return builder.createValueExpression(expectedType);
+    }
+
+    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() {
+        Map<String, Method> funcs = new HashMap<String, Method>();
+        return funcs;
+    }
+
+    private Properties properties;
+    private boolean isBackwardCompatible22;
+}
diff --git a/impl/src/main/java/com/sun/el/Messages.properties b/impl/src/main/java/com/sun/el/Messages.properties
new file mode 100644
index 0000000..802a38a
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/Messages.properties
@@ -0,0 +1,79 @@
+#
+# 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
new file mode 100644
index 0000000..2f98e8b
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/MethodExpressionImpl.java
@@ -0,0 +1,326 @@
+/*
+ * 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.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 javax.el.EvaluationListener;
+
+import com.sun.el.lang.ELSupport;
+import com.sun.el.lang.EvaluationContext;
+import com.sun.el.lang.ExpressionBuilder;
+import com.sun.el.parser.Node;
+import com.sun.el.util.ReflectionUtil;
+
+/**
+ * An <code>Expression</code> that refers to a method on an object.
+ * 
+ * <p>
+ * <code>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 transient Node node;
+
+    private Class[] paramTypes;
+
+    /**
+     * 
+     */
+    public MethodExpressionImpl() {
+        super();
+    }
+
+    /**
+     * @param expr
+     * @param node
+     * @param fnMapper
+     * @param expectedType
+     * @param paramTypes
+     */
+    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)
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof MethodExpressionImpl) {
+            MethodExpressionImpl me = (MethodExpressionImpl) obj;
+            return getNode().equals(me.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()
+     */
+    public String getExpressionString() {
+        return this.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)
+     */
+    public MethodInfo getMethodInfo(ELContext context)
+            throws PropertyNotFoundException, MethodNotFoundException,
+            ELException {
+        Node n = this.getNode();
+        EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
+                this.varMapper);
+        return n.getMethodInfo(ctx, this.paramTypes);
+    }
+
+    /**
+     * @return The Node for the expression
+     * @throws ELException
+     */
+    private Node getNode() throws ELException {
+        if (this.node == null) {
+            this.node = ExpressionBuilder.createNode(this.expr);
+        }
+        return this.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()
+     */
+    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[])
+     */
+    public Object invoke(ELContext context, Object[] params)
+            throws PropertyNotFoundException, MethodNotFoundException,
+            ELException {
+        EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
+                this.varMapper);
+        ctx.notifyBeforeEvaluation(this.expr);
+        Object obj = this.getNode().invoke(ctx, this.paramTypes, params);
+        ctx.notifyAfterEvaluation(this.expr);
+        return obj;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
+     */
+    public void readExternal(ObjectInput in) throws IOException,
+            ClassNotFoundException {
+        this.expr = in.readUTF();
+        String type = in.readUTF();
+        if (!"".equals(type)) {
+            this.expectedType = ReflectionUtil.forName(type);
+        }
+        this.paramTypes = ReflectionUtil.toTypeArray(((String[]) in
+                .readObject()));
+        this.fnMapper = (FunctionMapper) in.readObject();
+        this.varMapper = (VariableMapper) in.readObject();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
+     */
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeUTF(this.expr);
+        out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
+                : "");
+        out.writeObject(ReflectionUtil.toTypeNameArray(this.paramTypes));
+        out.writeObject(this.fnMapper);
+        out.writeObject(this.varMapper);
+    }
+
+    public boolean isLiteralText() {
+        return false;
+    }
+
+    @Override
+    public boolean isParametersProvided() {
+        return this.getNode().isParametersProvided();
+    }
+}
+
diff --git a/impl/src/main/java/com/sun/el/MethodExpressionLiteral.java b/impl/src/main/java/com/sun/el/MethodExpressionLiteral.java
new file mode 100644
index 0000000..507076f
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/MethodExpressionLiteral.java
@@ -0,0 +1,98 @@
+/*
+ * 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.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.lang.ELSupport;
+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;
+    }
+
+    public MethodInfo getMethodInfo(ELContext context) throws ELException {
+        return new MethodInfo(this.expr, this.expectedType, this.paramTypes);
+    }
+
+    public Object invoke(ELContext context, Object[] params) throws ELException {
+        if (this.expectedType == null) {
+            return this.expr;
+        }
+
+        try {
+            return context.convertToType(this.expr, this.expectedType);
+        } catch (Exception ex) {
+            throw new ELException (ex);
+        }
+    }
+
+    public String getExpressionString() {
+        return this.expr;
+    }
+
+    public boolean equals(Object obj) {
+        return (obj instanceof MethodExpressionLiteral && this.hashCode() == obj.hashCode());
+    }
+
+    public int hashCode() {
+        return this.expr.hashCode();
+    }
+
+    public boolean isLiteralText() {
+        return true;
+    }
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        this.expr = in.readUTF();
+        String type = in.readUTF();
+        if (!"".equals(type)) {
+            this.expectedType = ReflectionUtil.forName(type);
+        }
+        this.paramTypes = ReflectionUtil.toTypeArray(((String[]) in
+                .readObject()));
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeUTF(this.expr);
+        out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
+                : "");
+        out.writeObject(ReflectionUtil.toTypeNameArray(this.paramTypes));
+    }
+}
diff --git a/impl/src/main/java/com/sun/el/ValueExpressionImpl.java b/impl/src/main/java/com/sun/el/ValueExpressionImpl.java
new file mode 100644
index 0000000..ec99876
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/ValueExpressionImpl.java
@@ -0,0 +1,284 @@
+/*
+ * 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.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.VariableMapper;
+import javax.el.ValueReference;
+import javax.el.EvaluationListener;
+
+import com.sun.el.lang.ELSupport;
+import com.sun.el.lang.EvaluationContext;
+import com.sun.el.lang.ExpressionBuilder;
+import com.sun.el.parser.AstLiteralExpression;
+import com.sun.el.parser.Node;
+import com.sun.el.util.ReflectionUtil;
+
+/**
+ * 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>
+ * <code>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)
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof ValueExpressionImpl) {
+            ValueExpressionImpl v = (ValueExpressionImpl) obj;
+            return getNode().equals(v.getNode());
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.el.ValueExpression#getExpectedType()
+     */
+    public Class getExpectedType() {
+        return this.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()
+     */
+    public String getExpressionString() {
+        return this.expr;
+    }
+
+    /**
+     * @return The Node for the expression
+     * @throws ELException
+     */
+    private Node getNode() throws ELException {
+        if (this.node == null) {
+            this.node = ExpressionBuilder.createNode(this.expr);
+        }
+        return this.node;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.el.ValueExpression#getType(javax.el.ELContext)
+     */
+    public Class getType(ELContext context) throws PropertyNotFoundException,
+            ELException {
+        EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
+                this.varMapper);
+        return this.getNode().getType(ctx);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.el.ValueExpression#getValueReference(javax.el.ELContext)
+     */
+    public ValueReference getValueReference(ELContext context)
+            throws PropertyNotFoundException, ELException {
+        EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
+                this.varMapper);
+        return this.getNode().getValueReference(ctx);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.el.ValueExpression#getValue(javax.el.ELContext)
+     */
+    public Object getValue(ELContext context) throws PropertyNotFoundException,
+            ELException {
+        EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
+                this.varMapper);
+        ctx.notifyBeforeEvaluation(this.expr);
+        Object value = this.getNode().getValue(ctx);
+        if (this.expectedType != null) {
+            try {
+                value = ctx.convertToType(value, this.expectedType);
+            } catch (IllegalArgumentException ex) {
+                throw new ELException(ex);
+            }
+        }
+        ctx.notifyAfterEvaluation(this.expr);
+        return value;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return getNode().hashCode();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.el.ValueExpression#isLiteralText()
+     */
+    public boolean isLiteralText() {
+        try {
+            return this.getNode() instanceof AstLiteralExpression;
+        } catch (ELException ele) {
+            return false;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.el.ValueExpression#isReadOnly(javax.el.ELContext)
+     */
+    public boolean isReadOnly(ELContext context)
+            throws PropertyNotFoundException, ELException {
+        EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
+                this.varMapper);
+        return this.getNode().isReadOnly(ctx);
+    }
+
+    public void readExternal(ObjectInput in) throws IOException,
+            ClassNotFoundException {
+        this.expr = in.readUTF();
+        String type = in.readUTF();
+        if (!"".equals(type)) {
+            this.expectedType = ReflectionUtil.forName(type);
+        }
+        this.fnMapper = (FunctionMapper) in.readObject();
+        this.varMapper = (VariableMapper) in.readObject();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see javax.el.ValueExpression#setValue(javax.el.ELContext,
+     *      java.lang.Object)
+     */
+    public void setValue(ELContext context, Object value)
+            throws PropertyNotFoundException, PropertyNotWritableException,
+            ELException {
+        EvaluationContext ctx = new EvaluationContext(context, this.fnMapper,
+                this.varMapper);
+        this.getNode().setValue(ctx, value);
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeUTF(this.expr);
+        out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
+                : "");
+        out.writeObject(this.fnMapper);
+        out.writeObject(this.varMapper);
+    }
+
+    public String toString() {
+        return "ValueExpression["+this.expr+"]";
+    }
+}
diff --git a/impl/src/main/java/com/sun/el/ValueExpressionLiteral.java b/impl/src/main/java/com/sun/el/ValueExpressionLiteral.java
new file mode 100644
index 0000000..82ed197
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/ValueExpressionLiteral.java
@@ -0,0 +1,116 @@
+/*
+ * 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.io.Externalizable;
+import java.io.IOException;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.PropertyNotWritableException;
+
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.el.ValueExpression;
+
+import com.sun.el.lang.ELSupport;
+import com.sun.el.util.MessageFactory;
+import com.sun.el.util.ReflectionUtil;
+
+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;
+    }
+
+    public Object getValue(ELContext context) {
+        if (this.expectedType != null) {
+            try {
+                return context.convertToType(this.value, this.expectedType);
+            } catch (IllegalArgumentException ex) {
+                throw new ELException(ex);
+            }
+        }
+        return this.value;
+    }
+
+    public void setValue(ELContext context, Object value) {
+        throw new PropertyNotWritableException(MessageFactory.get(
+                "error.value.literal.write", this.value));
+    }
+
+    public boolean isReadOnly(ELContext context) {
+        return true;
+    }
+
+    public Class getType(ELContext context) {
+        return (this.value != null) ? this.value.getClass() : null;
+    }
+
+    public Class getExpectedType() {
+        return this.expectedType;
+    }
+
+    public String getExpressionString() {
+        return (this.value != null) ? this.value.toString() : null;
+    }
+
+    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))));
+    }
+
+    public int hashCode() {
+        return (this.value != null) ? this.value.hashCode() : 0;
+    }
+
+    public boolean isLiteralText() {
+        return true;
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject(this.value);
+        out.writeUTF((this.expectedType != null) ? this.expectedType.getName()
+                : "");
+    }
+
+    public void readExternal(ObjectInput in) throws IOException,
+            ClassNotFoundException {
+        this.value = in.readObject();
+        String type = in.readUTF();
+        if (!"".equals(type)) {
+            this.expectedType = ReflectionUtil.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
new file mode 100644
index 0000000..c832f8a
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/lang/ELArithmetic.java
@@ -0,0 +1,376 @@
+/*
+ * 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.math.BigDecimal;
+import java.math.BigInteger;
+
+import com.sun.el.util.MessageFactory;
+
+/**
+ * A helper class of Arithmetic defined by the EL 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 {
+
+        protected Number add(Number num0, Number num1) {
+            return ((BigDecimal) num0).add((BigDecimal) num1);
+        }
+
+        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());
+        }
+
+        protected Number coerce(String str) {
+            return new BigDecimal(str);
+        }
+
+        protected Number divide(Number num0, Number num1) {
+            return ((BigDecimal) num0).divide((BigDecimal) num1,
+                    BigDecimal.ROUND_HALF_UP);
+        }
+
+        protected Number subtract(Number num0, Number num1) {
+            return ((BigDecimal) num0).subtract((BigDecimal) num1);
+        }
+
+        protected Number mod(Number num0, Number num1) {
+            return Double.valueOf(num0.doubleValue() % num1.doubleValue());
+        }
+
+        protected Number multiply(Number num0, Number num1) {
+            return ((BigDecimal) num0).multiply((BigDecimal) num1);
+        }
+
+        public boolean matches(Object obj0, Object obj1) {
+            return (obj0 instanceof BigDecimal || obj1 instanceof BigDecimal);
+        }
+    }
+
+    public final static class BigIntegerDelegate extends ELArithmetic {
+
+        protected Number add(Number num0, Number num1) {
+            return ((BigInteger) num0).add((BigInteger) num1);
+        }
+
+        protected Number coerce(Number num) {
+            if (num instanceof BigInteger)
+                return num;
+            return new BigInteger(num.toString());
+        }
+
+        protected Number coerce(String str) {
+            return new BigInteger(str);
+        }
+
+        protected Number divide(Number num0, Number num1) {
+            return (new BigDecimal((BigInteger) num0)).divide(new BigDecimal((BigInteger) num1), BigDecimal.ROUND_HALF_UP);
+        }
+
+        protected Number multiply(Number num0, Number num1) {
+            return ((BigInteger) num0).multiply((BigInteger) num1);
+        }
+
+        protected Number mod(Number num0, Number num1) {
+            return ((BigInteger) num0).mod((BigInteger) num1);
+        }
+
+        protected Number subtract(Number num0, Number num1) {
+            return ((BigInteger) num0).subtract((BigInteger) num1);
+        }
+
+        public boolean matches(Object obj0, Object obj1) {
+            return (obj0 instanceof BigInteger || obj1 instanceof BigInteger);
+        }
+    }
+
+    public final static class DoubleDelegate extends ELArithmetic {
+
+        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()));
+        	} else if (num1 instanceof BigDecimal) {
+        		return ((new BigDecimal(num0.doubleValue()).add((BigDecimal) num1)));
+        	}
+            return Double.valueOf(num0.doubleValue() + num1.doubleValue());
+        }
+
+        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());
+        }
+
+        protected Number coerce(String str) {
+            return Double.valueOf(str);
+        }
+
+        protected Number divide(Number num0, Number num1) {
+            return Double.valueOf(num0.doubleValue() / num1.doubleValue());
+        }
+
+        protected Number mod(Number num0, Number num1) {
+            return Double.valueOf(num0.doubleValue() % num1.doubleValue());
+        }
+
+        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()));
+        	} else if (num1 instanceof BigDecimal) {
+        		return ((new BigDecimal(num0.doubleValue()).subtract((BigDecimal) num1)));
+        	}
+            return Double.valueOf(num0.doubleValue() - num1.doubleValue());
+        }
+
+        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()));
+        	} else if (num1 instanceof BigDecimal) {
+        		return ((new BigDecimal(num0.doubleValue()).multiply((BigDecimal) num1)));
+        	}
+            return Double.valueOf(num0.doubleValue() * num1.doubleValue());
+        }
+
+        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 {
+
+        protected Number add(Number num0, Number num1) {
+            return Long.valueOf(num0.longValue() + num1.longValue());
+        }
+
+        protected Number coerce(Number num) {
+            if (num instanceof Long)
+                return num;
+            return Long.valueOf(num.longValue());
+        }
+
+        protected Number coerce(String str) {
+            return Long.valueOf(str);
+        }
+
+        protected Number divide(Number num0, Number num1) {
+            return Long.valueOf(num0.longValue() / num1.longValue());
+        }
+
+        protected Number mod(Number num0, Number num1) {
+            return Long.valueOf(num0.longValue() % num1.longValue());
+        }
+
+        protected Number subtract(Number num0, Number num1) {
+            return Long.valueOf(num0.longValue() - num1.longValue());
+        }
+
+        protected Number multiply(Number num0, Number num1) {
+            return Long.valueOf(num0.longValue() * num1.longValue());
+        }
+
+        public boolean matches(Object obj0, Object obj1) {
+            return (obj0 instanceof Long || obj1 instanceof Long);
+        }
+    }
+
+    public final static BigDecimalDelegate BIGDECIMAL = new BigDecimalDelegate();
+
+    public final static BigIntegerDelegate BIGINTEGER = new BigIntegerDelegate();
+
+    public final static DoubleDelegate DOUBLE = new DoubleDelegate();
+
+    public final static LongDelegate LONG = new LongDelegate();
+
+    private final static 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
new file mode 100644
index 0000000..945bf44
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/lang/ELSupport.java
@@ -0,0 +1,504 @@
+/*
+ * 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.ELContext;
+import javax.el.ELException;
+import javax.el.PropertyNotFoundException;
+
+import com.sun.el.util.MessageFactory;
+
+/**
+ * A helper class that implements the EL 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 EvaluationException
+     */
+    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 EvaluationException
+     */
+    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 to EL 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
new file mode 100644
index 0000000..26770bb
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/lang/EvaluationContext.java
@@ -0,0 +1,149 @@
+/*
+ * 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.EventListener;
+import java.util.List;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.VariableMapper;
+import javax.el.TypeConverter;
+import javax.el.ImportHandler;
+import javax.el.EvaluationListener;
+
+/**
+ * The context for EL expression evaluation.  This wrapper ELContext captures
+ * the function mapper and the variable mapper at the point when the epxression
+ * 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 this.elContext;
+    }
+
+    @Override
+    public FunctionMapper getFunctionMapper() {
+        return this.fnMapper;
+    }
+
+    @Override
+    public VariableMapper getVariableMapper() {
+        return this.varMapper;
+    }
+
+    @Override
+    public Object getContext(Class key) {
+        return this.elContext.getContext(key);
+    }
+
+    @Override
+    public ELResolver getELResolver() {
+        return this.elContext.getELResolver();
+    }
+
+    @Override
+    public boolean isPropertyResolved() {
+        return this.elContext.isPropertyResolved();
+    }
+
+    @Override
+    public void putContext(Class key, Object contextObject) {
+        this.elContext.putContext(key, contextObject);
+    }
+
+    @Override
+    public void setPropertyResolved(boolean resolved) {
+        this.elContext.setPropertyResolved(resolved);
+    }
+
+    @Override
+    public void setPropertyResolved(Object base, Object property) {
+        this.elContext.setPropertyResolved(base, property);
+    }
+
+    @Override
+    public void addEvaluationListener(EvaluationListener listener) {
+        this.elContext.addEvaluationListener(listener);
+    }
+
+    @Override
+    public List<EvaluationListener> getEvaluationListeners() {
+        return this.elContext.getEvaluationListeners();
+    }
+
+    @Override
+    public void notifyBeforeEvaluation(String expr) {
+        this.elContext.notifyBeforeEvaluation(expr);
+    }
+
+    @Override
+    public void notifyAfterEvaluation(String expr) {
+        this.elContext.notifyAfterEvaluation(expr);
+    }
+
+    @Override
+    public void notifyPropertyResolved(Object base, Object property) {
+        this.elContext.notifyPropertyResolved(base, property);
+    }
+
+    @Override
+    public boolean isLambdaArgument(String arg) {
+        return this.elContext.isLambdaArgument(arg);
+    }
+
+    @Override
+    public Object getLambdaArgument(String arg) {
+        return this.elContext.getLambdaArgument(arg);
+    }
+
+    @Override
+    public void enterLambdaScope(Map<String,Object> args) {
+        this.elContext.enterLambdaScope(args);
+    }
+
+    @Override
+    public void exitLambdaScope() {
+        this.elContext.exitLambdaScope();
+    }
+
+    @Override
+    public Object convertToType(Object obj, Class<?> targetType) {
+        return this.elContext.convertToType(obj, targetType);
+    }
+
+    @Override
+    public ImportHandler getImportHandler() {
+        return this.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
new file mode 100644
index 0000000..17552d1
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/lang/ExpressionBuilder.java
@@ -0,0 +1,291 @@
+/*
+ * 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.reflect.Method;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.lang.ref.ReferenceQueue;
+import java.util.Map;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentMap;
+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 final static Node createNode(String expr) throws ELException {
+        Node n = createNodeInternal(expr);
+        return n;
+    }
+
+    private final 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)
+     */
+    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 EL 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
new file mode 100644
index 0000000..49c7516
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/lang/FunctionMapperFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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)
+     */
+    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
new file mode 100644
index 0000000..34325ec
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/lang/FunctionMapperImpl.java
@@ -0,0 +1,198 @@
+/*
+ * 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)
+     */
+    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)
+     */
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject(this.functions);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
+     */
+    // Safe cast
+    @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)
+         */
+        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)
+         */
+        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)
+         */
+        public boolean equals(Object obj) {
+            if (obj instanceof Function) {
+                return this.hashCode() == obj.hashCode();
+            }
+            return false;
+        }
+        
+        /* (non-Javadoc)
+         * @see java.lang.Object#hashCode()
+         */
+        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
new file mode 100644
index 0000000..c6d6bab
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/lang/VariableMapperFactory.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+    }
+
+    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;
+    }
+
+    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
new file mode 100644
index 0000000..dac562f
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/lang/VariableMapperImpl.java
@@ -0,0 +1,58 @@
+/*
+ * 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();
+    }
+
+    public ValueExpression resolveVariable(String variable) {
+        return this.vars.get(variable);
+    }
+
+    public ValueExpression setVariable(String variable,
+            ValueExpression expression) {
+        return this.vars.put(variable, expression);
+    }
+
+    // Safe cast.
+    @SuppressWarnings("unchecked")
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        this.vars = (Map<String, ValueExpression>) in.readObject();
+    }
+
+    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
new file mode 100644
index 0000000..f776245
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/ArithmeticNode.java
@@ -0,0 +1,40 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..04622b6
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstAnd.java
@@ -0,0 +1,43 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..f9f7c36
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstAssign.java
@@ -0,0 +1,38 @@
+/*
+ * 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.VariableMapper;
+import com.sun.el.ValueExpressionImpl;
+import com.sun.el.lang.EvaluationContext;
+
+public
+class AstAssign extends SimpleNode {
+    public AstAssign(int id) {
+        super(id);
+    }
+
+    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
new file mode 100644
index 0000000..9c72d80
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstBracketSuffix.java
@@ -0,0 +1,37 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..1bb9591
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstChoice.java
@@ -0,0 +1,70 @@
+/*
+ * 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);
+    }
+
+    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);
+    }
+
+    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);
+    }
+
+    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);
+    }
+
+    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);
+    }
+
+    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
new file mode 100644
index 0000000..4c624f6
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstCompositeExpression.java
@@ -0,0 +1,52 @@
+/*
+ * 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);
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return String.class;
+    }
+
+    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
new file mode 100644
index 0000000..00e1097
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstConcat.java
@@ -0,0 +1,37 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..977930f
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstDeferredExpression.java
@@ -0,0 +1,51 @@
+/*
+ * 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);
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return this.children[0].getType(ctx);
+    }
+
+    public Object getValue(EvaluationContext ctx)
+            throws ELException {
+        return this.children[0].getValue(ctx);
+    }
+
+    public boolean isReadOnly(EvaluationContext ctx)
+            throws ELException {
+        return this.children[0].isReadOnly(ctx);
+    }
+
+    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
new file mode 100644
index 0000000..aa677e0
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstDiv.java
@@ -0,0 +1,39 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..abd69ca
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstDotSuffix.java
@@ -0,0 +1,36 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..653ec2a
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstDynamicExpression.java
@@ -0,0 +1,51 @@
+/*
+ * 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);
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return this.children[0].getType(ctx);
+    }
+
+    public Object getValue(EvaluationContext ctx)
+            throws ELException {
+        return this.children[0].getValue(ctx);
+    }
+
+    public boolean isReadOnly(EvaluationContext ctx)
+            throws ELException {
+        return this.children[0].isReadOnly(ctx);
+    }
+
+    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
new file mode 100644
index 0000000..0b42bee
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstEmpty.java
@@ -0,0 +1,56 @@
+/*
+ * 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);
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return Boolean.class;
+    }
+
+    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
new file mode 100644
index 0000000..a799058
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstEqual.java
@@ -0,0 +1,38 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..71b51b9
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstFalse.java
@@ -0,0 +1,36 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..b416907
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstFloatingPoint.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+    }
+
+    public Object getValue(EvaluationContext ctx)
+            throws ELException {
+        return this.getFloatingPoint();
+    }
+
+    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
new file mode 100644
index 0000000..f89bf9a
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstFunction.java
@@ -0,0 +1,206 @@
+/*
+ * 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.ELException;
+import javax.el.FunctionMapper;
+import javax.el.LambdaExpression;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+import javax.el.ELClass;
+
+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 EL 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
new file mode 100644
index 0000000..adce813
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstGreaterThan.java
@@ -0,0 +1,44 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..af6dc71
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstGreaterThanEqual.java
@@ -0,0 +1,44 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..1ce74ba
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstIdentifier.java
@@ -0,0 +1,215 @@
+/*
+ * 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.ELResolver;
+import javax.el.MethodExpression;
+import javax.el.MethodInfo;
+import javax.el.MethodNotFoundException;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+import javax.el.ValueReference;
+import javax.el.PropertyNotWritableException;
+import javax.el.ELClass;
+
+import com.sun.el.lang.EvaluationContext;
+import com.sun.el.lang.ELSupport;
+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;
+    }
+
+    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;
+    }
+
+    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;
+    }
+
+    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 final 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());
+        }
+    }
+
+    public Object invoke(EvaluationContext ctx, Class[] paramTypes,
+            Object[] paramValues) throws ELException {
+        return this.getMethodExpression(ctx).invoke(ctx.getELContext(), paramValues);
+    }
+    
+
+    public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes)
+            throws ELException {
+        return this.getMethodExpression(ctx).getMethodInfo(ctx.getELContext());
+    }
+
+    private final 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
new file mode 100644
index 0000000..866ff2d
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstInteger.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return this.getInteger().getClass();
+    }
+
+    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
new file mode 100644
index 0000000..ab2461e
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstLambdaExpression.java
@@ -0,0 +1,67 @@
+/*
+ * 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.ValueExpression;
+import javax.el.LambdaExpression;
+import com.sun.el.lang.EvaluationContext;
+import com.sun.el.ValueExpressionImpl;
+import com.sun.el.util.MessageFactory;
+
+/**
+ * @author Kin-man Chung
+ */
+public
+class AstLambdaExpression extends SimpleNode {
+
+    public AstLambdaExpression(int id) {
+      super(id);
+    }
+
+    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
new file mode 100644
index 0000000..1573bd3
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstLambdaParameters.java
@@ -0,0 +1,41 @@
+/*
+ * 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 java.util.ArrayList;
+
+/**
+ * @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
new file mode 100644
index 0000000..bcc2294
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstLessThan.java
@@ -0,0 +1,44 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..4408c38
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstLessThanEqual.java
@@ -0,0 +1,44 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..f8d8a51
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstListData.java
@@ -0,0 +1,39 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..168fb8f
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstLiteralExpression.java
@@ -0,0 +1,61 @@
+/*
+ * 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);
+    }
+
+    public Class getType(EvaluationContext ctx) throws ELException {
+        return String.class;
+    }
+
+    public Object getValue(EvaluationContext ctx) throws ELException {
+        return this.image;
+    }
+
+    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
new file mode 100644
index 0000000..e08ae32
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstMapData.java
@@ -0,0 +1,57 @@
+/*
+ * 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.HashSet;
+import java.util.HashMap;
+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);
+    }
+
+    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
new file mode 100644
index 0000000..0e9b256
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstMapEntry.java
@@ -0,0 +1,27 @@
+/*
+ * 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
new file mode 100644
index 0000000..c67d452
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstMethodArguments.java
@@ -0,0 +1,56 @@
+/*
+ * 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
new file mode 100644
index 0000000..6b5d11b
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstMinus.java
@@ -0,0 +1,39 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..b7c0e85
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstMod.java
@@ -0,0 +1,39 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..a3f4265
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstMult.java
@@ -0,0 +1,39 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..4518150
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstNegative.java
@@ -0,0 +1,81 @@
+/*
+ * 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);
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return Number.class;
+    }
+
+    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
new file mode 100644
index 0000000..94f3a15
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstNot.java
@@ -0,0 +1,43 @@
+/*
+ * 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);
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return Boolean.class;
+    }
+
+    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
new file mode 100644
index 0000000..5fa4d60
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstNotEqual.java
@@ -0,0 +1,38 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..4ece392
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstNull.java
@@ -0,0 +1,41 @@
+/*
+ * 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);
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return null;
+    }
+
+    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
new file mode 100644
index 0000000..94d4024
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstOr.java
@@ -0,0 +1,43 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..5433418
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstPlus.java
@@ -0,0 +1,40 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..b787831
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstSemiColon.java
@@ -0,0 +1,42 @@
+/*
+ * 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);
+    }
+
+    public Object getValue(EvaluationContext ctx)
+            throws ELException {
+        this.children[0].getValue(ctx);
+        return this.children[1].getValue(ctx);
+    }
+
+    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
new file mode 100644
index 0000000..f533ccc
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstString.java
@@ -0,0 +1,72 @@
+/*
+ * 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;
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        return String.class;
+    }
+
+    public Object getValue(EvaluationContext ctx)
+            throws ELException {
+        return this.getString();
+    }
+
+    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
new file mode 100644
index 0000000..28b5584
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstTrue.java
@@ -0,0 +1,36 @@
+/*
+ * 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);
+    }
+
+    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
new file mode 100644
index 0000000..12fc5aa
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/AstValue.java
@@ -0,0 +1,272 @@
+/*
+ * 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.ELException;
+import javax.el.ELResolver;
+import javax.el.MethodInfo;
+import javax.el.ValueReference;
+import javax.el.ELClass;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.el.ImportHandler;
+
+import com.sun.el.lang.EvaluationContext;
+import com.sun.el.lang.ELSupport;
+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);
+    }
+
+    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;
+    }
+
+    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 final 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 final 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]);
+    }
+
+    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;
+    }
+
+    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;
+    }
+
+    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);
+        }
+    }
+
+    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());
+    }
+
+    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
new file mode 100644
index 0000000..6a91a2e
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/BooleanNode.java
@@ -0,0 +1,38 @@
+/*
+ * 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);
+    }
+    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
new file mode 100644
index 0000000..8321548
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/ELParser.java
@@ -0,0 +1,3029 @@
+/*
+ * 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);
+          }
+    }
+  }
+
+/*
+ * Expression
+ * EL Expression Language 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
new file mode 100644
index 0000000..703f6ef
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/ELParser.jjt
@@ -0,0 +1,573 @@
+/*
+ * 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
new file mode 100644
index 0000000..1106e0d
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/ELParserConstants.java
@@ -0,0 +1,218 @@
+/*
+ * 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
new file mode 100644
index 0000000..7d04aec
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/ELParserTokenManager.java
@@ -0,0 +1,2079 @@
+/*
+ * 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;
+import java.io.StringReader;
+import javax.el.ELException;
+
+/** 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 = (int)(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 = (int)(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 = (int)(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
new file mode 100644
index 0000000..aa6def4
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/ELParserTreeConstants.java
@@ -0,0 +1,111 @@
+/*
+ * 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
+{
+  public int JJTCOMPOSITEEXPRESSION = 0;
+  public int JJTLITERALEXPRESSION = 1;
+  public int JJTDEFERREDEXPRESSION = 2;
+  public int JJTDYNAMICEXPRESSION = 3;
+  public int JJTVOID = 4;
+  public int JJTSEMICOLON = 5;
+  public int JJTASSIGN = 6;
+  public int JJTLAMBDAEXPRESSION = 7;
+  public int JJTLAMBDAPARAMETERS = 8;
+  public int JJTCHOICE = 9;
+  public int JJTOR = 10;
+  public int JJTAND = 11;
+  public int JJTEQUAL = 12;
+  public int JJTNOTEQUAL = 13;
+  public int JJTLESSTHAN = 14;
+  public int JJTGREATERTHAN = 15;
+  public int JJTLESSTHANEQUAL = 16;
+  public int JJTGREATERTHANEQUAL = 17;
+  public int JJTCONCAT = 18;
+  public int JJTPLUS = 19;
+  public int JJTMINUS = 20;
+  public int JJTMULT = 21;
+  public int JJTDIV = 22;
+  public int JJTMOD = 23;
+  public int JJTNEGATIVE = 24;
+  public int JJTNOT = 25;
+  public int JJTEMPTY = 26;
+  public int JJTVALUE = 27;
+  public int JJTDOTSUFFIX = 28;
+  public int JJTBRACKETSUFFIX = 29;
+  public int JJTMETHODARGUMENTS = 30;
+  public int JJTMAPDATA = 31;
+  public int JJTMAPENTRY = 32;
+  public int JJTLISTDATA = 33;
+  public int JJTIDENTIFIER = 34;
+  public int JJTFUNCTION = 35;
+  public int JJTTRUE = 36;
+  public int JJTFALSE = 37;
+  public int JJTFLOATINGPOINT = 38;
+  public int JJTINTEGER = 39;
+  public int JJTSTRING = 40;
+  public int JJTNULL = 41;
+
+
+  public 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
new file mode 100644
index 0000000..e348d83
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/JJTELParserState.java
@@ -0,0 +1,139 @@
+/*
+ * 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
new file mode 100644
index 0000000..a568950
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/Node.java
@@ -0,0 +1,74 @@
+/*
+ * 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. */
+  public void jjtOpen();
+
+  /** This method is called after all the child nodes have been
+    added. */
+  public void jjtClose();
+
+  /** This pair of methods are used to inform the node of its
+    parent. */
+  public void jjtSetParent(Node n);
+  public Node jjtGetParent();
+
+  /** This method tells the node to add its argument to the node's
+    list of children.  */
+  public void jjtAddChild(Node n, int i);
+
+  /** This method returns a child node.  The children are numbered
+     from zero, left to right. */
+  public Node jjtGetChild(int i);
+
+  /** Return the number of children the node has. */
+  public int jjtGetNumChildren();
+  
+  public String getImage();
+  
+  public Object getValue(EvaluationContext ctx) throws ELException;
+  public void setValue(EvaluationContext ctx, Object value) throws ELException;
+  public Class getType(EvaluationContext ctx) throws ELException;
+  public ValueReference getValueReference(EvaluationContext ctx)
+             throws ELException;
+  public boolean isReadOnly(EvaluationContext ctx) throws ELException;
+  public void accept(NodeVisitor visitor) throws ELException;
+  public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes) throws ELException;
+  public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException;
+
+  public boolean equals(Object n);
+  public int hashCode();
+  public 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
new file mode 100644
index 0000000..d71a2ec
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/NodeVisitor.java
@@ -0,0 +1,27 @@
+/*
+ * 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 {
+    public 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
new file mode 100644
index 0000000..70b7dd1
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/ParseException.java
@@ -0,0 +1,207 @@
+/*
+ * 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.
+   */
+  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
new file mode 100644
index 0000000..816e5b9
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/SimpleCharStream.java
@@ -0,0 +1,487 @@
+/*
+ * 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
new file mode 100644
index 0000000..8f836f4
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/SimpleNode.java
@@ -0,0 +1,220 @@
+/*
+ * 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 javax.el.PropertyNotWritableException;
+
+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;
+    }
+
+    public void jjtOpen() {
+    }
+
+    public void jjtClose() {
+    }
+
+    public void jjtSetParent(Node n) {
+        parent = n;
+    }
+
+    public Node jjtGetParent() {
+        return parent;
+    }
+
+    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;
+    }
+
+    public Node jjtGetChild(int i) {
+        return children[i];
+    }
+
+    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.
+     */
+
+    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 + " ");
+                }
+            }
+        }
+    }
+
+    public String getImage() {
+        return image;
+    }
+
+    public void setImage(String image) {
+        this.image = image;
+    }
+
+    public Class getType(EvaluationContext ctx)
+            throws ELException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getValue(EvaluationContext ctx)
+            throws ELException {
+        throw new UnsupportedOperationException();
+    }
+
+    public ValueReference getValueReference(EvaluationContext ctx)
+            throws ELException {
+        return null;
+    }
+
+    public boolean isReadOnly(EvaluationContext ctx)
+            throws ELException {
+        return true;
+    }
+
+    public void setValue(EvaluationContext ctx, Object value)
+            throws ELException {
+        throw new PropertyNotWritableException(MessageFactory.get("error.syntax.set"));
+    }
+
+    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);
+            }
+        }
+    }
+
+    public Object invoke(EvaluationContext ctx, Class[] paramTypes, Object[] paramValues) throws ELException {
+        throw new UnsupportedOperationException();
+    }
+
+    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
new file mode 100644
index 0000000..98777c0
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/Token.java
@@ -0,0 +1,98 @@
+/*
+ * 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.
+   */
+  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
new file mode 100644
index 0000000..bcfe037
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/parser/TokenMgrError.java
@@ -0,0 +1,148 @@
+/*
+ * 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.
+    */
+   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
new file mode 100644
index 0000000..4793ce3
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/stream/Operator.java
@@ -0,0 +1,24 @@
+/*
+ * 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
new file mode 100644
index 0000000..1cae95c
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/stream/Optional.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+import java.util.Comparator;
+
+import javax.el.ELContext;
+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
new file mode 100644
index 0000000..4e7f4a6
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/stream/Stream.java
@@ -0,0 +1,564 @@
+/*
+ * 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 com.sun.el.lang.ELSupport;
+import com.sun.el.lang.ELArithmetic;
+
+import java.lang.reflect.Array;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Set;
+
+import javax.el.ELException;
+import javax.el.LambdaExpression;
+
+
+/*
+ */
+
+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
new file mode 100644
index 0000000..bb29e83
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/stream/StreamELResolver.java
@@ -0,0 +1,129 @@
+/*
+ * 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.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.lang.reflect.Array;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.LambdaExpression;
+
+/*
+ * This ELResolver intercepts method calls to a Collections, to provide
+ * support for collection operations. 
+ */
+
+public class StreamELResolver extends ELResolver {
+
+    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;
+    }
+*/
+    public Object getValue(ELContext context, Object base, Object property) {
+        return null;
+    }
+
+    public Class<?> getType(ELContext context, Object base, Object property) {
+        return null;
+    }
+
+    public void setValue(ELContext context, Object base, Object property,
+                                  Object value) {
+    }
+
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+        return false;
+    }
+
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(
+                                            ELContext context,
+                                            Object base) {
+        return null;
+    }
+
+    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
new file mode 100644
index 0000000..293b040
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/util/MessageFactory.java
@@ -0,0 +1,70 @@
+/*
+ * 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
new file mode 100644
index 0000000..7ea8987
--- /dev/null
+++ b/impl/src/main/java/com/sun/el/util/ReflectionUtil.java
@@ -0,0 +1,752 @@
+/*
+ * 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.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.InvocationTargetException;
+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/nb-configuration.xml b/nb-configuration.xml
new file mode 100644
index 0000000..72bf4d8
--- /dev/null
+++ b/nb-configuration.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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
+
+-->
+
+<project-shared-configuration>
+    <!--
+This file contains additional configuration written by modules in the NetBeans IDE.
+The configuration is intended to be shared among all the users of project and
+therefore it is assumed to be part of version control checkout.
+Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+-->
+    <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
+        <!--
+Properties that influence various parts of the IDE, especially code formatting and the like. 
+You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+That way multiple projects can share the same settings (useful for formatting rules for example).
+Any value defined here will override the pom.xml file value but is only applicable to the current project.
+-->
+        <netbeans.compile.on.save>all</netbeans.compile.on.save>
+    </properties>
+</project-shared-configuration>
diff --git a/parent-pom/pom.xml b/parent-pom/pom.xml
new file mode 100644
index 0000000..26c74f5
--- /dev/null
+++ b/parent-pom/pom.xml
@@ -0,0 +1,150 @@
+<?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/pom.xml b/pom.xml
new file mode 100644
index 0000000..abc1fc6
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,391 @@
+<?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">
+    
+    <parent>
+      <groupId>org.eclipse.ee4j</groupId>
+      <artifactId>project</artifactId>
+      <version>1.0</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.glassfish</groupId>
+    <artifactId>javax.el</artifactId>
+    <version>3.0.1-b11-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <name>Expression Language 3.0</name>
+
+    <properties>
+        <!-- the bundle build number must be the same as the maven number -->
+        <bundle.version>3.0.0</bundle.version>
+        <!-- The most current api version -->
+        <spec.version>3.0</spec.version>
+        <extensionName>javax.el</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>
+
+    <description>Expression Language (JSR 341) Reference Implementation</description>
+    <url>https://projects.eclipse.org/projects/ee4j.el</url>
+
+
+    <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>EL 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>
+        <plugins>
+            <!-- Use this to include both the api and impl sources -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.1</version>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>api/src/main/java</source>
+                                <source>impl/src/main/java</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- 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>
+                            Expression Language ${spec.version} API and 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>
+                    </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-source-plugin</artifactId>
+                <version> 2.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>
+                <version>2.8.1</version>
+                <executions>
+                    <execution>
+                        <id>attach-javadocs</id>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        <configuration>
+                            <sourcepath>api/src;impl/src</sourcepath>
+                            <groups>
+                                <group>
+                                    <title>Expresion Language 3.0 API and 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>
+                    <!--
+                    <parallel>classes</parallel>
+                    -->
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.glassfish.copyright</groupId>
+                <artifactId>glassfish-copyright-maven-plugin</artifactId>
+                <version>1.32</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-remote-resources-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                  <execution>
+                    <goals>
+                      <goal>process</goal>
+                    </goals>
+                    <configuration>
+                      <resourceBundles>
+                        <resourceBundle>org.glassfish:legal:1.1</resourceBundle>
+                      </resourceBundles>
+                    </configuration>
+                  </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <resources>
+            <resource>
+                <directory>api/src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>impl/src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                </includes>
+            </resource>
+        </resources>
+    </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>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>licensee</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>wagon-maven-plugin</artifactId>
+                        <version>1.0-beta-4</version>
+                        <inherited>false</inherited>
+                        <executions>
+                            <execution>
+                                <id>get-license</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>download-single</goal>
+                                </goals>
+                                <configuration>
+                                    <url>${tlda-license.url}</url>
+                                    <fromFile>
+                                        TLDA_SCSL_Licensees_License_Notice.txt
+                                    </fromFile>
+                                    <toDir>${project.build.directory}/license</toDir>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <version>2.4</version>
+                        <inherited>false</inherited>
+                        <executions>
+                            <execution>
+                                <id>make-licensee-src-assembly</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <finalName>el-${project.version}-src</finalName>
+                                    <attach>false</attach>
+                                    <appendAssemblyId>false</appendAssemblyId>
+                                    <descriptors>
+                                        <descriptor>src/assembly/assembly.xml</descriptor>
+                                    </descriptors>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/src/assembly/assembly.xml b/src/assembly/assembly.xml
new file mode 100644
index 0000000..8780af6
--- /dev/null
+++ b/src/assembly/assembly.xml
@@ -0,0 +1,45 @@
+<!--
+
+    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
new file mode 100644
index 0000000..814e924
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/ConvertTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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
new file mode 100644
index 0000000..533ec01
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/Customer.java
@@ -0,0 +1,54 @@
+/*
+ * 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
new file mode 100644
index 0000000..51daab7
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/DataBase.java
@@ -0,0 +1,102 @@
+/*
+ * 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
new file mode 100644
index 0000000..f202fb2
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/Date.java
@@ -0,0 +1,35 @@
+/*
+ * 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
new file mode 100644
index 0000000..3381e7d
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/ELProcessorTest.java
@@ -0,0 +1,190 @@
+/*
+ * 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
new file mode 100644
index 0000000..3da7dce
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/ElasticityTest.java.sav
@@ -0,0 +1,146 @@
+/*
+ * 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
new file mode 100644
index 0000000..410bde2
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/EvalListenerTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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
new file mode 100644
index 0000000..2734e0c
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/LambdaTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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
new file mode 100644
index 0000000..a9d512f
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/OperatorTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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
new file mode 100644
index 0000000..6ebfeaf
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/Order.java
@@ -0,0 +1,42 @@
+/*
+ * 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
new file mode 100644
index 0000000..c0a3aa4
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/OverloadedMethodTest.java
@@ -0,0 +1,279 @@
+/*
+ * 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
new file mode 100644
index 0000000..72d9cd5
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/Product.java
@@ -0,0 +1,48 @@
+/*
+ * 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
new file mode 100644
index 0000000..4c8df7b
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/StaticRefTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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
new file mode 100644
index 0000000..e8c5ef6
--- /dev/null
+++ b/src/test/java/org/glassfish/el/test/StreamTest.java
@@ -0,0 +1,283 @@
+/*
+ * 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
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/uel/.gitkeep
