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) {
                        if (childStates == null) {
                            childStates = new ArrayList<>(
                                    parent.getFacetCount()
                                    + parent.getChildCount()
                                    - totalChildCount
                                    + childEmptyIndex);
                            for (int ci = 0; ci < childEmptyIndex; ci++) {
                                childStates.add(LEAF_NO_STATE);
                            }
                        }

                        childStates.add(child.getChildCount() > 0
                                ? new Object[]{new SavedState((EditableValueHolder) child),
                                    saveDescendantComponentStates(child, saveChildFacets, true)}
                                : new Object[]{new SavedState((EditableValueHolder) child), null});
                    }
                    else if (child.getChildCount() > 0 || (saveChildFacets && child.getFacetCount() > 0)) {
                        Object descendantSavedState = saveDescendantComponentStates(child, saveChildFacets, true);

                        if (descendantSavedState == null) {
                            if (childStates == null) {
                                childEmptyIndex++;
                            }
                            else {
                                childStates.add(LEAF_NO_STATE);
                            }
                        }
                        else {
                            if (childStates == null) {
                                childStates = new ArrayList<>(
                                        parent.getFacetCount()
                                        + parent.getChildCount()
                                        - totalChildCount
                                        + childEmptyIndex);
                                for (int ci = 0; ci < childEmptyIndex; ci++) {
                                    childStates.add(LEAF_NO_STATE);
                                }
                            }
                            childStates.add(new Object[]{null, descendantSavedState});
                        }
                    }
                    else {
                        if (childStates == null) {
                            childEmptyIndex++;
                        }
                        else {
                            childStates.add(LEAF_NO_STATE);
                        }
                    }
                }
                totalChildCount++;
            }
        }

        if (parent.getChildCount() > 0) {
            for (int i = 0; i < parent.getChildCount(); i++) {
                UIComponent child = parent.getChildren().get(i);
                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) {
                        if (childStates == null) {
                            childStates = new ArrayList<>(
                                    parent.getFacetCount()
                                    + parent.getChildCount()
                                    - totalChildCount
                                    + childEmptyIndex);
                            for (int ci = 0; ci < childEmptyIndex; ci++) {
                                childStates.add(LEAF_NO_STATE);
                            }
                        }

                        childStates.add(child.getChildCount() > 0
                                ? new Object[]{new SavedState((EditableValueHolder) child),
                                    saveDescendantComponentStates(child, saveChildFacets, true)}
                                : new Object[]{new SavedState((EditableValueHolder) child), null});
                    }
                    else if (child.getChildCount() > 0 || (saveChildFacets && child.getFacetCount() > 0)) {
                        Object descendantSavedState = saveDescendantComponentStates(child, saveChildFacets, true);

                        if (descendantSavedState == null) {
                            if (childStates == null) {
                                childEmptyIndex++;
                            }
                            else {
                                childStates.add(LEAF_NO_STATE);
                            }
                        }
                        else {
                            if (childStates == null) {
                                childStates = new ArrayList<>(
                                        parent.getFacetCount()
                                        + parent.getChildCount()
                                        - totalChildCount
                                        + childEmptyIndex);
                                for (int ci = 0; ci < childEmptyIndex; ci++) {
                                    childStates.add(LEAF_NO_STATE);
                                }
                            }
                            childStates.add(new Object[]{null, descendantSavedState});
                        }
                    }
                    else {
                        if (childStates == null) {
                            childEmptyIndex++;
                        }
                        else {
                            childStates.add(LEAF_NO_STATE);
                        }
                    }
                }
                totalChildCount++;
            }
        }

        return childStates;
    }
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.
primefaces/src/main/java/org/primefaces/component/api/UITabPanel.java