Fix #175 - add support for array length as a property of an array
diff --git a/api/src/main/java/jakarta/el/ArrayELResolver.java b/api/src/main/java/jakarta/el/ArrayELResolver.java
index 445f6e8..0da612c 100644
--- a/api/src/main/java/jakarta/el/ArrayELResolver.java
+++ b/api/src/main/java/jakarta/el/ArrayELResolver.java
@@ -45,6 +45,8 @@
  */
 public class ArrayELResolver extends ELResolver {
 
+    private static final String LENGTH_PROPERTY_NAME = "length";
+
     /**
      * Creates a new read/write <code>ArrayELResolver</code>.
      */
@@ -116,23 +118,27 @@
     }
 
     /**
-     * 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.
+     * If the base object is a Java language array, returns the length of the array or the value at the given index. If
+     * the {@code property} argument is the case sensitive string {@code "length"}, then the length of the array is
+     * returned. Otherwise, the {@code property} argument is coerced into an integer and used as the index of the value
+     * to be returned. If the coercion could not be performed, an {@code IllegalArgumentException} is thrown. If the
+     * index is out of bounds, {@code null} 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.
+     * If the base is a Java language array, the {@code propertyResolved} property of the {@code ELContext} object must
+     * be set to {@code true} by this resolver, before returning. If this property is not {@code true} 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>.
+     * @param property Either the string {@code "length"} or the index of the value to be returned. An index value will
+     * be coerced into an integer.
+     * @return If the {@code propertyResolved} property of {@code ELContext} was set to {@code true}, then the length of
+     * the array, the value at the given index or {@code null} if the index was out of bounds. Otherwise, undefined.
+     * @throws IllegalArgumentException if the property was not the string {@code "length"} and could not be coerced
+     * into an integer.
+     * @throws NullPointerException if context is {@code null}.
      * @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.
      */
@@ -145,6 +151,9 @@
 
         if (base != null && base.getClass().isArray()) {
             context.setPropertyResolved(base, property);
+            if (LENGTH_PROPERTY_NAME.equals(property)) {
+                return Integer.valueOf(Array.getLength(base));
+            }
             int index = toInteger(property);
             if (index >= 0 && index < Array.getLength(base)) {
                 return Array.get(base, index);
diff --git a/spec/src/main/asciidoc/ELSpec.adoc b/spec/src/main/asciidoc/ELSpec.adoc
index e502dab..434ff4c 100644
--- a/spec/src/main/asciidoc/ELSpec.adoc
+++ b/spec/src/main/asciidoc/ELSpec.adoc
@@ -1269,6 +1269,14 @@
 the `Spade` enum, you would say `${mySuit == 'Spade'}`. The type of the
 `mySuit` will trigger the invocation of `Enum.valueOf(Suit.class, 'Spade')`.
 
+
+=== Arrays
+
+In addition to accessing array elements by index, the unified EL also supports
+the property `length` for arrays which will return the length of the array as an
+integer.
+
+
 === Static Field and Method Reference
 
 A static field or static method of a Java
@@ -3026,6 +3034,10 @@
 
 * Add a JPMS module descriptor that defines the module name as `jakarta.el`.
 
+* https://github.com/jakartaee/expression-language/issues/175[#175]
+  Add a special case for the property `length` to the `ArrayELResolver` that
+  returns the length of the array.
+
 * https://github.com/jakartaee/expression-language/issues/183[#183]
   Avoid a `NullPointerException` when passing `null` for varargs.