static Optional<Object> coerceParam(Class<?> currentIdxActualParameterType, Class<?> expectedParameterType,
                                        Object actualObject) {
        /* 10.3.2.9.4 Type conversions
           from singleton list:
           When the type of the expression is List<T>, the value of the expression is a singleton list and the target
           type is T, the expression is converted by unwrapping the first element. */
        if (Collection.class.isAssignableFrom(currentIdxActualParameterType)) {
            Collection<?> valueCollection = (Collection<?>) actualObject;
            if (valueCollection.size() == 1) {
                Object singletonValue = valueCollection.iterator().next();
                // re-perform the assignable-from check, this time using the element itself the singleton value from
                // the original parameter list
                if (singletonValue != null) {
                    return expectedParameterType.isAssignableFrom(singletonValue.getClass()) ?
                            Optional.of(singletonValue) :
                            coerceParam(singletonValue.getClass(), expectedParameterType, singletonValue);
                }
            }
        }
        /* to singleton list:
           When the type of the expression is T and the target type is List<T> the expression is converted to a
           singleton list. */
        if (!Collection.class.isAssignableFrom(currentIdxActualParameterType) &&
                Collection.class.isAssignableFrom(expectedParameterType)) {
            Object singletonValue = coerceParam(currentIdxActualParameterType, currentIdxActualParameterType, actualObject)
                    .orElse(actualObject);
            return Optional.of(Collections.singletonList(singletonValue));
        }
        /* from date to date and time
            When the type of the expression is date and the target type is date and time, the expression is converted
            to a date time value in which the time of day is UTC midnight (00:00:00)
         */
        if (actualObject instanceof LocalDate localDate &&
                ZonedDateTime.class.isAssignableFrom(expectedParameterType)) {
            Object coercedObject = DateTimeEvalHelper.coerceDateTime(localDate);
            return Optional.of(coercedObject);
        }
        return Optional.empty();
    }
@Test
    void coerceParam() {
        // Coerce List to singleton
        Class<?> currentIdxActualParameterType = List.class;
        Class<?> expectedParameterType = Number.class;
        Object valueObject = 34;
        Object actualObject = List.of(valueObject);
        Optional<Object> retrieved = CoerceUtil.coerceParam(currentIdxActualParameterType, expectedParameterType, actualObject);
        assertNotNull(retrieved);
        assertTrue(retrieved.isPresent());
        assertEquals(valueObject, retrieved.get());

        // Coerce single element to singleton list
        currentIdxActualParameterType = Number.class;
        expectedParameterType = List.class;
        actualObject = 34;
        retrieved = CoerceUtil.coerceParam(currentIdxActualParameterType, expectedParameterType, actualObject);
        assertNotNull(retrieved);
        assertTrue(retrieved.isPresent());
        assertTrue(retrieved.get() instanceof List);
        List lstRetrieved = (List) retrieved.get();
        assertEquals(1, lstRetrieved.size());
        assertEquals(actualObject, lstRetrieved.get(0));

        // Coerce date to date and time
        actualObject = LocalDate.now();
        currentIdxActualParameterType = LocalDate.class;
        expectedParameterType = ZonedDateTime.class;
        retrieved = CoerceUtil.coerceParam(currentIdxActualParameterType, expectedParameterType, actualObject);
        assertNotNull(retrieved);
        assertTrue(retrieved.isPresent());
        assertTrue(retrieved.get() instanceof ZonedDateTime);
        ZonedDateTime zdtRetrieved = (ZonedDateTime) retrieved.get();
        assertEquals(actualObject, zdtRetrieved.toLocalDate());
        assertEquals(ZoneOffset.UTC, zdtRetrieved.getOffset());
        assertEquals(0, zdtRetrieved.getHour());
        assertEquals(0, zdtRetrieved.getMinute());
        assertEquals(0, zdtRetrieved.getSecond());
    }