You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2022/12/07 13:51:43 UTC

[myfaces] branch 2.3-next updated: MYFACES-4523

This is an automated email from the ASF dual-hosted git repository.

tandraschko pushed a commit to branch 2.3-next
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/2.3-next by this push:
     new f58a71758 MYFACES-4523
f58a71758 is described below

commit f58a71758cab0d1b879e57dde36ac35441cda123
Author: tandraschko <ta...@apache.org>
AuthorDate: Wed Dec 7 14:51:37 2022 +0100

    MYFACES-4523
---
 .../faces/component/_ComponentAttributesMap.java   |  16 +-
 .../api/shared/lang/PropertyDescriptorUtils.java   | 693 +++++++++++----------
 .../api/shared/lang/PropertyDescriptorWrapper.java | 166 +++--
 .../myfaces/application/ApplicationImpl.java       |  20 +-
 .../myfaces/el/resolver/LambdaBeanELResolver.java  | 347 ++++++-----
 .../myfaces/view/facelets/component/UIRepeat.java  |  59 +-
 .../view/facelets/tag/BeanPropertyTagRule.java     |  22 +-
 .../facelets/tag/LambdaMetadataTargetImpl.java     | 276 ++++----
 8 files changed, 795 insertions(+), 804 deletions(-)

diff --git a/api/src/main/java/javax/faces/component/_ComponentAttributesMap.java b/api/src/main/java/javax/faces/component/_ComponentAttributesMap.java
index 50a35f375..49173e0d9 100755
--- a/api/src/main/java/javax/faces/component/_ComponentAttributesMap.java
+++ b/api/src/main/java/javax/faces/component/_ComponentAttributesMap.java
@@ -26,6 +26,8 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
 
 import javax.el.ValueExpression;
 import javax.faces.FacesException;
