api/src/main/java/jakarta/faces/component/UIData.java [743:940]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    @SuppressWarnings("unchecked")
    private void restoreDescendantComponentStates(UIComponent parent, boolean iterateFacets, Object state,
                                                  boolean restoreChildFacets)
    {
        int descendantStateIndex = -1;
        List<? extends Object[]> stateCollection = null;
        
        if (iterateFacets && parent.getFacetCount() > 0)
        {
            Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
            
            while (childIterator.hasNext())
            {
                UIComponent component = childIterator.next();

                // reset the client id (see spec 3.1.6)
                component.setId(component.getId());
                if (!component.isTransient())
                {
                    if (descendantStateIndex == -1)
                    {
                        stateCollection = ((List<? extends Object[]>) state);
                        descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
                    }
                    
                    if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size())
                    {
                        Object[] object = stateCollection.get(descendantStateIndex);
                        if (component instanceof EditableValueHolder holder)
                        {
                            EditableValueHolderState evhState = (EditableValueHolderState) object[0];
                            if (evhState == null)
                            {
                                evhState = EditableValueHolderState.EMPTY;
                            }
                            evhState.restoreState(holder);
                        }

                        // If there is descendant state to restore, call it recursively, otherwise
                        // it is safe to skip iteration.
                        if (object[1] != null)
                        {
                            restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
                        }
                        else
                        {
                            restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                        }
                    }
                    else
                    {
                        restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                    }
                    descendantStateIndex++;
                }
            }
        }
        
        if (parent.getChildCount() > 0)
        {
            for (int i = 0; i < parent.getChildCount(); i++)
            {
                UIComponent component = parent.getChildren().get(i);

                // reset the client id (see spec 3.1.6)
                component.setId(component.getId());
                if (!component.isTransient())
                {
                    if (descendantStateIndex == -1)
                    {
                        stateCollection = ((List<? extends Object[]>) state);
                        descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
                    }
                    
                    if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size())
                    {
                        Object[] object = stateCollection.get(descendantStateIndex);
                        if (component instanceof EditableValueHolder holder)
                        {
                            EditableValueHolderState evhState = (EditableValueHolderState) object[0];
                            if (evhState == null)
                            {
                                evhState = EditableValueHolderState.EMPTY;
                            }
                            evhState.restoreState(holder);
                        }

                        // If there is descendant state to restore, call it recursively, otherwise
                        // it is safe to skip iteration.
                        if (object[1] != null)
                        {
                            restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
                        }
                        else
                        {
                            restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                        }
                    }
                    else
                    {
                        restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                    }
                    descendantStateIndex++;
                }
            }
        }
    }

    /**
     * Just call component.setId(component.getId()) to reset all client ids and 
     * ensure they will be calculated for the current row, but do not waste time
     * dealing with row state code.
     * 
     * @param parent
     * @param iterateFacets
     * @param restoreChildFacets 
     */
    private void restoreDescendantComponentWithoutRestoreState(UIComponent parent, boolean iterateFacets,
                                                               boolean restoreChildFacets)
    {
        if (iterateFacets && parent.getFacetCount() > 0)
        {
            Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
            
            while (childIterator.hasNext())
            {
                UIComponent component = childIterator.next();

                // reset the client id (see spec 3.1.6)
                component.setId(component.getId());
                if (!component.isTransient())
                {
                    restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                }
            }
        }
        
        if (parent.getChildCount() > 0)
        {
            for (int i = 0; i < parent.getChildCount(); i++)
            {
                UIComponent component = parent.getChildren().get(i);

                // reset the client id (see spec 3.1.6)
                component.setId(component.getId());
                if (!component.isTransient())
                {
                    restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                }
            }
        }
    }

    /**
     * Walk the tree of child components of this UIData, saving the parts of their state that can vary between rows.
     * <p>
     * This is very similar to the process that occurs for normal components when the view is serialized. Transient
     * components are skipped (no state is saved for them).
     * <p>
     * If there are no children then null is returned. If there are one or more children, and all children are transient
     * then an empty collection is returned; this will happen whenever a table contains only read-only components.
     * <p>
     * Otherwise a collection is returned which contains an object for every non-transient child component; that object
     * may itself contain a collection of the state of that child's child components.
     */
    private Collection<Object[]> saveDescendantComponentStates(UIComponent parent, boolean iterateFacets,
                                                               boolean saveChildFacets)
    {
        Collection<Object[]> childStates = null;
        // Index to indicate how many components has been passed without state to save.
        int childEmptyIndex = 0;
        int totalChildCount = 0;
                
        if (iterateFacets && parent.getFacetCount() > 0)
        {
            Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();

            while (childIterator.hasNext())
            {
                UIComponent child = childIterator.next();
                if (!child.isTransient())
                {
                    // Add an entry to the collection, being an array of two
                    // elements. The first element is the state of the children
                    // of this component; the second is the state of the current
                    // child itself.
                    if (child instanceof EditableValueHolder holder)
                    {
                        if (childStates == null)
                        {
                            childStates = new ArrayList<>(
                                    parent.getFacetCount()
                                    + parent.getChildCount()
                                    - totalChildCount
                                    + childEmptyIndex);
                            for (int ci = 0; ci < childEmptyIndex; ci++)
                            {
                                childStates.add(LEAF_NO_STATE);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



impl/src/main/java/org/apache/myfaces/view/facelets/component/UIRepeat.java [520:716]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    @SuppressWarnings("unchecked")
    private void restoreDescendantComponentStates(UIComponent parent, boolean iterateFacets, Object state,
                                                  boolean restoreChildFacets)
    {
        int descendantStateIndex = -1;
        List<? extends Object[]> stateCollection = null;
        
        if (iterateFacets && parent.getFacetCount() > 0)
        {
            Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
            
            while (childIterator.hasNext())
            {
                UIComponent component = childIterator.next();

                // reset the client id (see spec 3.1.6)
                component.setId(component.getId());
                if (!component.isTransient())
                {
                    if (descendantStateIndex == -1)
                    {
                        stateCollection = ((List<? extends Object[]>) state);
                        descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
                    }
                    
                    if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size())
                    {
                        Object[] object = stateCollection.get(descendantStateIndex);
                        if (component instanceof EditableValueHolder holder)
                        {
                            EditableValueHolderState evhState = (EditableValueHolderState) object[0];
                            if (evhState == null)
                            {
                                evhState = EditableValueHolderState.EMPTY;
                            }
                            evhState.restoreState(holder);
                        }
                        // If there is descendant state to restore, call it recursively, otherwise
                        // it is safe to skip iteration.
                        if (object[1] != null)
                        {
                            restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
                        }
                        else
                        {
                            restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                        }
                    }
                    else
                    {
                        restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                    }
                    descendantStateIndex++;
                }
            }
        }
        
        if (parent.getChildCount() > 0)
        {
            for (int i = 0; i < parent.getChildCount(); i++)
            {
                UIComponent component = parent.getChildren().get(i);

                // reset the client id (see spec 3.1.6)
                component.setId(component.getId());
                if (!component.isTransient())
                {
                    if (descendantStateIndex == -1)
                    {
                        stateCollection = ((List<? extends Object[]>) state);
                        descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
                    }
                    
                    if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size())
                    {
                        Object[] object = stateCollection.get(descendantStateIndex);
                        if (component instanceof EditableValueHolder holder)
                        {
                            EditableValueHolderState evhState = (EditableValueHolderState) object[0];
                            if (evhState == null)
                            {
                                evhState = EditableValueHolderState.EMPTY;
                            }
                            evhState.restoreState(holder);
                        }
                        // If there is descendant state to restore, call it recursively, otherwise
                        // it is safe to skip iteration.
                        if (object[1] != null)
                        {
                            restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
                        }
                        else
                        {
                            restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                        }
                    }
                    else
                    {
                        restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                    }
                    descendantStateIndex++;
                }
            }
        }
    }

    /**
     * Just call component.setId(component.getId()) to reset all client ids and 
     * ensure they will be calculated for the current row, but do not waste time
     * dealing with row state code.
     * 
     * @param parent
     * @param iterateFacets
     * @param restoreChildFacets 
     */
    private void restoreDescendantComponentWithoutRestoreState(UIComponent parent, boolean iterateFacets,
                                                               boolean restoreChildFacets)
    {
        if (iterateFacets && parent.getFacetCount() > 0)
        {
            Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
            
            while (childIterator.hasNext())
            {
                UIComponent component = childIterator.next();

                // reset the client id (see spec 3.1.6)
                component.setId(component.getId());
                if (!component.isTransient())
                {
                    restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                }
            }
        }
        
        if (parent.getChildCount() > 0)
        {
            for (int i = 0; i < parent.getChildCount(); i++)
            {
                UIComponent component = parent.getChildren().get(i);

                // reset the client id (see spec 3.1.6)
                component.setId(component.getId());
                if (!component.isTransient())
                {
                    restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
                }
            }
        }
    }

    /**
     * Walk the tree of child components of this UIRepeat, saving the parts of their state that can vary between rows.
     * <p>
     * This is very similar to the process that occurs for normal components when the view is serialized. Transient
     * components are skipped (no state is saved for them).
     * <p>
     * If there are no children then null is returned. If there are one or more children, and all children are transient
     * then an empty collection is returned; this will happen whenever a table contains only read-only components.
     * <p>
     * Otherwise a collection is returned which contains an object for every non-transient child component; that object
     * may itself contain a collection of the state of that child's child components.
     */
    private Collection<Object[]> saveDescendantComponentStates(UIComponent parent, boolean iterateFacets,
                                                               boolean saveChildFacets)
    {
        Collection<Object[]> childStates = null;
        // Index to indicate how many components has been passed without state to save.
        int childEmptyIndex = 0;
        int totalChildCount = 0;
                
        if (iterateFacets && parent.getFacetCount() > 0)
        {
            Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();

            while (childIterator.hasNext())
            {
                UIComponent child = childIterator.next();
                if (!child.isTransient())
                {
                    // Add an entry to the collection, being an array of two
                    // elements. The first element is the state of the children
                    // of this component; the second is the state of the current
                    // child itself.

                    if (child instanceof EditableValueHolder holder)
                    {
                        if (childStates == null)
                        {
                            childStates = new ArrayList<>(
                                    parent.getFacetCount()
                                    + parent.getChildCount()
                                    - totalChildCount
                                    + childEmptyIndex);
                            for (int ci = 0; ci < childEmptyIndex; ci++)
                            {
                                childStates.add(LEAF_NO_STATE);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



