/*
 * 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.tobago.internal.renderkit.renderer;

import org.apache.myfaces.tobago.internal.component.AbstractUISelectManyBase;
import org.apache.myfaces.tobago.internal.util.ArrayUtils;
import org.apache.myfaces.tobago.util.ComponentUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.application.ProjectStage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UISelectItem;
import javax.faces.component.UISelectItems;
import javax.faces.component.UISelectMany;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.model.SelectItem;
import javax.faces.model.SelectItemGroup;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

public abstract class SelectManyRendererBase extends MessageLayoutRendererBase {

  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

  @Override
  public void decode(final FacesContext facesContext, final UIComponent component) {
    if (ComponentUtils.isOutputOnly(component)) {
      return;
    }

    final AbstractUISelectManyBase select = (AbstractUISelectManyBase) component;

    String[] newValues =
        facesContext.getExternalContext().getRequestParameterValuesMap().get(select.getClientId(facesContext));
    if (LOG.isDebugEnabled()) {
      LOG.debug("decode: key='" + component.getClientId(facesContext)
          + "' value='" + Arrays.toString(newValues) + "'");
      LOG.debug("size ... '" + (newValues != null ? newValues.length : -1) + "'");
      if (newValues != null) {
        for (final String newValue : newValues) {
          LOG.debug("newValues[i] = '" + newValue + "'");
        }
      }
    }

    if (newValues == null) {
      newValues = ArrayUtils.EMPTY_STRING_ARRAY; // because no selection will not submitted by browsers
    }
    select.setSubmittedValue(newValues);

    decodeClientBehaviors(facesContext, select);
  }

  public String[] getSubmittedValues(final UIInput input) {
    return (String[]) input.getSubmittedValue();
  }

  @Override
  public Object getConvertedValue(
      final FacesContext facesContext, final UIComponent component, final Object submittedValue)
      throws ConverterException {

    if (submittedValue == null) {
      return null;
    } else {
      if (!(submittedValue instanceof String[])) {
        throw new ConverterException("Submitted value not of type String[] for component : "
            + component.getClientId(facesContext) + "expected");
      }
    }
    return getConvertedUISelectManyValue(facesContext, (UISelectMany) component, (String[]) submittedValue);
  }

  // #################################################################################################################
  // #################################################################################################################
  // ###  The following methods and classes are copied from myfaces api 2.2.8,
  // ###  slightly modified to compile in this context.
  // ###  We copy this to avoid the dependency
  // #################################################################################################################
  // #################################################################################################################

  // #################################################################################################################
  // ### BEGIN copy out of https://svn.apache.org/repos/asf/myfaces/core/tags/myfaces-core-module-2.2.8/
  // ###     api/src/main/java/javax/faces/component/_SharedRendererUtils.java
  // #################################################################################################################
  static final String COLLECTION_TYPE_KEY = "collectionType";
  static final String VALUE_TYPE_KEY = "valueType";

  static Object getConvertedUISelectManyValue(final FacesContext facesContext, final UISelectMany component,
                                              final String[] submittedValue) throws ConverterException {
    return getConvertedUISelectManyValue(facesContext, component,
        submittedValue, false);
  }

  /**
   * Gets the converted value of a UISelectMany component.
   * If the considerValueType is true, this method will also consider the
   * valueType attribute of Tomahawk UISelectMany components.
   *
   * @param facesContext
   * @param component
   * @param submittedValue
   * @param considerValueType
   * @return
   * @throws ConverterException
   */
  static Object getConvertedUISelectManyValue(final FacesContext facesContext, final UISelectMany component,
                                              final String[] submittedValue, final boolean considerValueType)
      throws ConverterException {
    // Attention!
    // This code is duplicated in shared renderkit package (except for considerValueType).
    // If you change something here please do the same in the other class!

    if (submittedValue == null) {
      throw new NullPointerException("submittedValue");
    }

    final ValueExpression expression = component.getValueExpression("value");
    Object targetForConvertedValues = null;

    // if the component has an attached converter, use it
    Converter converter = component.getConverter();
    // at this point the valueType attribute is handled in shared.
    if (converter == null && considerValueType) {
      // try to get a converter from the valueType attribute
      converter = getValueTypeConverter(facesContext, component);
    }

    if (expression != null) {
      final Class<?> modelType = expression
          .getType(facesContext.getELContext());
      if (modelType == null) {
        // FIXME temporal workaround for MYFACES-2552
        return submittedValue;
      } else if (modelType.isArray()) {
        // the target should be an array
        final Class<?> componentType = modelType.getComponentType();
        // check for optimization if the target is
        // a string array --> no conversion needed
        if (String.class.equals(componentType)) {
          return submittedValue;
        }
        if (converter == null) {
          // the compononent does not have an attached converter
          // --> try to get a registered-by-class converter
          converter = facesContext.getApplication().createConverter(
              componentType);

          if (converter == null && !Object.class.equals(componentType)) {
            // could not obtain a Converter
            // --> check if we maybe do not really have to convert

            // target is not an Object array
            // and not a String array (checked some lines above)
            // and we do not have a Converter
            throw new ConverterException(
                "Could not obtain a Converter for "
                    + componentType.getName());
          }
        }
        // instantiate the array
        targetForConvertedValues = Array.newInstance(componentType,
            submittedValue.length);
      } else if (Collection.class.isAssignableFrom(modelType) || Object.class.equals(modelType)) {
        if (converter == null) {
          // try to get the by-type-converter from the type of the SelectItems
          final SelectItemsIterator iterator = new SelectItemsIterator(component, facesContext);
          converter = getSelectItemsValueConverter(iterator, facesContext);
        }

        final Object collectionTypeAttr = component.getAttributes().get(
            COLLECTION_TYPE_KEY);
        if (collectionTypeAttr != null) {
          final Class<?> collectionType = getClassFromAttribute(facesContext, collectionTypeAttr);
          if (collectionType == null) {
            throw new FacesException(
                "The attribute "
                    + COLLECTION_TYPE_KEY
                    + " of component "
                    + component.getClientId(facesContext)
                    + " does not evaluate to a "
                    + "String, a Class object or a ValueExpression pointing "
                    + "to a String or a Class object.");
          }
          // now we have a collectionType --> but is it really some kind of Collection
          if (!Collection.class.isAssignableFrom(collectionType)) {
            throw new FacesException("The attribute "
                + COLLECTION_TYPE_KEY + " of component "
                + component.getClientId(facesContext)
                + " does not point to a valid type of Collection.");
          }
          // now we have a real collectionType --> try to instantiate it
          try {
            targetForConvertedValues = collectionType.newInstance();
          } catch (final Exception e) {
            throw new FacesException("The Collection "
                + collectionType.getName()
                + "can not be instantiated.", e);
          }
        } else if (Collection.class.isAssignableFrom(modelType)) {
          // component.getValue() will implement Collection at this point
          final Collection<?> componentValue = (Collection<?>) component
              .getValue();
          // can we clone the Collection
          if (componentValue instanceof Cloneable) {
            // clone method of Object is protected --> use reflection
            try {
              final Method cloneMethod = componentValue.getClass()
                  .getMethod("clone");
              final Collection<?> clone = (Collection<?>) cloneMethod
                  .invoke(componentValue);
              clone.clear();
              targetForConvertedValues = clone;
            } catch (final Exception e) {
              LOG.error("Could not clone " + componentValue.getClass().getName(), e);
            }
          }

          // if clone did not work
          if (targetForConvertedValues == null) {
            // try to create the (concrete) collection from modelType
            // or with the class object of componentValue (if any)
            try {
              targetForConvertedValues = (componentValue != null
                  ? componentValue.getClass()
                  : modelType).newInstance();
            } catch (final Exception e) {
              // this did not work either
              // use the standard concrete type
              if (SortedSet.class.isAssignableFrom(modelType)) {
                targetForConvertedValues = new TreeSet();
              } else if (Queue.class.isAssignableFrom(modelType)) {
                targetForConvertedValues = new LinkedList();
              } else if (Set.class.isAssignableFrom(modelType)) {
                targetForConvertedValues = new HashSet(
                    submittedValue.length);
              } else {
                targetForConvertedValues = new ArrayList(
                    submittedValue.length);
              }
            }
          }
        } else /* if (Object.class.equals(modelType)) */ {
          // a modelType of Object is also permitted, in order to support
          // managed bean properties of type Object

          // optimization: if we don't have a converter, we can return the submittedValue
          if (converter == null) {
            return submittedValue;
          }

          targetForConvertedValues = new Object[submittedValue.length];
        }
      } else {
        // the expression does neither point to an array nor to a collection
        throw new ConverterException(
            "ValueExpression for UISelectMany must be of type Collection or Array.");
      }
    } else {
      targetForConvertedValues = new Object[submittedValue.length];
    }

    // convert the values with the selected converter (if any)
    // and store them in targetForConvertedValues
    final boolean isArray = targetForConvertedValues.getClass().isArray();
    for (int i = 0; i < submittedValue.length; i++) {
      // get the value
      final Object value;
      if (converter != null) {
        value = converter.getAsObject(facesContext, component,
            submittedValue[i]);
      } else {
        value = submittedValue[i];
      }
      // store it in targetForConvertedValues
      if (isArray) {
        Array.set(targetForConvertedValues, i, value);
      } else {
        ((Collection) targetForConvertedValues).add(value);
      }
    }

    return targetForConvertedValues;
  }

  /**
   * Gets a Class object from a given component attribute. The attribute can
   * be a ValueExpression (that evaluates to a String or a Class) or a
   * String (that is a fully qualified Java class name) or a Class object.
   *
   * @param facesContext
   * @param attribute
   * @return
   * @throws FacesException if the value is a String and the represented
   *                        class cannot be found
   */
  static Class<?> getClassFromAttribute(final FacesContext facesContext,
                                        final Object attribute) throws FacesException {
    // Attention!
    // This code is duplicated in shared renderkit package.
    // If you change something here please do the same in the other class!

    Class<?> type = null;

    // if there is a value, it must be a ...
    // ... a ValueExpression that evaluates to a String or a Class
    final Object attr = attribute instanceof ValueExpression
        // get the value of the ValueExpression
        ? ((ValueExpression) attribute).getValue(facesContext.getELContext())
        : attribute;
    // ... String that is a fully qualified Java class name
    if (attr instanceof String) {
      try {
        type = Class.forName((String) attr);
      } catch (final ClassNotFoundException cnfe) {
        throw new FacesException("Unable to find class " + attr + " on the classpath.", cnfe);
      }
    } else if (attr instanceof Class) {
      // ... a Class object
      type = (Class<?>) attr;
    }

    return type;
  }

  /**
   * Uses the valueType attribute of the given UISelectMany component to
   * get a by-type converter.
   *
   * @param facesContext
   * @param component
   * @return
   */
  static Converter getValueTypeConverter(final FacesContext facesContext, final UISelectMany component) {
    Converter converter = null;

    final Object valueTypeAttr = component.getAttributes().get(VALUE_TYPE_KEY);
    if (valueTypeAttr != null) {
      // treat the valueType attribute exactly like the collectionType attribute
      final Class<?> valueType = getClassFromAttribute(facesContext, valueTypeAttr);
      if (valueType == null) {
        throw new FacesException(
            "The attribute "
                + VALUE_TYPE_KEY
                + " of component "
                + component.getClientId(facesContext)
                + " does not evaluate to a "
                + "String, a Class object or a ValueExpression pointing "
                + "to a String or a Class object.");
      }
      // now we have a valid valueType
      // --> try to get a registered-by-class converter
      converter = facesContext.getApplication().createConverter(valueType);

      if (converter == null) {
        facesContext.getExternalContext().log("Found attribute valueType on component "
            + getPathToComponent(component)
            + ", but could not get a by-type converter for type "
            + valueType.getName());
      }
    }

    return converter;
  }

  /**
   * Iterates through the SelectItems with the given Iterator and tries to obtain
   * a by-class-converter based on the Class of SelectItem.getValue().
   *
   * @param iterator
   * @param facesContext
   * @return The first suitable Converter for the given SelectItems or null.
   */
  static Converter getSelectItemsValueConverter(final Iterator<SelectItem> iterator, final FacesContext facesContext) {
    // Attention!
    // This code is duplicated in jsfapi component package.
    // If you change something here please do the same in the other class!

    Converter converter = null;
    while (converter == null && iterator.hasNext()) {
      final SelectItem item = iterator.next();
      if (item instanceof SelectItemGroup) {
        final Iterator<SelectItem> groupIterator = Arrays.asList(
            ((SelectItemGroup) item).getSelectItems()).iterator();
        converter = getSelectItemsValueConverter(groupIterator, facesContext);
      } else {
        final Class<?> selectItemsType = item.getValue().getClass();

        // optimization: no conversion for String values
        if (String.class.equals(selectItemsType)) {
          return null;
        }

        try {
          converter = facesContext.getApplication().createConverter(selectItemsType);
        } catch (final FacesException e) {
          // nothing - try again
        }
      }
    }
    return converter;
  }
  // #################################################################################################################
  // ### END copy out of https://svn.apache.org/repos/asf/myfaces/core/tags/myfaces-core-module-2.2.8/
  // ###     api/src/main/java/javax/faces/component/_SharedRendererUtils.java
  // #################################################################################################################

  // #################################################################################################################
  // ### BEGIN copy out of https://svn.apache.org/repos/asf/myfaces/core/tags/myfaces-core-module-2.2.8/
  // ###     api/src/main/java/javax/faces/component/_ComponentUtils.java
  // #################################################################################################################
  static String getPathToComponent(final UIComponent component) {
    final StringBuilder builder = new StringBuilder();

    if (component == null) {
      builder.append("{Component-Path : ");
      builder.append("[null]}");
      return builder.toString();
    }

    getPathToComponent(component, builder);

    builder.insert(0, "{Component-Path : ");
    builder.append("}");

    return builder.toString();
  }

  private static void getPathToComponent(final UIComponent component, final StringBuilder builder) {
    if (component == null) {
      return;
    }

    final StringBuilder intBuilder = new StringBuilder();

    intBuilder.append("[Class: ");
    intBuilder.append(component.getClass().getName());
    if (component instanceof UIViewRoot) {
      intBuilder.append(",ViewId: ");
      intBuilder.append(((UIViewRoot) component).getViewId());
    } else {
      intBuilder.append(",Id: ");
      intBuilder.append(component.getId());
    }
    intBuilder.append("]");

    builder.insert(0, intBuilder.toString());

    getPathToComponent(component.getParent(), builder);
  }
  // #################################################################################################################
  // ### END copy out of https://svn.apache.org/repos/asf/myfaces/core/tags/myfaces-core-module-2.2.8/
  // ###     api/src/main/java/javax/faces/component/_ComponentUtils.java
  // #################################################################################################################

  // #################################################################################################################
  // ### BEGIN copy out of https://svn.apache.org/repos/asf/myfaces/core/tags/myfaces-core-module-2.2.8/
  // ###     api/src/main/java/javax/faces/component/_SelectItemsIterator.java
  // #################################################################################################################
  private static class SelectItemsIterator implements Iterator<SelectItem> {

    private static final Iterator<UIComponent> EMPTY_UICOMPONENT_ITERATOR = new EmptyIterator<>();

    // org.apache.myfaces.shared.util.SelectItemsIterator uses JSFAttr
    private static final String VAR_ATTR = "var";
    private static final String ITEM_VALUE_ATTR = "itemValue";
    private static final String ITEM_LABEL_ATTR = "itemLabel";
    private static final String ITEM_DESCRIPTION_ATTR = "itemDescription";
    private static final String ITEM_DISABLED_ATTR = "itemDisabled";
    private static final String ITEM_LABEL_ESCAPED_ATTR = "itemLabelEscaped";
    private static final String NO_SELECTION_VALUE_ATTR = "noSelectionValue";

    private final Iterator<UIComponent> children;
    private Iterator<?> nestedItems;
    private SelectItem nextItem;
    private UIComponent currentComponent;
    private UISelectItems currentUISelectItems;
    private FacesContext facesContext;

    SelectItemsIterator(final UIComponent selectItemsParent, final FacesContext facesContext) {
      children = selectItemsParent.getChildCount() > 0
          ? selectItemsParent.getChildren().iterator()
          : EMPTY_UICOMPONENT_ITERATOR;
      this.facesContext = facesContext;
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean hasNext() {
      if (nextItem != null) {
        return true;
      }
      if (nestedItems != null) {
        if (nestedItems.hasNext()) {
          return true;
        }
        nestedItems = null;
        currentComponent = null;
      }
      if (children.hasNext()) {
        UIComponent child = children.next();
        // When there is other components nested that does
        // not extends from UISelectItem or UISelectItems
        // the behavior for this iterator is just skip this
        // element(s) until an element that extends from these
        // classes are found. If there is no more elements
        // that conform this condition, just return false.
        while (!(child instanceof UISelectItem) && !(child instanceof UISelectItems)) {
          // Try to skip it
          if (children.hasNext()) {
            // Skip and do the same check
            child = children.next();
          } else {
            // End loop, so the final result is return false,
            // since there are no more components to iterate.
            return false;
          }
        }
        if (child instanceof UISelectItem) {
          final UISelectItem uiSelectItem = (UISelectItem) child;
          Object item = uiSelectItem.getValue();
          if (item == null) {
            // no value attribute --> create the SelectItem out of the other attributes
            final Object itemValue = uiSelectItem.getItemValue();
            String label = uiSelectItem.getItemLabel();
            final String description = uiSelectItem.getItemDescription();
            final boolean disabled = uiSelectItem.isItemDisabled();
            final boolean escape = uiSelectItem.isItemEscaped();
            final boolean noSelectionOption = uiSelectItem.isNoSelectionOption();
            if (label == null) {
              label = itemValue.toString();
            }
            item = new SelectItem(itemValue, label, description, disabled, escape, noSelectionOption);
          } else if (!(item instanceof SelectItem)) {
            final ValueExpression expression = uiSelectItem.getValueExpression("value");
            throw new IllegalArgumentException("ValueExpression '"
                + (expression == null ? null : expression.getExpressionString()) + "' of UISelectItem : "
                + getPathToComponent(child) + " does not reference an Object of type SelectItem");
          }
          nextItem = (SelectItem) item;
          currentComponent = child;
          return true;
        } else if (child instanceof UISelectItems) {
          currentUISelectItems = (UISelectItems) child;
          final Object value = currentUISelectItems.getValue();
          currentComponent = child;

          if (value instanceof SelectItem) {
            nextItem = (SelectItem) value;
            return true;
          } else if (value != null && value.getClass().isArray()) {
            // value is any kind of array (primitive or non-primitive)
            // --> we have to use class Array to get the values
            final int length = Array.getLength(value);
            final Collection<Object> items = new ArrayList<>(length);
            for (int i = 0; i < length; i++) {
              items.add(Array.get(value, i));
            }
            nestedItems = items.iterator();
            return hasNext();
          } else if (value instanceof Iterable) {
            // value is Iterable --> Collection, DataModel,...
            nestedItems = ((Iterable<?>) value).iterator();
            return hasNext();
          } else if (value instanceof Map) {
            final Map<Object, Object> map = (Map<Object, Object>) value;
            final Collection<SelectItem> items = new ArrayList<>(map.size());
            for (final Map.Entry<Object, Object> entry : map.entrySet()) {
              items.add(new SelectItem(entry.getValue(), entry.getKey().toString()));
            }

            nestedItems = items.iterator();
            return hasNext();
          } else {

            if ((facesContext.isProjectStage(ProjectStage.Production) && LOG.isDebugEnabled())
                || LOG.isWarnEnabled()) {
              final ValueExpression expression = currentUISelectItems.getValueExpression("value");
              final Object[] objects = {
                  expression == null ? null : expression.getExpressionString(),
                  getPathToComponent(child),
                  value == null ? null : value.getClass().getName()
              };
              final String message = "ValueExpression {0} of UISelectItems with component-path {1}"
                  + " does not reference an Object of type SelectItem,"
                  + " array, Iterable or Map, but of type: {2}";
              if (facesContext.isProjectStage(ProjectStage.Production)) {
                LOG.debug(message, objects);
              } else {
                LOG.warn(message, objects);
              }
            }
          }
        } else {
          currentComponent = null;
        }
      }
      return false;
    }

    @Override
    public SelectItem next() {
      if (!hasNext()) {
        throw new NoSuchElementException();
      }
      if (nextItem != null) {
        final SelectItem value = nextItem;
        nextItem = null;
        return value;
      }
      if (nestedItems != null) {
        Object item = nestedItems.next();

        if (!(item instanceof SelectItem)) {
          // check new params of SelectItems (since 2.0): itemValue, itemLabel, itemDescription,...
          // Note that according to the spec UISelectItems does not provide Getter and Setter
          // methods for this values, so we have to use the attribute map
          final Map<String, Object> attributeMap = currentUISelectItems.getAttributes();

          // write the current item into the request map under the key listed in var, if available
          boolean wroteRequestMapVarValue = false;
          Object oldRequestMapVarValue = null;
          final String var = (String) attributeMap.get(VAR_ATTR);
          if (var != null && !"".equals(var)) {
            // save the current value of the key listed in var from the request map
            oldRequestMapVarValue = facesContext.getExternalContext().getRequestMap().put(var, item);
            wroteRequestMapVarValue = true;
          }

          // check the itemValue attribute
          Object itemValue = attributeMap.get(ITEM_VALUE_ATTR);
          if (itemValue == null) {
            // the itemValue attribute was not provided
            // --> use the current item as the itemValue
            itemValue = item;
          }

          // Spec: When iterating over the select items, toString()
          // must be called on the string rendered attribute values
          Object itemLabel = attributeMap.get(ITEM_LABEL_ATTR);
          if (itemLabel == null) {
            if (itemValue != null) {
              itemLabel = itemValue.toString();
            }
          } else {
            itemLabel = itemLabel.toString();
          }
          Object itemDescription = attributeMap.get(ITEM_DESCRIPTION_ATTR);
          if (itemDescription != null) {
            itemDescription = itemDescription.toString();
          }
          final Boolean itemDisabled = getBooleanAttribute(currentUISelectItems, ITEM_DISABLED_ATTR, false);
          final Boolean itemLabelEscaped = getBooleanAttribute(currentUISelectItems, ITEM_LABEL_ESCAPED_ATTR, true);
          final Object noSelectionValue = attributeMap.get(NO_SELECTION_VALUE_ATTR);
          item = new SelectItem(itemValue,
              (String) itemLabel,
              (String) itemDescription,
              itemDisabled,
              itemLabelEscaped,
              itemValue.equals(noSelectionValue));

          // remove the value with the key from var from the request map, if previously written
          if (wroteRequestMapVarValue) {
            // If there was a previous value stored with the key from var in the request map, restore it
            if (oldRequestMapVarValue != null) {
              facesContext.getExternalContext()
                  .getRequestMap().put(var, oldRequestMapVarValue);
            } else {
              facesContext.getExternalContext()
                  .getRequestMap().remove(var);
            }
          }
        }
        return (SelectItem) item;
      }
      throw new NoSuchElementException();
    }

    @Override
    public void remove() {
      throw new UnsupportedOperationException();
    }

    public UIComponent getCurrentComponent() {
      return currentComponent;
    }

    private boolean getBooleanAttribute(
        final UIComponent component, final String attrName, final boolean defaultValue) {
      final Object value = component.getAttributes().get(attrName);
      if (value == null) {
        return defaultValue;
      } else if (value instanceof Boolean) {
        return (Boolean) value;
      } else {
        // If the value is a String, parse the boolean.
        // This makes the following code work: <tag attribute="true" />,
        // otherwise you would have to write <tag attribute="#{true}" />.
        return Boolean.valueOf(value.toString());
      }
    }

    private String getPathToComponent(final UIComponent component) {
      final StringBuilder builder = new StringBuilder();

      if (component == null) {
        builder.append("{Component-Path : ");
        builder.append("[null]}");
        return builder.toString();
      }

      getPathToComponent(component, builder);

      builder.insert(0, "{Component-Path : ");
      builder.append("}");

      return builder.toString();
    }

    private void getPathToComponent(final UIComponent component, final StringBuilder builder) {
      if (component == null) {
        return;
      }

      final StringBuilder intBuilder = new StringBuilder();

      intBuilder.append("[Class: ");
      intBuilder.append(component.getClass().getName());
      if (component instanceof UIViewRoot) {
        intBuilder.append(",ViewId: ");
        intBuilder.append(((UIViewRoot) component).getViewId());
      } else {
        intBuilder.append(",Id: ");
        intBuilder.append(component.getId());
      }
      intBuilder.append("]");

      builder.insert(0, intBuilder);

      getPathToComponent(component.getParent(), builder);
    }
  }
  // #################################################################################################################
  // ### END copy out of https://svn.apache.org/repos/asf/myfaces/core/tags/myfaces-core-module-2.2.8/
  // ###     api/src/main/java/javax/faces/component/_SelectItemsIterator.java
  // #################################################################################################################

  // #################################################################################################################
  // ### BEGIN copy out of https://svn.apache.org/repos/asf/myfaces/core/tags/myfaces-core-module-2.2.8/
  // ###     api/src/main/java/javax/faces/component/_EmptyIterator.java
  // #################################################################################################################
  private static class EmptyIterator<T> implements Iterator<T> {

    @Override
    public boolean hasNext() {
      return false;
    }

    @Override
    public T next() {
      throw new NoSuchElementException();
    }

    @Override
    public void remove() {
      throw new UnsupportedOperationException();
    }
  }
  // #################################################################################################################
  // ### END copy out of https://svn.apache.org/repos/asf/myfaces/core/tags/myfaces-core-module-2.2.8/
  // ###     api/src/main/java/javax/faces/component/_EmptyIterator.java
  // #################################################################################################################
}