@@ -648,7 +650,11 @@ class _ComponentAttributesMap implements Map<String, Object>, Serializable
         {
             if (propertyDescriptor instanceof LambdaPropertyDescriptor)
             {
-                return ((LambdaPropertyDescriptor) propertyDescriptor).getReadFunction().apply(_component);
+                Function<Object, Object> readFunction = ((LambdaPropertyDescriptor) propertyDescriptor).getReadFunction();
+                if (readFunction != null)
+                {
+                    return readFunction.apply(_component);
+                }
             }
 
             return readMethod.invoke(_component, EMPTY_ARGS);
@@ -681,9 +687,15 @@ class _ComponentAttributesMap implements Map<String, Object>, Serializable
 
         try
         {
+            BiConsumer<Object, Object> writeFunction = null;
             if (propertyDescriptor instanceof LambdaPropertyDescriptor)
             {
-                ((LambdaPropertyDescriptor) propertyDescriptor).getWriteFunction().accept(_component, value);
+                writeFunction = ((LambdaPropertyDescriptor) propertyDescriptor).getWriteFunction();
+            }
+
+            if (writeFunction != null)
+            {
+                writeFunction.accept(_component, value);
             }
             else
             {
diff --git a/api/src/main/java/org/apache/myfaces/core/api/shared/lang/PropertyDescriptorUtils.java b/api/src/main/java/org/apache/myfaces/core/api/shared/lang/PropertyDescriptorUtils.java
index 0b29ac34b..a38b0e566 100644
--- a/api/src/main/java/org/apache/myfaces/core/api/shared/lang/PropertyDescriptorUtils.java
+++ b/api/src/main/java/org/apache/myfaces/core/api/shared/lang/PropertyDescriptorUtils.java
@@ -1,343 +1,350 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.myfaces.core.api.shared.lang;
-
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.invoke.CallSite;
-import java.lang.invoke.LambdaConversionException;
-import java.lang.invoke.LambdaMetafactory;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.function.ObjDoubleConsumer;
-import java.util.function.ObjIntConsumer;
-import java.util.function.ObjLongConsumer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.faces.FacesException;
-import javax.faces.context.ExternalContext;
-import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
-
-public class PropertyDescriptorUtils
-{
-    private static final Logger LOG = Logger.getLogger(PropertyDescriptorUtils.class.getName());
-
-    /**
-     * Defines if Lambda expressions (via LambdaMetafactory) are used for getter/setter instead of Reflection.
-     */
-    @JSFWebConfigParam(since="2.3-next", defaultValue="true", expectedValues="true,false", tags="performance")
-    public static final String USE_LAMBDA_METAFACTORY = "org.apache.myfaces.USE_LAMBDA_METAFACTORY";
-
-    private static final String CACHE_KEY = PropertyDescriptorUtils.class.getName() + ".CACHE";
-
-    private static Method privateLookupIn;
-
-    static
-    {
-        try
-        {
-            privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class,
-                    MethodHandles.Lookup.class);
-        }
-        catch (Exception e)
-        {
-        }
-    }
-    
-    private static Map<String, Map<String, ? extends PropertyDescriptorWrapper>> getCache(ExternalContext ec)
-    {
-        Map<String, Map<String, ? extends PropertyDescriptorWrapper>> cache = 
-                (Map<String, Map<String, ? extends PropertyDescriptorWrapper>>) ec.getApplicationMap().get(CACHE_KEY);
-        if (cache == null)
-        {
-            cache = new ConcurrentHashMap<>(1000);
-            ec.getApplicationMap().put(CACHE_KEY, cache);
-        }
-
-        return cache;
-    }
-
-    public static Map<String, ? extends PropertyDescriptorWrapper> getCachedPropertyDescriptors(ExternalContext ec,
-            Class<?> target)
-    {
-        Map<String, ? extends PropertyDescriptorWrapper> cache = getCache(ec).get(target.getName());
-        if (cache == null)
-        {
-            cache = getCache(ec).computeIfAbsent(target.getName(), k -> getPropertyDescriptors(ec, target));
-        }
-
-        return cache;
-    }
-
-    public static boolean isUseLambdaMetafactory(ExternalContext ec)
-    {
-        if (privateLookupIn == null)
-        {
-            return false;
-        }
-        
-        // activated per default
-        String useMethodHandles = ec.getInitParameter(USE_LAMBDA_METAFACTORY);
-        return useMethodHandles == null || useMethodHandles.trim().isEmpty() || useMethodHandles.contains("true");
-    }
-
-    public static Map<String, ? extends PropertyDescriptorWrapper> getPropertyDescriptors(ExternalContext ec,
-            Class<?> target)
-    {
-        if (isUseLambdaMetafactory(ec))
-        {
-            try
-            {
-                return getLambdaPropertyDescriptors(target);
-            }
-            catch (IllegalAccessException e)
-            {
-                LOG.log(Level.FINEST, 
-                        "Could not generate LambdaPropertyDescriptor for "
-                                + target.getName() + ". Use PropertyDescriptor...");
-            }
-            catch (Throwable e)
-            {
-                LOG.log(Level.INFO, 
-                        "Could not generate LambdaPropertyDescriptor for "
-                                + target.getName() + ". Use PropertyDescriptor...",
-                        e);
-            }
-        }
-
-        try
-        {
-            PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(target).getPropertyDescriptors();
-            
-            Map<String, PropertyDescriptorWrapper> map = new ConcurrentHashMap<>(propertyDescriptors.length);
-
-            for (int i = 0; i < propertyDescriptors.length; i++)
-            {
-                PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
-                Method readMethod = propertyDescriptor.getReadMethod();
-
-                map.put(propertyDescriptor.getName(),
-                        new PropertyDescriptorWrapper(target, propertyDescriptor, readMethod));
-            }
-
-            return map;
-        }
-        catch (IntrospectionException e)
-        {
-            throw new FacesException(e);
-        }
-    }
-    
-    public static LambdaPropertyDescriptor getLambdaPropertyDescriptor(Class<?> target, String name)
-    {
-        try
-        {
-            PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(target).getPropertyDescriptors();
-            if (propertyDescriptors == null || propertyDescriptors.length == 0)
-            {
-                return null;
-            }
-            
-            for (PropertyDescriptor pd : propertyDescriptors)
-            {
-                if (name.equals(pd.getName()))
-                {
-                    MethodHandles.Lookup lookup = (MethodHandles.Lookup) privateLookupIn.invoke(null, target,
-                            MethodHandles.lookup());
-                    return createLambdaPropertyDescriptor(target, pd, lookup);
-                }
-            }
-
-            throw new FacesException("Property \"" + name + "\" not found on \"" + target.getName() + "\"");
-        }
-        catch (Throwable e)
-        {
-            throw new FacesException(e);
-        }
-    }
-    
-  
-    public static LambdaPropertyDescriptor createLambdaPropertyDescriptor(Class<?> target, PropertyDescriptor pd,
-            MethodHandles.Lookup lookup) throws Throwable
-    {
-        LambdaPropertyDescriptor lpd = new LambdaPropertyDescriptor(target, pd);
-
-        Method readMethod = pd.getReadMethod();
-        if (readMethod != null)
-        {
-            MethodHandle handle = lookup.unreflect(readMethod);
-            CallSite callSite = LambdaMetafactory.metafactory(lookup,
-                    "apply",
-                    MethodType.methodType(Function.class),
-                    MethodType.methodType(Object.class, Object.class),
-                    handle,
-                    handle.type());
-            lpd.readFunction = (Function) callSite.getTarget().invokeExact();
-        }
-
-        Method writeMethod = pd.getWriteMethod();
-        if (writeMethod != null)
-        {
-            MethodHandle handle = lookup.unreflect(writeMethod);
-            lpd.writeFunction = createSetter(lookup, lpd, handle);
-        }
-
-        return lpd;
-    }
-    
-    public static Map<String, LambdaPropertyDescriptor> getLambdaPropertyDescriptors(Class<?> target) throws Throwable
-    {
-        PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(target).getPropertyDescriptors();
-        if (propertyDescriptors == null || propertyDescriptors.length == 0)
-        {
-            return Collections.emptyMap();
-        }
-
-        Map<String, LambdaPropertyDescriptor> properties = new ConcurrentHashMap<>(propertyDescriptors.length);
-
-        MethodHandles.Lookup lookup = (MethodHandles.Lookup)
-                privateLookupIn.invoke(null, target, MethodHandles.lookup());
-        for (PropertyDescriptor pd : Introspector.getBeanInfo(target).getPropertyDescriptors())
-        {
-            LambdaPropertyDescriptor lpd = createLambdaPropertyDescriptor(target, pd, lookup);
-            properties.put(pd.getName(), lpd);
-        }
-
-        return properties;
-    }
-
-    @SuppressWarnings("unchecked")
-    protected static BiConsumer createSetter(MethodHandles.Lookup lookup, LambdaPropertyDescriptor propertyInfo,
-            MethodHandle setterHandle)
-            throws LambdaConversionException, Throwable
-    {
-        Class<?> propertyType = propertyInfo.getPropertyType();
-        // special handling for primitives required, see https://dzone.com/articles/setters-method-handles-and-java-11
-        if (propertyType.isPrimitive())
-        {
-            if (propertyType == double.class)
-            {
-                ObjDoubleConsumer consumer = (ObjDoubleConsumer) createSetterCallSite(
-                        lookup, setterHandle, ObjDoubleConsumer.class, double.class).getTarget().invokeExact();
-                return (a, b) -> consumer.accept(a, (double) b);
-            }
-            else if (propertyType == int.class)
-            {
-                ObjIntConsumer consumer = (ObjIntConsumer) createSetterCallSite(
-                        lookup, setterHandle, ObjIntConsumer.class, int.class).getTarget().invokeExact();
-                return (a, b) -> consumer.accept(a, (int) b);
-            }
-            else if (propertyType == long.class)
-            {
-                ObjLongConsumer consumer = (ObjLongConsumer) createSetterCallSite(
-                        lookup, setterHandle, ObjLongConsumer.class, long.class).getTarget().invokeExact();
-                return (a, b) -> consumer.accept(a, (long) b);
-            }
-            else if (propertyType == float.class)
-            {
-                ObjFloatConsumer consumer = (ObjFloatConsumer) createSetterCallSite(
-                        lookup, setterHandle, ObjFloatConsumer.class, float.class).getTarget().invokeExact();
-                return (a, b) -> consumer.accept(a, (float) b);
-            }
-            else if (propertyType == byte.class)
-            {
-                ObjByteConsumer consumer = (ObjByteConsumer) createSetterCallSite(
-                        lookup, setterHandle, ObjByteConsumer.class, byte.class).getTarget().invokeExact();
-                return (a, b) -> consumer.accept(a, (byte) b);
-            }
-            else if (propertyType == char.class)
-            {
-                ObjCharConsumer consumer = (ObjCharConsumer) createSetterCallSite(
-                        lookup, setterHandle, ObjCharConsumer.class, char.class).getTarget().invokeExact();
-                return (a, b) -> consumer.accept(a, (char) b);
-            }
-            else if (propertyType == short.class)
-            {
-                ObjShortConsumer consumer = (ObjShortConsumer) createSetterCallSite(
-                        lookup, setterHandle, ObjShortConsumer.class, short.class).getTarget().invokeExact();
-                return (a, b) -> consumer.accept(a, (short) b);
-            }
-            else if (propertyType == boolean.class)
-            {
-                ObjBooleanConsumer consumer = (ObjBooleanConsumer) createSetterCallSite(
-                        lookup, setterHandle, ObjBooleanConsumer.class, boolean.class).getTarget().invokeExact();
-                return (a, b) -> consumer.accept(a, (boolean) b);
-            }
-            else
-            {
-                throw new RuntimeException("Type is not supported yet: " + propertyType.getName());
-            }
-        }
-        else
-        {
-            return (BiConsumer) createSetterCallSite(lookup, setterHandle, BiConsumer.class, Object.class).getTarget()
-                    .invokeExact();
-        }
-    }
-
-    protected static CallSite createSetterCallSite(MethodHandles.Lookup lookup, MethodHandle setter,
-            Class<?> interfaceType, Class<?> valueType)
-            throws LambdaConversionException
-    {
-        return LambdaMetafactory.metafactory(lookup,
-                "accept",
-                MethodType.methodType(interfaceType),
-                MethodType.methodType(void.class, Object.class, valueType),
-                setter,
-                setter.type());
-    }
-
-    @FunctionalInterface
-    public interface ObjFloatConsumer<T extends Object>
-    {
-        public void accept(T t, float i);
-    }
-
-    @FunctionalInterface
-    public interface ObjByteConsumer<T extends Object>
-    {
-        public void accept(T t, byte i);
-    }
-
-    @FunctionalInterface
-    public interface ObjCharConsumer<T extends Object>
-    {
-        public void accept(T t, char i);
-    }
-
-    @FunctionalInterface
-    public interface ObjShortConsumer<T extends Object>
-    {
-        public void accept(T t, short i);
-    }
-
-    @FunctionalInterface
-    public interface ObjBooleanConsumer<T extends Object>
-    {
-        public void accept(T t, boolean i);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.myfaces.core.api.shared.lang;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.invoke.CallSite;
+import java.lang.invoke.LambdaConversionException;
+import java.lang.invoke.LambdaMetafactory;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.ObjDoubleConsumer;
+import java.util.function.ObjIntConsumer;
+import java.util.function.ObjLongConsumer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
+
+public class PropertyDescriptorUtils
+{
+    private static final Logger LOG = Logger.getLogger(PropertyDescriptorUtils.class.getName());
+
+    /**
+     * Defines if Lambda expressions (via LambdaMetafactory) are used for getter/setter instead of Reflection.
+     */
+    @JSFWebConfigParam(since="2.3-next", defaultValue="true", expectedValues="true,false", tags="performance")
+    public static final String USE_LAMBDA_METAFACTORY = "org.apache.myfaces.USE_LAMBDA_METAFACTORY";
+
+    private static final String CACHE_KEY = PropertyDescriptorUtils.class.getName() + ".CACHE";
+
+    private static Method privateLookupIn;
+
+    static
+    {
+        try
+        {
+            privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class,
+                    MethodHandles.Lookup.class);
+        }
+        catch (Exception e)
+        {
+        }
+    }
+    
+    private static Map<String, Map<String, ? extends PropertyDescriptorWrapper>> getCache(ExternalContext ec)
+    {
+        Map<String, Map<String, ? extends PropertyDescriptorWrapper>> cache = 
+                (Map<String, Map<String, ? extends PropertyDescriptorWrapper>>) ec.getApplicationMap().get(CACHE_KEY);
+        if (cache == null)
+        {
+            cache = new ConcurrentHashMap<>(1000);
+            ec.getApplicationMap().put(CACHE_KEY, cache);
+        }
+
+        return cache;
+    }
+
+    public static Map<String, ? extends PropertyDescriptorWrapper> getCachedPropertyDescriptors(ExternalContext ec,
+            Class<?> target)
+    {
+        Map<String, ? extends PropertyDescriptorWrapper> cache = getCache(ec).get(target.getName());
+        if (cache == null)
+        {
+            cache = getCache(ec).computeIfAbsent(target.getName(), k -> getPropertyDescriptors(ec, target));
+        }
+
+        return cache;
+    }
+
+    public static boolean isUseLambdaMetafactory(ExternalContext ec)
+    {
+        if (privateLookupIn == null)
+        {
+            return false;
+        }
+        
+        // activated per default
+        String useMethodHandles = ec.getInitParameter(USE_LAMBDA_METAFACTORY);
+        return useMethodHandles == null || useMethodHandles.trim().isEmpty() || useMethodHandles.contains("true");
+    }
+
+    public static Map<String, ? extends PropertyDescriptorWrapper> getPropertyDescriptors(ExternalContext ec,
+            Class<?> target)
+    {
+        if (isUseLambdaMetafactory(ec))
+        {
+            try
+            {
+                return getLambdaPropertyDescriptors(target);
+            }
+            catch (IllegalAccessException e)
+            {
+                LOG.log(Level.FINEST, 
+                        "Could not generate LambdaPropertyDescriptor for "
+                                + target.getName() + ". Use PropertyDescriptor...");
+            }
+            catch (Throwable e)
+            {
+                LOG.log(Level.INFO, 
+                        "Could not generate LambdaPropertyDescriptor for "
+                                + target.getName() + ". Use PropertyDescriptor...",
+                        e);
+            }
+        }
+
+        try
+        {
+            PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(target).getPropertyDescriptors();
+            
+            Map<String, PropertyDescriptorWrapper> map = new ConcurrentHashMap<>(propertyDescriptors.length);
+
+            for (int i = 0; i < propertyDescriptors.length; i++)
+            {
+                PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
+                map.put(propertyDescriptor.getName(),
+                        new PropertyDescriptorWrapper(target, propertyDescriptor));
+            }
+
+            return map;
+        }
+        catch (IntrospectionException e)
+        {
+            throw new FacesException(e);
+        }
+    }
+    
+    public static LambdaPropertyDescriptor getLambdaPropertyDescriptor(Class<?> target, String name)
+    {
+        try
+        {
+            PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(target).getPropertyDescriptors();
+            if (propertyDescriptors == null || propertyDescriptors.length == 0)
+            {
+                return null;
+            }
+            
+            for (PropertyDescriptor pd : propertyDescriptors)
+            {
+                if (name.equals(pd.getName()))
+                {
+                    MethodHandles.Lookup lookup = (MethodHandles.Lookup) privateLookupIn.invoke(null, target,
+                            MethodHandles.lookup());
+                    return createLambdaPropertyDescriptor(target, pd, lookup);
+                }
+            }
+
+            throw new FacesException("Property \"" + name + "\" not found on \"" + target.getName() + "\"");
+        }
+        catch (Throwable e)
+        {
+            throw new FacesException(e);
+        }
+    }
+    
+  
+    public static LambdaPropertyDescriptor createLambdaPropertyDescriptor(Class<?> target, PropertyDescriptor pd,
+            MethodHandles.Lookup lookup) throws Throwable
+    {
+        if (pd.getPropertyType() == null)
+        {
+            return null;
+        }
+
+        LambdaPropertyDescriptor lpd = new LambdaPropertyDescriptor(target, pd);
+
+        Method readMethod = pd.getReadMethod();
+        if (readMethod != null)
+        {
+            MethodHandle handle = lookup.unreflect(readMethod);
+            CallSite callSite = LambdaMetafactory.metafactory(lookup,
+                    "apply",
+                    MethodType.methodType(Function.class),
+                    MethodType.methodType(Object.class, Object.class),
+                    handle,
+                    handle.type());
+            lpd.readFunction = (Function) callSite.getTarget().invokeExact();
+        }
+
+        Method writeMethod = pd.getWriteMethod();
+        if (writeMethod != null)
+        {
+            MethodHandle handle = lookup.unreflect(writeMethod);
+            lpd.writeFunction = createSetter(lookup, lpd, handle);
+        }
+
+        return lpd;
+    }
+    
+    public static Map<String, PropertyDescriptorWrapper> getLambdaPropertyDescriptors(Class<?> target) throws Throwable
+    {
+        PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(target).getPropertyDescriptors();
+        if (propertyDescriptors == null || propertyDescriptors.length == 0)
+        {
+            return Collections.emptyMap();
+        }
+
+        Map<String, PropertyDescriptorWrapper> properties = new ConcurrentHashMap<>(propertyDescriptors.length);
+
+        MethodHandles.Lookup lookup = (MethodHandles.Lookup)
+                privateLookupIn.invoke(null, target, MethodHandles.lookup());
+        for (PropertyDescriptor pd : Introspector.getBeanInfo(target).getPropertyDescriptors())
+        {
+            PropertyDescriptorWrapper wrapped = createLambdaPropertyDescriptor(target, pd, lookup);
+            if (wrapped == null)
+            {
+                wrapped = new PropertyDescriptorWrapper(target, pd);
+            }
+            properties.put(pd.getName(), wrapped);
+        }
+
+        return properties;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected static BiConsumer createSetter(MethodHandles.Lookup lookup, LambdaPropertyDescriptor propertyInfo,
+            MethodHandle setterHandle)
+            throws LambdaConversionException, Throwable
+    {
+        Class<?> propertyType = propertyInfo.getPropertyType();
+        // special handling for primitives required, see https://dzone.com/articles/setters-method-handles-and-java-11
+        if (propertyType.isPrimitive())
+        {
+            if (propertyType == double.class)
+            {
+                ObjDoubleConsumer consumer = (ObjDoubleConsumer) createSetterCallSite(
+                        lookup, setterHandle, ObjDoubleConsumer.class, double.class).getTarget().invokeExact();
+                return (a, b) -> consumer.accept(a, (double) b);
+            }
+            else if (propertyType == int.class)
+            {
+                ObjIntConsumer consumer = (ObjIntConsumer) createSetterCallSite(
+                        lookup, setterHandle, ObjIntConsumer.class, int.class).getTarget().invokeExact();
+                return (a, b) -> consumer.accept(a, (int) b);
+            }
+            else if (propertyType == long.class)
+            {
+                ObjLongConsumer consumer = (ObjLongConsumer) createSetterCallSite(
+                        lookup, setterHandle, ObjLongConsumer.class, long.class).getTarget().invokeExact();
+                return (a, b) -> consumer.accept(a, (long) b);
+            }
+            else if (propertyType == float.class)
+            {
+                ObjFloatConsumer consumer = (ObjFloatConsumer) createSetterCallSite(
+                        lookup, setterHandle, ObjFloatConsumer.class, float.class).getTarget().invokeExact();
+                return (a, b) -> consumer.accept(a, (float) b);
+            }
+            else if (propertyType == byte.class)
+            {
+                ObjByteConsumer consumer = (ObjByteConsumer) createSetterCallSite(
+                        lookup, setterHandle, ObjByteConsumer.class, byte.class).getTarget().invokeExact();
+                return (a, b) -> consumer.accept(a, (byte) b);
+            }
+            else if (propertyType == char.class)
+            {
+                ObjCharConsumer consumer = (ObjCharConsumer) createSetterCallSite(
+                        lookup, setterHandle, ObjCharConsumer.class, char.class).getTarget().invokeExact();
+                return (a, b) -> consumer.accept(a, (char) b);
+            }
+            else if (propertyType == short.class)
+            {
+                ObjShortConsumer consumer = (ObjShortConsumer) createSetterCallSite(
+                        lookup, setterHandle, ObjShortConsumer.class, short.class).getTarget().invokeExact();
+                return (a, b) -> consumer.accept(a, (short) b);
+            }
+            else if (propertyType == boolean.class)
+            {
+                ObjBooleanConsumer consumer = (ObjBooleanConsumer) createSetterCallSite(
+                        lookup, setterHandle, ObjBooleanConsumer.class, boolean.class).getTarget().invokeExact();
+                return (a, b) -> consumer.accept(a, (boolean) b);
+            }
+            else
+            {
+                throw new RuntimeException("Type is not supported yet: " + propertyType.getName());
+            }
+        }
+        else
+        {
+            return (BiConsumer) createSetterCallSite(lookup, setterHandle, BiConsumer.class, Object.class).getTarget()
+                    .invokeExact();
+        }
+    }
+
+    protected static CallSite createSetterCallSite(MethodHandles.Lookup lookup, MethodHandle setter,
+            Class<?> interfaceType, Class<?> valueType)
+            throws LambdaConversionException
+    {
+        return LambdaMetafactory.metafactory(lookup,
+                "accept",
+                MethodType.methodType(interfaceType),
+                MethodType.methodType(void.class, Object.class, valueType),
+                setter,
+                setter.type());
+    }
+
+    @FunctionalInterface
+    public interface ObjFloatConsumer<T extends Object>
+    {
+        public void accept(T t, float i);
+    }
+
+    @FunctionalInterface
+    public interface ObjByteConsumer<T extends Object>
+    {
+        public void accept(T t, byte i);
+    }
+
+    @FunctionalInterface
+    public interface ObjCharConsumer<T extends Object>
+    {
+        public void accept(T t, char i);
+    }
+
+    @FunctionalInterface
+    public interface ObjShortConsumer<T extends Object>
+    {
+        public void accept(T t, short i);
+    }
+
+    @FunctionalInterface
+    public interface ObjBooleanConsumer<T extends Object>
+    {
+        public void accept(T t, boolean i);
+    }
+}
diff --git a/api/src/main/java/org/apache/myfaces/core/api/shared/lang/PropertyDescriptorWrapper.java b/api/src/main/java/org/apache/myfaces/core/api/shared/lang/PropertyDescriptorWrapper.java
index 27c927141..35fe312c3 100644
--- a/api/src/main/java/org/apache/myfaces/core/api/shared/lang/PropertyDescriptorWrapper.java
+++ b/api/src/main/java/org/apache/myfaces/core/api/shared/lang/PropertyDescriptorWrapper.java
@@ -1,86 +1,80 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.myfaces.core.api.shared.lang;
-
-import java.beans.PropertyDescriptor;
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Method;
-import javax.faces.FacesWrapper;
-
-public class PropertyDescriptorWrapper implements FacesWrapper<PropertyDescriptor>
-{
-    private final PropertyDescriptor wrapped;
-    private Reference<Method> readMethodRef;
-    private Reference<Method> writeMethodRef;
-
-    public PropertyDescriptorWrapper(Class<?> beanClass, PropertyDescriptor wrapped)
-    {
-        this.wrapped = wrapped;
-        this.readMethodRef = new SoftReference<>(wrapped.getReadMethod());
-    }
-
-    public PropertyDescriptorWrapper(Class<?> beanClass, PropertyDescriptor wrapped, Method readMethod)
-    {
-        this.wrapped = wrapped;
-        this.readMethodRef = new SoftReference<>(readMethod);
-    }
-
-    public Class<?> getPropertyType()
-    {
-        return wrapped.getPropertyType();
-    }    
-    
-    public String getName()
-    {
-        return wrapped.getName();
-    }
-    
-    @Override
-    public PropertyDescriptor getWrapped()
-    {
-        return wrapped;
-    }
-
-    public Method getReadMethod()
-    {
-        Method readMethod = readMethodRef.get();
-        if (readMethod == null)
-        {
-            readMethod = wrapped.getReadMethod();
-            readMethodRef = new SoftReference<>(readMethod);
-        }
-        return readMethod;
-    }
-
-    public Method getWriteMethod()
-    {
-        if (writeMethodRef == null || writeMethodRef.get() == null)
-        {
-            // In facelets, the Method instance used to write the variable is stored
-            // in a variable (see org.apache.myfaces.view.facelets.tag.BeanPropertyTagRule),
-            // so the impact of this synchronized call at the end is minimal compared with 
-            // getReadMethod. That's the reason why cache it here in a lazy way is enough
-            // instead retrieve it as soon as this holder is created.
-            Method writeMethod = wrapped.getWriteMethod();
-            writeMethodRef = new SoftReference<>(writeMethod);
-        }
-        return writeMethodRef.get();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.myfaces.core.api.shared.lang;
+
+import java.beans.PropertyDescriptor;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.lang.reflect.Method;
+import javax.faces.FacesWrapper;
+
+public class PropertyDescriptorWrapper implements FacesWrapper<PropertyDescriptor>
+{
+    private final PropertyDescriptor wrapped;
+    private Reference<Method> readMethodRef;
+    private Reference<Method> writeMethodRef;
+
+    public PropertyDescriptorWrapper(Class<?> beanClass, PropertyDescriptor wrapped)
+    {
+        this.wrapped = wrapped;
+        this.readMethodRef = new SoftReference<>(wrapped.getReadMethod());
+    }
+
+    public Class<?> getPropertyType()
+    {
+        return wrapped.getPropertyType();
+    }    
+    
+    public String getName()
+    {
+        return wrapped.getName();
+    }
+    
+    @Override
+    public PropertyDescriptor getWrapped()
+    {
+        return wrapped;
+    }
+
+    public Method getReadMethod()
+    {
+        Method readMethod = readMethodRef.get();
+        if (readMethod == null)
+        {
+            readMethod = wrapped.getReadMethod();
+            readMethodRef = new SoftReference<>(readMethod);
+        }
+        return readMethod;
+    }
+
+    public Method getWriteMethod()
+    {
+        if (writeMethodRef == null || writeMethodRef.get() == null)
+        {
+            // In facelets, the Method instance used to write the variable is stored
+            // in a variable (see org.apache.myfaces.view.facelets.tag.BeanPropertyTagRule),
+            // so the impact of this synchronized call at the end is minimal compared with 
+            // getReadMethod. That's the reason why cache it here in a lazy way is enough
+            // instead retrieve it as soon as this holder is created.
+            Method writeMethod = wrapped.getWriteMethod();
+            writeMethodRef = new SoftReference<>(writeMethod);
+        }
+        return writeMethodRef.get();
+    }
+}
diff --git a/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java b/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
index f82301262..a3cbfbbda 100755
--- a/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
@@ -34,6 +34,8 @@ import java.util.MissingResourceException;
 import java.util.TimeZone;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -1590,9 +1592,16 @@ public class ApplicationImpl extends Application
                     if (!pd.getPropertyType().isPrimitive())
                     {
                         Object defaultValue;
+                        
+                        Function<Object, Object> readFunction = null;
                         if (pd instanceof LambdaPropertyDescriptor)
                         {
-                            defaultValue = ((LambdaPropertyDescriptor) pd).getReadFunction().apply(converter);
+                            readFunction = ((LambdaPropertyDescriptor) pd).getReadFunction();
+                        }
+
+                        if (readFunction != null)
+                        {
+                            defaultValue = readFunction.apply(converter);
                         }
                         else
                         {
@@ -1606,9 +1615,16 @@ public class ApplicationImpl extends Application
                     }
 
                     Object convertedValue = ClassUtils.convertToType(property.getDefaultValue(), pd.getPropertyType());
+
+                    BiConsumer<Object, Object> writeFunction = null;
                     if (pd instanceof LambdaPropertyDescriptor)
                     {
-                        ((LambdaPropertyDescriptor) pd).getWriteFunction().accept(converter, convertedValue);
+                        writeFunction = ((LambdaPropertyDescriptor) pd).getWriteFunction();
+                    }
+
+                    if (writeFunction != null)
+                    {
+                        writeFunction.accept(converter, convertedValue);
                     }
                     else
                     {
diff --git a/impl/src/main/java/org/apache/myfaces/el/resolver/LambdaBeanELResolver.java b/impl/src/main/java/org/apache/myfaces/el/resolver/LambdaBeanELResolver.java
index cb8cb0d16..00518dda0 100644
--- a/impl/src/main/java/org/apache/myfaces/el/resolver/LambdaBeanELResolver.java
+++ b/impl/src/main/java/org/apache/myfaces/el/resolver/LambdaBeanELResolver.java
@@ -1,166 +1,181 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.myfaces.el.resolver;
-
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.el.BeanELResolver;
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.PropertyNotFoundException;
-import javax.el.PropertyNotWritableException;
-import javax.faces.context.FacesContext;
-import org.apache.myfaces.core.api.shared.lang.LambdaPropertyDescriptor;
-import org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils;
-import org.apache.myfaces.core.api.shared.lang.PropertyDescriptorWrapper;
-
-public class LambdaBeanELResolver extends BeanELResolver
-{
-    private final ConcurrentHashMap<String, Map<String, ? extends PropertyDescriptorWrapper>> cache;
-
-    public LambdaBeanELResolver()
-    {
-        this.cache = new ConcurrentHashMap<>(1000);
-    }
-
-    @Override
-    public Class<?> getType(ELContext context, Object base, Object property)
-    {
-        Objects.requireNonNull(context);
-        if (base == null || property == null)
-        {
-            return null;
-        }
-
-        context.setPropertyResolved(base, property);
-
-        return getPropertyDescriptor(base, property).getPropertyType();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Object getValue(ELContext context, Object base, Object property)
-    {        
-        Objects.requireNonNull(context);
-        if (base == null || property == null)
-        {
-            return null;
-        }
-
-        context.setPropertyResolved(base, property);
-
-        try
-        {
-            PropertyDescriptorWrapper pd = getPropertyDescriptor(base, property);
-            if (pd instanceof LambdaPropertyDescriptor)
-            {
-                return ((LambdaPropertyDescriptor) pd).getReadFunction().apply(base);
-            }
-
-            return pd.getWrapped().getReadMethod().invoke(base);
-        }
-        catch (Exception e)
-        {
-            throw new ELException(e);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void setValue(ELContext context, Object base, Object property, Object value)
-    {
-        Objects.requireNonNull(context);
-        if (base == null || property == null)
-        {
-            return;
-        }
-
-        context.setPropertyResolved(base, property);
-
-        PropertyDescriptorWrapper pd = getPropertyDescriptor(base, property);
-        if (pd.getWrapped().getWriteMethod()== null)
-        {
-            throw new PropertyNotWritableException("Property \"" + (String) property
-                    + "\" in \"" + base.getClass().getName() + "\" is not writable!");
-        }
-
-        try
-        {
-            if (pd instanceof LambdaPropertyDescriptor)
-            {
-                ((LambdaPropertyDescriptor) pd).getWriteFunction().accept(base, value);
-            }
-            else
-            {
-                pd.getWrapped().getWriteMethod().invoke(base, value);
-            }
-        }
-        catch (Exception e)
-        {
-            throw new ELException(e);
-        }
-    }
-
-    @Override
-    public boolean isReadOnly(ELContext context, Object base, Object property)
-    {
-        Objects.requireNonNull(context);
-        if (base == null || property == null)
-        {
-            return false;
-        }
-
-        context.setPropertyResolved(base, property);
-
-        return getPropertyDescriptor(base, property).getWrapped().getWriteMethod() == null;
-    }
-
-    @Override
-    public Class<?> getCommonPropertyType(ELContext context, Object base)
-    {
-        if (base != null)
-        {
-            return Object.class;
-        }
-
-        return null;
-    }
-
-    protected PropertyDescriptorWrapper getPropertyDescriptor(Object base, Object property)
-    {
-        Map<String, ? extends PropertyDescriptorWrapper> beanCache = cache.get(base.getClass().getName());
-        if (beanCache == null)
-        {
-            beanCache = PropertyDescriptorUtils.getCachedPropertyDescriptors(
-                    FacesContext.getCurrentInstance().getExternalContext(),
-                    base.getClass());
-            cache.put(base.getClass().getName(), beanCache);
-        }
-
-        PropertyDescriptorWrapper pd = beanCache.get((String) property);
-        if (pd == null)
-        {
-            throw new PropertyNotFoundException("Property [" + property
-                    + "] not found on type [" + base.getClass().getName() + "]");
-        }
-        return pd;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.myfaces.el.resolver;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import javax.el.BeanELResolver;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.faces.context.FacesContext;
+import org.apache.myfaces.core.api.shared.lang.LambdaPropertyDescriptor;
+import org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils;
+import org.apache.myfaces.core.api.shared.lang.PropertyDescriptorWrapper;
+
+public class LambdaBeanELResolver extends BeanELResolver
+{
+    private final ConcurrentHashMap<String, Map<String, ? extends PropertyDescriptorWrapper>> cache;
+
+    public LambdaBeanELResolver()
+    {
+        this.cache = new ConcurrentHashMap<>(1000);
+    }
+
+    @Override
+    public Class<?> getType(ELContext context, Object base, Object property)
+    {
+        Objects.requireNonNull(context);
+        if (base == null || property == null)
+        {
+            return null;
+        }
+
+        context.setPropertyResolved(base, property);
+
+        return getPropertyDescriptor(base, property).getPropertyType();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Object getValue(ELContext context, Object base, Object property)
+    {        
+        Objects.requireNonNull(context);
+        if (base == null || property == null)
+        {
+            return null;
+        }
+
+        context.setPropertyResolved(base, property);
+
+        try
+        {
+            PropertyDescriptorWrapper pd = getPropertyDescriptor(base, property);
+
+            Function<Object, Object> readFunction = null;
+            if (pd instanceof LambdaPropertyDescriptor)
+            {
+                readFunction = ((LambdaPropertyDescriptor) pd).getReadFunction();
+            }
+
+            if (readFunction != null)
+            {
+                return readFunction.apply(base);
+            }
+
+            return pd.getWrapped().getReadMethod().invoke(base);
+        }
+        catch (Exception e)
+        {
+            throw new ELException(e);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void setValue(ELContext context, Object base, Object property, Object value)
+    {
+        Objects.requireNonNull(context);
+        if (base == null || property == null)
+        {
+            return;
+        }
+
+        context.setPropertyResolved(base, property);
+
+        PropertyDescriptorWrapper pd = getPropertyDescriptor(base, property);
+        if (pd.getWrapped().getWriteMethod()== null)
+        {
+            throw new PropertyNotWritableException("Property \"" + (String) property
+                    + "\" in \"" + base.getClass().getName() + "\" is not writable!");
+        }
+
+        try
+        {
+            BiConsumer<Object, Object> writeFunction = null;
+            if (pd instanceof LambdaPropertyDescriptor)
+            {
+                writeFunction = ((LambdaPropertyDescriptor) pd).getWriteFunction();
+            }
+
+            if (writeFunction != null)
+            {
+                writeFunction.accept(base, value);
+            }
+            else
+            {
+                pd.getWrapped().getWriteMethod().invoke(base, value);
+            }
+        }
+        catch (Exception e)
+        {
+            throw new ELException(e);
+        }
+    }
+
+    @Override
+    public boolean isReadOnly(ELContext context, Object base, Object property)
+    {
+        Objects.requireNonNull(context);
+        if (base == null || property == null)
+        {
+            return false;
+        }
+
+        context.setPropertyResolved(base, property);
+
+        return getPropertyDescriptor(base, property).getWrapped().getWriteMethod() == null;
+    }
+
+    @Override
+    public Class<?> getCommonPropertyType(ELContext context, Object base)
+    {
+        if (base != null)
+        {
+            return Object.class;
+        }
+
+        return null;
+    }
+
+    protected PropertyDescriptorWrapper getPropertyDescriptor(Object base, Object property)
+    {
+        Map<String, ? extends PropertyDescriptorWrapper> beanCache = cache.get(base.getClass().getName());
+        if (beanCache == null)
+        {
+            beanCache = PropertyDescriptorUtils.getCachedPropertyDescriptors(
+                    FacesContext.getCurrentInstance().getExternalContext(),
+                    base.getClass());
+            cache.put(base.getClass().getName(), beanCache);
+        }
+
+        PropertyDescriptorWrapper pd = beanCache.get((String) property);
+        if (pd == null)
+        {
+            throw new PropertyNotFoundException("Property [" + property
+                    + "] not found on type [" + base.getClass().getName() + "]");
+        }
+        return pd;
+    }
+}
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java b/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java
index 66d3ae0c8..6978bc390 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java
@@ -1678,59 +1678,12 @@ public class UIRepeat extends UIComponentBase implements NamingContainer
                 _rowStates.clear();
             }
         }
-        if (initialStateMarked())
-        {
-            Object parentSaved = super.saveState(context);
-            if (context.getCurrentPhaseId() != null && 
-                !PhaseId.RENDER_RESPONSE.equals(context.getCurrentPhaseId()))
-            {
-                if (parentSaved == null /*&&_rowDeltaStates.isEmpty()*/ && _rowStates.isEmpty())
-                {
-                    return null;
-                }
-                else
-                {
-                    Object values[] = new Object[3];
-                    values[0] = super.saveState(context);
-                    values[1] = null;
-                    values[2] = UIComponentBase.saveAttachedState(context, _rowStates);
-                    return values;
-                }
-            }
-            else
-            {
-                if (parentSaved == null)
-                {
-                    return null;
-                }
-                else
-                {
-                    Object values[] = new Object[2];
-                    values[0] = super.saveState(context);
-                    values[1] = null;
-                    return values; 
-                }
-            }
-        }
-        else
-        {
-            if (context.getCurrentPhaseId() != null && 
-                !PhaseId.RENDER_RESPONSE.equals(context.getCurrentPhaseId()))
-            {
-                Object values[] = new Object[3];
-                values[0] = super.saveState(context);
-                values[1] = null;
-                values[2] = UIComponentBase.saveAttachedState(context, _rowStates);
-                return values; 
-            }
-            else
-            {
-                Object values[] = new Object[2];
-                values[0] = super.saveState(context);
-                values[1] = null;
-                return values;
-            }
-        }
+
+        Object values[] = new Object[3];
+        values[0] = super.saveState(context);
+        values[1] = null;
+        values[2] = UIComponentBase.saveAttachedState(context, _rowStates);
+        return values;
     }
     
     @Override
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/tag/BeanPropertyTagRule.java b/impl/src/main/java/org/apache/myfaces/view/facelets/tag/BeanPropertyTagRule.java
index 55615b541..455797379 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/tag/BeanPropertyTagRule.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/tag/BeanPropertyTagRule.java
@@ -41,21 +41,21 @@ public final class BeanPropertyTagRule extends MetaRule
     @Override
     public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta)
     {
+        BiConsumer<Object, Object> writeFunction = null;
         if (meta instanceof LambdaMetadataTargetImpl)
         {
-            BiConsumer<Object, Object> f = ((LambdaMetadataTargetImpl) meta).getWriteFunction(name);
+            writeFunction = ((LambdaMetadataTargetImpl) meta).getWriteFunction(name);
+        }
 
-            // if the property is writable
-            if (f != null)
+        if (writeFunction != null)
+        {
+            if (attribute.isLiteral())
             {
-                if (attribute.isLiteral())
-                {
-                    return new LiteralPropertyMetadata(meta.getPropertyType(name), f, attribute);
-                }
-                else
-                {
-                    return new DynamicPropertyMetadata(meta.getPropertyType(name), f, attribute);
-                }
+                return new LiteralPropertyMetadata(meta.getPropertyType(name), writeFunction, attribute);
+            }
+            else
+            {
+                return new DynamicPropertyMetadata(meta.getPropertyType(name), writeFunction, attribute);
             }
         }
         else
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/tag/LambdaMetadataTargetImpl.java b/impl/src/main/java/org/apache/myfaces/view/facelets/tag/LambdaMetadataTargetImpl.java
index 5d5280543..76016b8e7 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/tag/LambdaMetadataTargetImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/tag/LambdaMetadataTargetImpl.java
@@ -1,141 +1,135 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.myfaces.view.facelets.tag;
-
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import javax.faces.context.FacesContext;
-import javax.faces.view.facelets.MetadataTarget;
-import org.apache.myfaces.core.api.shared.lang.LambdaPropertyDescriptor;
-import org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils;
-import org.apache.myfaces.core.api.shared.lang.PropertyDescriptorWrapper;
-
-public class LambdaMetadataTargetImpl extends MetadataTarget
-{
-    private final Map<String, ? extends PropertyDescriptorWrapper> propertyDescriptors;
-    private final Class<?> type;
-
-    public LambdaMetadataTargetImpl(Class<?> type) throws IntrospectionException
-    {
-        this.type = type;
-        this.propertyDescriptors = PropertyDescriptorUtils.getCachedPropertyDescriptors(
-                FacesContext.getCurrentInstance().getExternalContext(),
-                type);
-    }
-
-    @Override
-    public PropertyDescriptor getProperty(String name)
-    {
-        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
-        if (lpd == null)
-        {
-            return null;
-        }
-
-        return lpd.getWrapped();
-    }
-
-    @Override
-    public Class<?> getPropertyType(String name)
-    {
-        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
-        if (lpd == null)
-        {
-            return null;
-        }
-
-        return lpd.getPropertyType();
-    }
-
-    @Override
-    public Method getReadMethod(String name)
-    {
-        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
-        if (lpd == null)
-        {
-            return null;
-        }
-        
-        return lpd.getReadMethod();
-    }
-
-    @Override
-    public Class<?> getTargetClass()
-    {
-        return type;
-    }
-
-    @Override
-    public Method getWriteMethod(String name)
-    {
-        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
-        if (lpd == null)
-        {
-            return null;
-        }
-        
-        return lpd.getWriteMethod();
-    }
-
-    @Override
-    public boolean isTargetInstanceOf(Class type)
-    {
-        return type.isAssignableFrom(type);
-    }
- 
-    public LambdaPropertyDescriptor getLambdaProperty(String name)
-    {
-        PropertyDescriptorWrapper wrapper = propertyDescriptors.get(name);
-
-        if (wrapper instanceof LambdaPropertyDescriptor)
-        {
-            return (LambdaPropertyDescriptor) wrapper;
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-    public Function<Object, Object> getReadFunction(String name)
-    {
-        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
-        if (lpd == null)
-        {
-            return null;
-        }
-        
-        return lpd.getReadFunction();
-    }
-
-    public BiConsumer<Object, Object> getWriteFunction(String name)
-    {
-        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
-        if (lpd == null)
-        {
-            return null;
-        }
-        
-        return lpd.getWriteFunction();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.myfaces.view.facelets.tag;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import javax.faces.context.FacesContext;
+import javax.faces.view.facelets.MetadataTarget;
+import org.apache.myfaces.core.api.shared.lang.LambdaPropertyDescriptor;
+import org.apache.myfaces.core.api.shared.lang.PropertyDescriptorUtils;
+import org.apache.myfaces.core.api.shared.lang.PropertyDescriptorWrapper;
+
+public class LambdaMetadataTargetImpl extends MetadataTarget
+{
+    private final Map<String, ? extends PropertyDescriptorWrapper> propertyDescriptors;
+    private final Class<?> type;
+
+    public LambdaMetadataTargetImpl(Class<?> type) throws IntrospectionException
+    {
+        this.type = type;
+        this.propertyDescriptors = PropertyDescriptorUtils.getCachedPropertyDescriptors(
+                FacesContext.getCurrentInstance().getExternalContext(),
+                type);
+    }
+
+    @Override
+    public PropertyDescriptor getProperty(String name)
+    {
+        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
+        if (lpd == null)
+        {
+            return null;
+        }
+
+        return lpd.getWrapped();
+    }
+
+    @Override
+    public Class<?> getPropertyType(String name)
+    {
+        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
+        if (lpd == null)
+        {
+            return null;
+        }
+
+        return lpd.getPropertyType();
+    }
+
+    @Override
+    public Method getReadMethod(String name)
+    {
+        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
+        if (lpd == null)
+        {
+            return null;
+        }
+        
+        return lpd.getReadMethod();
+    }
+
+    @Override
+    public Class<?> getTargetClass()
+    {
+        return type;
+    }
+
+    @Override
+    public Method getWriteMethod(String name)
+    {
+        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
+        if (lpd == null)
+        {
+            return null;
+        }
+        
+        return lpd.getWriteMethod();
+    }
+
+    @Override
+    public boolean isTargetInstanceOf(Class type)
+    {
+        return type.isAssignableFrom(type);
+    }
+
+    public LambdaPropertyDescriptor getLambdaProperty(String name)
+    {
+        PropertyDescriptorWrapper pdw = propertyDescriptors.get(name);
+        return pdw instanceof LambdaPropertyDescriptor
+                ? (LambdaPropertyDescriptor) pdw
+                : null;
+    }
+
+    public Function<Object, Object> getReadFunction(String name)
+    {
+        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
+        if (lpd == null)
+        {
+            return null;
+        }
+        
+        return lpd.getReadFunction();
+    }
+
+    public BiConsumer<Object, Object> getWriteFunction(String name)
+    {
+        LambdaPropertyDescriptor lpd = getLambdaProperty(name);
+        if (lpd == null)
+        {
+            return null;
+        }
+        
+        return lpd.getWriteFunction();
+    }
+}