org.apache.wicket.Component.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.Component.java

Source

/*
 * 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.wicket;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Optional;

import org.apache.wicket.ajax.IAjaxRegionMarkupIdProvider;
import org.apache.wicket.application.IComponentInstantiationListener;
import org.apache.wicket.authorization.Action;
import org.apache.wicket.authorization.AuthorizationException;
import org.apache.wicket.authorization.IAuthorizationStrategy;
import org.apache.wicket.authorization.UnauthorizedActionException;
import org.apache.wicket.authorization.strategies.page.SimplePageAuthorizationStrategy;
import org.apache.wicket.behavior.Behavior;
import org.apache.wicket.core.request.handler.BookmarkableListenerRequestHandler;
import org.apache.wicket.core.request.handler.ListenerRequestHandler;
import org.apache.wicket.core.request.handler.PageAndComponentProvider;
import org.apache.wicket.core.util.lang.WicketObjects;
import org.apache.wicket.core.util.string.ComponentStrings;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.event.IEventSink;
import org.apache.wicket.event.IEventSource;
import org.apache.wicket.feedback.FeedbackDelay;
import org.apache.wicket.feedback.FeedbackMessage;
import org.apache.wicket.feedback.FeedbackMessages;
import org.apache.wicket.feedback.IFeedback;
import org.apache.wicket.feedback.IFeedbackContributor;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.IMarkupFragment;
import org.apache.wicket.markup.Markup;
import org.apache.wicket.markup.MarkupCache;
import org.apache.wicket.markup.MarkupElement;
import org.apache.wicket.markup.MarkupException;
import org.apache.wicket.markup.MarkupNotFoundException;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.WicketTag;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.StringHeaderItem;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
import org.apache.wicket.markup.html.panel.DefaultMarkupSourcingStrategy;
import org.apache.wicket.markup.html.panel.IMarkupSourcingStrategy;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IComponentAssignedModel;
import org.apache.wicket.model.IComponentInheritedModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.IModelComparator;
import org.apache.wicket.model.IWrapModel;
import org.apache.wicket.protocol.http.WicketFilter;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Response;
import org.apache.wicket.request.component.IRequestableComponent;
import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.ResourceReference;
import org.apache.wicket.response.StringResponse;
import org.apache.wicket.settings.DebugSettings;
import org.apache.wicket.settings.ExceptionSettings;
import org.apache.wicket.util.IHierarchical;
import org.apache.wicket.util.convert.IConverter;
import org.apache.wicket.util.io.IClusterable;
import org.apache.wicket.util.lang.Args;
import org.apache.wicket.util.lang.Classes;
import org.apache.wicket.util.string.PrependingStringBuffer;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.value.ValueMap;
import org.apache.wicket.util.visit.IVisitFilter;
import org.apache.wicket.util.visit.IVisitor;
import org.apache.wicket.util.visit.Visit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Component serves as the highest level abstract base class for all components.
 * 
 * <ul>
 * <li><b>Identity </b>- All Components must have a non-null id which is retrieved by calling
 * getId(). The id must be unique within the {@link MarkupContainer} that holds the Component, but
 * does not have to be globally unique or unique within a Page's component hierarchy.</li>
 * <li><b>Hierarchy </b>- A component has a parent which can be retrieved with {@link #getParent()}.
 * If a component is an instance of MarkupContainer, it may have children. In this way it has a
 * place in the hierarchy of components contained on a given page.
 * <p>
 * The path from the Page at the root of the component hierarchy to a given Component is simply the
 * concatenation with colon separators of each id along the way. For example, the path "a:b:c" would
 * refer to the component named "c" inside the MarkupContainer named "b" inside the container named
 * "a". The path to a component can be retrieved by calling {@link #getPath()}. To get a Component
 * path relative to the page that contains it, you can call {@link #getPageRelativePath()}.</li>
 * <li><b>LifeCycle </b>- Components participate in the following lifecycle phases:
 * <ul>
 * <li><b>Construction </b>- A Component is constructed with the Java language new operator.
 * Children may be added during construction if the Component is a MarkupContainer.
 * {@link IComponentInstantiationListener}s are notified of component instantiation.
 * <p>
 * {@link #onInitialize()} is called on the component as soon as the component is part of a page's
 * component tree. At this state the component is able to access its markup.</li>
 * <li><b>Request Handling </b>- An incoming request is processed by a protocol request handler such
 * as {@link WicketFilter}. An associated Application object creates {@link Session},
 * {@link Request} and {@link Response} objects for use by a given Component in updating its model
 * and rendering a response. These objects are stored inside a container called {@link RequestCycle}
 * which is accessible via {@link Component#getRequestCycle()}. The convenience methods
 * {@link Component#getRequest()}, {@link Component#getResponse()} and
 * {@link Component#getSession()} provide easy access to the contents of this container.</li>
 * <li><b>Listener Invocation </b>- If the request references an {@link IRequestListener} on an
 * existing Component (or one of its {@link Behavior}s, see below), that listener is notified,
 * allowing arbitrary user code to handle events such as link clicks or form submits. Although
 * arbitrary listeners are supported in Wicket, the need to implement a new class of listener is
 * unlikely for a web application and even the need to implement a listener interface directly is
 * highly discouraged. Instead, calls to listeners are routed through logic specific to the event,
 * resulting in calls to user code through other overridable methods. See {@link Form} for an
 * example of a component which listens for events via {@link IFormSubmitListener}.</li>
 * <li><b>Rendering </b>- Before a page or part of a page (in case of Ajax updates) is rendered, all
 * containing components are able to prepare for rendering via two hook methods:
 * {@link #onConfigure()} (regardless whether they are visible or not) and {@link #onBeforeRender()}
 * (if visible only) . <br>
 * A markup response is generated by the Component via {@link Component#render()}, which calls
 * subclass implementation code contained in {@link Component#onRender()}. Once this phase begins, a
 * Component becomes immutable. Attempts to alter the Component will result in a
 * WicketRuntimeException.</li>
 * <li><b>Detachment </b>- Each request cycle finishes by detaching all touched components.
 * Subclasses should clean up their state by overriding {@link #onDetach()} or more specifically
 * {@link #detachModels()} if they keep references to models beside the default model.</li>
 * </ul>
 * </li>
 * <li><b>Visibility </b>- If a component is not visible (see {@link #setVisible(boolean)}) it will
 * not render a response (nor will their children).</li>
 * <li><b>Enabling </b>- Component subclasses take into account their enabled state (see
 * {@link #setEnabled(boolean)} when rendering, and in case of a {@link FormComponent} will not not
 * update its model while the request is handled.</li>
 * <li><b>Models </b>- The primary responsibility of a component is to use its model (an object that
 * implements {@link IModel}) to render a response in an appropriate markup language, such as HTML.
 * In addition, {@link FormComponent}s know how to update their models based on request information,
 * see {@link FormComponent#updateModel()}. Since the IModel interface is a wrapper around another
 * object, a convenience method {@link Component#getDefaultModelObject()} is provided to retrieve
 * the object from its IModel wrapper. A further convenience method,
 * {@link Component#getDefaultModelObjectAsString()}, is provided for the very common operation of
 * converting the wrapped object to a String. <br>
 * The component's model can be passed in the constructor or set via
 * {@link Component#setDefaultModel(IModel)}. In neither case a model can be created on demand with
 * {@link #initModel()}.<br>
 * Note that a component can have more models besides its default model.</li>
 * <li><b>Behaviors </b>- You can add multiple {@link Behavior}s to any component if you need to
 * dynamically alter the behavior of components, e.g. manipulate attributes of the markup tag to
 * which a Component is attached. Behaviors take part in the component's lifecycle through various
 * callback methods.</li>
 * <li><b>Locale </b>- The Locale for a Component is available through {@link #getLocale()}, which
 * delegates to its parent's locale, finally consulting the {@link Session}'s locale.</li>
 * <li><b>Style </b>- The Session's style ("skin") is available through
 * {@link org.apache.wicket.Component#getStyle()}. Styles are intended to give a particular look to
 * all components or resources in a session that is independent of its Locale. For example, a style
 * might be a set of resources, including images and markup files, which gives the design look of
 * "ocean" to the user. If the Session's style is set to "ocean" and these resources are given names
 * suffixed with "_ocean", Wicket's resource management logic will prefer these resources to other
 * resources, such as default resources, which are not as good of a match.</li>
 * <li><b>Variation </b>- Whereas styles are Session (user) specific, variations are component
 * specific. E.g. if the Style is "ocean" and {@link #getVariation()} returnss "NorthSea", than the
 * resources are given the names suffixed with "_ocean_NorthSea".</li>
 * <li><b>String Resources </b>- Components can have associated String resources via the
 * Application's Localizer, which is available through the method {@link Component#getLocalizer()}.
 * The convenience methods {@link Component#getString(String key)} and
 * {@link Component#getString(String key, IModel model)} wrap the identical methods on the
 * Application Localizer for easy access in Components.</li>
 * <li><b>Feedback Messages </b>- The {@link Component#debug(Serializable)},
 * {@link Component#info(Serializable)}, {@link Component#warn(Serializable)},
 * {@link Component#error(java.io.Serializable)} and {@link Component#fatal(Serializable)} methods
 * associate feedback messages with a Component. It is generally not necessary to use these methods
 * directly since Wicket validators automatically register feedback messages on Components. Feedback
 * message for a given Component can be retrieved with {@link Component#getFeedbackMessages}.</li>
 * <li><b>Versioning </b>- Pages are the unit of versioning in Wicket, but fine-grained control of
 * which Components should participate in versioning is possible via the
 * {@link Component#setVersioned(boolean)} method. The versioning participation of a given Component
 * can be retrieved with {@link Component#isVersioned()}.</li>
 * <li><b>Page </b>- The Page containing any given Component can be retrieved by calling
 * {@link Component#getPage()}. If the Component is not attached to a Page, an IllegalStateException
 * will be thrown. An equivalent method, {@link Component#findPage()} is available for special
 * circumstances where it might be desirable to get a null reference back instead.</li>
 * <li><b>Application </b>- The {@link #getApplication()} method provides convenient access to the
 * {@link Application} for a Component.</li>
 * <li><b>AJAX support</b>- Components can be re-rendered after the whole Page has been rendered at
 * least once by calling doRender().</li>
 * <li><b>Security </b>- All components are subject to an {@link IAuthorizationStrategy} which
 * controls instantiation, visibility and enabling. See {@link SimplePageAuthorizationStrategy} for
 * a simple implementation.</li>
 * 
 * @author Jonathan Locke
 * @author Chris Turner
 * @author Eelco Hillenius
 * @author Johan Compagner
 * @author Juergen Donnerstag
 * @author Igor Vaynberg (ivaynberg)
 */
public abstract class Component implements IClusterable, IConverterLocator, IRequestableComponent,
        IHeaderContributor, IHierarchical<Component>, IEventSink, IEventSource, IFeedbackContributor {
    /** Log. */
    private static final Logger log = LoggerFactory.getLogger(Component.class);

    private static final long serialVersionUID = 1L;

    /**
     * Action used with IAuthorizationStrategy to determine whether a component is allowed to be
     * enabled.
     * <p>
     * If enabling is authorized, a component may decide by itself (typically using it's enabled
     * property) whether it is enabled or not. If enabling is not authorized, the given component is
     * marked disabled, regardless its enabled property.
     * <p>
     * When a component is not allowed to be enabled (in effect disabled through the implementation
     * of this interface), Wicket will try to prevent model updates too. This is not completely fail
     * safe, as constructs like:
     * 
     * <pre>
     * 
     * User u = (User)getModelObject();
     * u.setName(&quot;got you there!&quot;);
     * 
     * </pre>
     * 
     * can't be prevented. Indeed it can be argued that any model protection is best dealt with in
     * your model objects to be completely secured. Wicket will catch all normal framework-directed
     * use though.
     */
    public static final Action ENABLE = new Action(Action.ENABLE);

    /** Separator for component paths */
    public static final char PATH_SEPARATOR = ':';
    /** Path segment that represents this component's parent */
    public static final String PARENT_PATH = "..";

    /**
     * Action used with IAuthorizationStrategy to determine whether a component and its children are
     * allowed to be rendered.
     * <p>
     * There are two uses for this method:
     * <ul>
     * <li>The 'normal' use is for controlling whether a component is rendered without having any
     * effect on the rest of the processing. If a strategy lets this method return 'false', then the
     * target component and its children will not be rendered, in the same fashion as if that
     * component had visibility property 'false'.</li>
     * <li>The other use is when a component should block the rendering of the whole page. So
     * instead of 'hiding' a component, what we generally want to achieve here is that we force the
     * user to logon/give-credentials for a higher level of authorization. For this functionality,
     * the strategy implementation should throw a {@link AuthorizationException}, which will then be
     * handled further by the framework.</li>
     * </ul>
     * </p>
     */
    public static final Action RENDER = new Action(Action.RENDER);

    /** meta data for user specified markup id */
    private static final MetaDataKey<String> MARKUP_ID_KEY = new MetaDataKey<String>() {
        private static final long serialVersionUID = 1L;
    };

    /** meta data for user specified markup id */
    private static final MetaDataKey<FeedbackMessages> FEEDBACK_KEY = new MetaDataKey<FeedbackMessages>() {
        private static final long serialVersionUID = 1L;
    };

    /** Basic model IModelComparator implementation for normal object models */
    private static final IModelComparator defaultModelComparator = new IModelComparator() {
        private static final long serialVersionUID = 1L;

        @Override
        public boolean compare(Component component, Object b) {
            final Object a = component.getDefaultModelObject();
            if (a == null && b == null) {
                return true;
            }
            if (a == null || b == null) {
                return false;
            }
            return a.equals(b);
        }
    };

    /** True when a component is being auto-added */
    private static final int FLAG_AUTO = 0x0001;

    /** Flag for escaping HTML in model strings */
    private static final int FLAG_ESCAPE_MODEL_STRINGS = 0x0002;

    /** Boolean whether this component's model is inheritable. */
    static final int FLAG_INHERITABLE_MODEL = 0x0004;

    /** Versioning boolean */
    private static final int FLAG_VERSIONED = 0x0008;

    /** Visibility boolean */
    private static final int FLAG_VISIBLE = 0x0010;

    /** Render tag boolean */
    private static final int FLAG_RENDER_BODY_ONLY = 0x0020;

    /** Ignore attribute modifiers */
    private static final int FLAG_IGNORE_ATTRIBUTE_MODIFIER = 0x0040;

    /** True when a component is enabled for model updates and is reachable. */
    private static final int FLAG_ENABLED = 0x0080;

    /** Reserved subclass-definable flag bit */
    protected static final int FLAG_RESERVED1 = 0x0100;
    /** Reserved subclass-definable flag bit */
    protected static final int FLAG_RESERVED2 = 0x0200;
    /** Reserved subclass-definable flag bit */
    protected static final int FLAG_RESERVED3 = 0x0400;
    /** Reserved subclass-definable flag bit */
    protected static final int FLAG_RESERVED4 = 0x0800;

    /** Boolean whether this component was rendered at least once for tracking changes. */
    private static final int FLAG_HAS_BEEN_RENDERED = 0x1000;

    /**
     * Internal indicator of whether this component may be rendered given the current context's
     * authorization. It overrides the visible flag in case this is false. Authorization is done
     * before trying to render any component (otherwise we would end up with a half rendered page in
     * the buffer)
     */
    private static final int FLAG_IS_RENDER_ALLOWED = 0x2000;

    /** Whether or not the component should print out its markup id into the id attribute */
    private static final int FLAG_OUTPUT_MARKUP_ID = 0x4000;

    /**
     * Output a placeholder tag if the component is not visible. This is useful in ajax mode to go
     * to visible(false) to visible(true) without the overhead of repainting a visible parent
     * container
     */
    private static final int FLAG_PLACEHOLDER = 0x8000;

    /** Reserved subclass-definable flag bit */
    protected static final int FLAG_RESERVED5 = 0x10000;
    /** onInitialize called */
    protected static final int FLAG_INITIALIZED = 0x20000;
    /** Set when a component is removed from the hierarchy */
    private static final int FLAG_REMOVED = 0x40000;
    /** Reserved subclass-definable flag bit */
    protected static final int FLAG_RESERVED8 = 0x80000;

    /**
     * Flag that determines whether the model is set. This is necessary because of the way we
     * represent component state ({@link #data}). We can't distinguish between model and behavior
     * using instanceof, because one object can implement both interfaces. Thus we need this flag -
     * when the flag is set, first object in {@link #data} is always model.
     */
    private static final int FLAG_MODEL_SET = 0x100000;

    /**
     * Flag that restricts visibility of a component when set to true. This is usually used when a
     * component wants to restrict visibility of another component. Calling
     * {@link #setVisible(boolean)} on a component does not always have the desired effect because
     * isVisible() can be overwritten thus this flag offers an alternative that should always work.
     */
    private static final int FLAG_VISIBILITY_ALLOWED = 0x40000000;

    /**
     * The name of attribute that will hold markup id
     */
    private static final String MARKUP_ID_ATTR_NAME = "id";

    /**
     * Meta data key for line precise error logging for the moment of addition. Made package private
     * for access in {@link MarkupContainer} and {@link Page}
     */
    static final MetaDataKey<String> ADDED_AT_KEY = new MetaDataKey<String>() {
        private static final long serialVersionUID = 1L;
    };

    /**
     * meta data key for line precise error logging for the moment of construction. Made package
     * private for access in {@link Page}
     */
    static final MetaDataKey<String> CONSTRUCTED_AT_KEY = new MetaDataKey<String>() {
        private static final long serialVersionUID = 1L;
    };

    /** Component flags. See FLAG_* for possible non-exclusive flag values. */
    private int flags = FLAG_VISIBLE | FLAG_ESCAPE_MODEL_STRINGS | FLAG_VERSIONED | FLAG_ENABLED
            | FLAG_IS_RENDER_ALLOWED | FLAG_VISIBILITY_ALLOWED | FLAG_RESERVED5 /* page's stateless hint */;

    private static final short RFLAG_ENABLED_IN_HIERARCHY_VALUE = 0x1;
    private static final short RFLAG_ENABLED_IN_HIERARCHY_SET = 0x2;
    private static final short RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED = 0x4;
    private static final short RFLAG_VISIBLE_IN_HIERARCHY_SET = 0x8;
    /** onconfigure has been called */
    private static final short RFLAG_CONFIGURED = 0x10;
    private static final short RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED = 0x20;
    private static final short RFLAG_INITIALIZE_SUPER_CALL_VERIFIED = 0x40;
    protected static final short RFLAG_CONTAINER_DEQUEING = 0x80;
    private static final short RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED = 0x100;
    /**
     * Flag that makes we are in before-render callback phase Set after component.onBeforeRender is
     * invoked (right before invoking beforeRender on children)
     */
    private static final short RFLAG_RENDERING = 0x200;
    private static final short RFLAG_PREPARED_FOR_RENDER = 0x400;
    private static final short RFLAG_AFTER_RENDER_SUPER_CALL_VERIFIED = 0x800;
    private static final short RFLAG_DETACHING = 0x1000;
    /** True when a component is being removed from the hierarchy */
    private static final short RFLAG_REMOVING_FROM_HIERARCHY = 0x2000;

    /**
     * Flags that only keep their value during the request. Useful for cache markers, etc. At the
     * end of the request the value of this variable is reset to 0
     */
    private transient short requestFlags = 0;

    /** Component id. */
    private final String id;

    /** Any parent container. */
    private MarkupContainer parent;

    /**
     * Instead of remembering the whole markupId, we just remember the number for this component so
     * we can "reconstruct" the markupId on demand. While this could be part of {@link #data},
     * profiling showed that having it as separate property consumes less memory.
     */
    int generatedMarkupId = -1;

    /** Must only be used by auto components */
    private transient IMarkupFragment markup;

    /**
     * Will be re-created instead of persisted when session is replicated. Markup sourcing strategy
     * are typically stateless (but don't have to).
     */
    private transient IMarkupSourcingStrategy markupSourcingStrategy;

    /**
     * The object that holds the component state.
     * <p>
     * What's stored here depends on what attributes are set on component. Data can contains
     * combination of following attributes:
     * <ul>
     * <li>Model (indicated by {@link #FLAG_MODEL_SET})
     * <li>MetaDataEntry (optionally {@link MetaDataEntry}[] if more metadata entries are present) *
     * <li>{@link Behavior}(s) added to component. The behaviors are not stored in separate array,
     * they are part of the {@link #data} array (this is in order to save the space of the pointer
     * to an empty array as most components have no behaviours). - FIXME - explain why - is this
     * correct?
     * </ul>
     * If there is only one attribute set (i.e. model or MetaDataEntry([]) or one behavior), the
     * #data object points directly to value of that attribute. Otherwise the data is of type
     * Object[] where the attributes are ordered as specified above.
     * <p>
     */
    Object data = null;

    final int data_start() {
        return getFlag(FLAG_MODEL_SET) ? 1 : 0;
    }

    final int data_length() {
        if (data == null) {
            return 0;
        } else if (data instanceof Object[] && !(data instanceof MetaDataEntry<?>[])) {
            return ((Object[]) data).length;
        } else {
            return 1;
        }
    }

    final Object data_get(int index) {
        if (data == null) {
            return null;
        } else if (data instanceof Object[] && !(data instanceof MetaDataEntry<?>[])) {
            Object[] array = (Object[]) data;
            return index < array.length ? array[index] : null;
        } else if (index == 0) {
            return data;
        } else {
            return null;
        }
    }

    final void data_set(int index, Object object) {
        if (index > data_length() - 1) {
            throw new IndexOutOfBoundsException(
                    "can not set data at " + index + " when data_length() is " + data_length());
        } else if (index == 0 && !(data instanceof Object[] && !(data instanceof MetaDataEntry<?>[]))) {
            data = object;
        } else {
            Object[] array = (Object[]) data;
            array[index] = object;
        }
    }

    final void data_add(Object object) {
        data_insert(-1, object);
    }

    final void data_insert(int position, Object object) {
        int currentLength = data_length();
        if (position == -1) {
            position = currentLength;
        }
        if (position > currentLength) {
            throw new IndexOutOfBoundsException(
                    "can not insert data at " + position + " when data_length() is " + currentLength);
        }
        if (currentLength == 0) {
            data = object;
        } else if (currentLength == 1) {
            Object[] array = new Object[2];
            if (position == 0) {
                array[0] = object;
                array[1] = data;
            } else {
                array[0] = data;
                array[1] = object;
            }
            data = array;
        } else {
            Object[] array = new Object[currentLength + 1];
            Object[] current = (Object[]) data;
            int after = currentLength - position;
            if (position > 0) {
                System.arraycopy(current, 0, array, 0, position);
            }
            array[position] = object;
            if (after > 0) {
                System.arraycopy(current, position, array, position + 1, after);
            }
            data = array;
        }
    }

    final void data_remove(int position) {
        int currentLength = data_length();

        if (position > currentLength - 1) {
            throw new IndexOutOfBoundsException();
        } else if (currentLength == 1) {
            data = null;
        } else if (currentLength == 2) {
            Object[] current = (Object[]) data;
            if (position == 0) {
                data = current[1];
            } else {
                data = current[0];
            }
        } else {
            Object[] current = (Object[]) data;
            data = new Object[currentLength - 1];

            if (position > 0) {
                System.arraycopy(current, 0, data, 0, position);
            }
            if (position != currentLength - 1) {
                final int left = currentLength - position - 1;
                System.arraycopy(current, position + 1, data, position, left);
            }
        }
    }

    /**
     * Constructor. All components have names. A component's id cannot be null. This is the minimal
     * constructor of component. It does not register a model.
     * 
     * @param id
     *            The non-null id of this component
     * @throws WicketRuntimeException
     *             Thrown if the component has been given a null id.
     */
    public Component(final String id) {
        this(id, null);
    }

    /**
     * Constructor. All components have names. A component's id cannot be null. This constructor
     * includes a model.
     * 
     * @param id
     *            The non-null id of this component
     * @param model
     *            The component's model
     * 
     * @throws WicketRuntimeException
     *             Thrown if the component has been given a null id.
     */
    public Component(final String id, final IModel<?> model) {
        checkId(id);
        this.id = id;

        init();

        Application application = getApplication();
        application.getComponentInstantiationListeners().onInstantiation(this);

        final DebugSettings debugSettings = application.getDebugSettings();
        if (debugSettings.isLinePreciseReportingOnNewComponentEnabled() && debugSettings.getComponentUseCheck()) {
            setMetaData(CONSTRUCTED_AT_KEY, ComponentStrings.toString(this, new MarkupException("constructed")));
        }

        if (model != null) {
            setModelImpl(wrap(model));
        }
    }

    /**
     * Let subclasses initialize this instance, before constructors are executed. <br>
     * This method is intentionally <b>not</b> declared protected, to limit overriding to classes in
     * this package.
     */
    void init() {
    }

    /**
     * Get the Markup associated with the Component. If not subclassed, the parent container is
     * asked to return the markup of this child component.
     * <p/>
     * Components like Panel and Border should return the "calling" markup fragment, e.g.
     * <code>&lt;span wicket:id="myPanel"&gt;body&lt;/span&gt;</code>. You may use
     * Panel/Border/Enclosure.getMarkup(null) to return the associated markup file. And
     * Panel/Border/Enclosure.getMarkup(child) will search the child in the appropriate markup
     * fragment.
     * 
     * @see MarkupContainer#getMarkup(Component)
     * 
     * @return The markup fragment
     */
    public IMarkupFragment getMarkup() {
        // Markup already determined or preset?
        if (markup != null) {
            return markup;
        }

        // No parent, than check associated markup files
        if (parent == null) {
            // Must be a MarkupContainer to have associated markup file
            if (this instanceof MarkupContainer) {
                MarkupContainer container = (MarkupContainer) this;
                Markup associatedMarkup = container.getAssociatedMarkup();
                if (associatedMarkup != null) {
                    markup = associatedMarkup;
                    return markup;
                }
            }

            // Don't know how to find the markup
            throw new MarkupNotFoundException(
                    "Can not determine Markup. Component is not yet connected to a parent. " + toString());
        }

        // Ask the parent for find the markup for me
        markup = parent.getMarkup(this);
        return markup;
    }

    /**
     * @return The 'id' attribute from the associated markup tag
     */
    public final String getMarkupIdFromMarkup() {
        ComponentTag tag = getMarkupTag();
        if (tag != null) {
            String id = tag.getAttribute("id");
            if (Strings.isEmpty(id) == false) {
                return id.trim();
            }
        }

        return null;
    }

    /**
     * Set the markup for the component. Note that the component's markup variable is transient and
     * thus must only be used for one render cycle. E.g. auto-component are using it. You may also
     * it if you subclassed getMarkup().
     * 
     * @param markup
     */
    public final Component setMarkup(final IMarkupFragment markup) {
        this.markup = markup;
        return this;
    }

    /**
     * Called on all components before any component is rendered. This method
     * should be used to configure such things as visibility and enabled flags.
     * <p>
     * Overrides must call {@code super.onConfigure()}, usually before any other code
     * <p>
     * NOTE: Component hierarchy should not be modified inside this method, instead it should be
     * done in {@link #onBeforeRender()}
     * <p>
     * NOTE: Why this method is preferrable to directly overriding {@link #isVisible()} and
     * {@link #isEnabled()}? Because those methods are called multiple times even for processing of
     * a single request. If they contain expensive logic they can slow down the response time of the
     * entire page. Further, overriding those methods directly on form components may lead to
     * inconsistent or unexpected state depending on when those methods are called in the form
     * processing workflow. It is a better practice to push changes to state rather than pull.
     * <p>
     * NOTE: If component's visibility or another property depends on another component you may call
     * {@code other.configure()} followed by {@code other.isVisible()} as mentioned in
     * {@link #configure()} javadoc.
     * <p>
     * NOTE: Why should {@link #onBeforeRender()} not be used for this? Because if a component's
     * visibility is controlled inside {@link #onBeforeRender()}, once invisible the component will
     * never become visible again.
     */
    protected void onConfigure() {
        setRequestFlag(RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED, true);
    }

    /**
     * This method is meant to be used as an alternative to initialize components. Usually the
     * component's constructor is used for this task, but sometimes a component cannot be
     * initialized in isolation, it may need to access its parent component or its markup in order
     * to fully initialize. This method is invoked once per component's lifecycle when a path exists
     * from this component to the {@link Page} thus providing the component with an atomic callback
     * when the component's environment is built out.
     * <p>
     * Overrides must call super#{@link #onInitialize()}. Usually this should be the first thing an
     * override does, much like a constructor.
     * </p>
     * <p>
     * Parent containers are guaranteed to be initialized before their children
     * </p>
     * 
     * <p>
     * It is safe to use {@link #getPage()} in this method
     * </p>
     * 
     * <p>
     * NOTE:The timing of this call is not precise, the contract is that it is called sometime
     * before {@link Component#onBeforeRender()}.
     * </p>
     * 
     */
    protected void onInitialize() {
        setRequestFlag(RFLAG_INITIALIZE_SUPER_CALL_VERIFIED, true);
    }

    /**
     * Checks if the component has been initialized - {@link #onInitialize()} has been called
     * 
     * @return {@code true} if component has been initialized
     */
    public final boolean isInitialized() {
        return getFlag(FLAG_INITIALIZED);
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * 
     * Used to call {@link #onInitialize()}
     */
    public void internalInitialize() {
        fireInitialize();
    }

    /**
     * Used to call {@link #onInitialize()}
     */
    final void fireInitialize() {
        if (!getFlag(FLAG_INITIALIZED)) {
            setFlag(FLAG_INITIALIZED, true);

            setRequestFlag(RFLAG_INITIALIZE_SUPER_CALL_VERIFIED, false);
            onInitialize();
            verifySuperCall("onInitialize", RFLAG_INITIALIZE_SUPER_CALL_VERIFIED);

            getApplication().getComponentInitializationListeners().onInitialize(this);
        } else if (getFlag(FLAG_REMOVED)) {
            setFlag(FLAG_REMOVED, false);

            setRequestFlag(RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED, false);
            onReAdd();
            verifySuperCall("onReAdd", RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED);
        }
    }

    /**
     * Called on every component after the page is rendered. Calls hook {@link #onAfterRender()}.
     */
    final void afterRender() {
        setRequestFlag(RFLAG_PREPARED_FOR_RENDER, false);

        try {
            setRequestFlag(RFLAG_AFTER_RENDER_SUPER_CALL_VERIFIED, false);

            onAfterRender();
            getApplication().getComponentOnAfterRenderListeners().onAfterRender(this);
            verifySuperCall("onAfterRender", RFLAG_AFTER_RENDER_SUPER_CALL_VERIFIED);
        } finally {
            // this flag must always be set to false.
            setRequestFlag(RFLAG_RENDERING, false);
        }
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * 
     * Called on all components before any component is rendered. Calls hooks
     * {@link #configure()} and (if visible) {@link #onBeforeRender()}
     * and delegates to {@link #beforeRender()} of all child components.
     */
    public final void beforeRender() {
        if (this instanceof IFeedback) {
            Optional<FeedbackDelay> delay = FeedbackDelay.get(getRequestCycle());
            if (delay.isPresent()) {
                delay.get().postpone((IFeedback) this);
                return;
            }
        }

        configure();

        if ((determineVisibility()) && !getRequestFlag(RFLAG_RENDERING)
                && !getRequestFlag(RFLAG_PREPARED_FOR_RENDER)) {
            try {
                setRequestFlag(RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED, false);

                Application application = getApplication();
                application.getComponentPreOnBeforeRenderListeners().onBeforeRender(this);

                onBeforeRender();
                application.getComponentPostOnBeforeRenderListeners().onBeforeRender(this);

                verifySuperCall("onBeforeRender", RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED);
            } catch (RuntimeException ex) {
                setRequestFlag(RFLAG_PREPARED_FOR_RENDER, false);
                throw ex;
            }
        }
    }

    /**
     * Triggers {@link #onConfigure()} to be invoked on this component if it has not already during
     * this request.
     * <p>
     * This method should be invoked before any calls to {@link #isVisible()} or
     * {@link #isEnabled()}. Usually this method will be called by the framework before the
     * component is rendered and so users should not need to call it; however, in cases where
     * visibility or enabled or other state of one component depends on the state of another this
     * method should be manually invoked on the other component by the user. EG to link visiliby of
     * two markup containers the following should be done:
     * 
     * <pre>
     * final WebMarkupContainer source=new WebMarkupContainer("a") {
     *    protected void onConfigure() {
     *    setVisible(Math.rand()>0.5f);
     *  }
     * };
     * 
     * WebMarkupContainer linked=new WebMarkupContainer("b") {
     *    protected void onConfigure() {
     *       source.configure(); // make sure source is configured
     *       setVisible(source.isVisible());
     *  }
     * }
     * </pre>
     * 
     * </p>
     */
    public final void configure() {
        if (!getRequestFlag(RFLAG_CONFIGURED)) {
            clearEnabledInHierarchyCache();
            clearVisibleInHierarchyCache();

            setRequestFlag(RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED, false);
            onConfigure();
            verifySuperCall("onConfigure", RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED);

            for (Behavior behavior : getBehaviors()) {
                if (isBehaviorAccepted(behavior)) {
                    behavior.onConfigure(this);
                }
            }

            // check authorization
            setRenderAllowed();

            internalOnAfterConfigure();

            getApplication().getComponentOnConfigureListeners().onConfigure(this);

            setRequestFlag(RFLAG_CONFIGURED, true);
        }
    }

    /**
     * Verify super calls of an overridden hook method.
     */
    private final void verifySuperCall(String method, short flag) {
        if (!getRequestFlag(flag)) {
            throw new IllegalStateException(String.format("%s() in the hierarchy of %s has not called super.%s()",
                    method, getClass().getName(), method));
        }

        setRequestFlag(flag, false);
    }

    /**
     * Called after the {@link #onConfigure()}, but before {@link #onBeforeRender()}
     */
    void internalOnAfterConfigure() {
    }

    /**
     * Redirects to any intercept page previously specified by a call to {@link #redirectToInterceptPage(Page)}.
     * The redirect is done by throwing an exception. If there is no intercept page no exception
     * will be thrown and the program flow will continue uninterrupted.
     * 
     * Example:
     * 
     * <pre>
     * add(new Link(&quot;login&quot;)
     * {
     *    protected void onClick()
     *    {
     *       if (authenticate())
     *       {
     *          continueToOriginalDestination();
     *          // if we reach this line there was no intercept page, so go to home page
     *          setResponsePage(WelcomePage.class);
     *       }
     *    }
     * });
     * 
     * @see Component#redirectToInterceptPage(Page)
     */
    public final void continueToOriginalDestination() {
        RestartResponseAtInterceptPageException.continueToOriginalDestination();
    }

    /**
     * Clears any data about previously intercepted page.
     */
    public final void clearOriginalDestination() {
        RestartResponseAtInterceptPageException.clearOriginalDestination();
    }

    /**
     * Registers a debug feedback message for this component
     * 
     * @param message
     *            The feedback message
     */
    @Override
    public final void debug(final Serializable message) {
        getFeedbackMessages().debug(this, message);
        addStateChange();
    }

    /**
     * Signals this Component that it is removed from the Component hierarchy.
     */
    final void internalOnRemove() {
        setRequestFlag(RFLAG_REMOVING_FROM_HIERARCHY, true);
        onRemove();
        setFlag(FLAG_REMOVED, true);
        if (getRequestFlag(RFLAG_REMOVING_FROM_HIERARCHY)) {
            throw new IllegalStateException(Component.class.getName()
                    + " has not been properly removed from hierachy. Something in the hierarchy of "
                    + getClass().getName()
                    + " has not called super.onRemove() in the override of onRemove() method");
        }
        new Behaviors(this).onRemove(this);
        removeChildren();
    }

    /**
     * Detaches the component. This is called at the end of the request for all the pages that are
     * touched in that request.
     */
    @Override
    public final void detach() {
        try {
            setRequestFlag(RFLAG_DETACHING, true);
            onDetach();
            if (getRequestFlag(RFLAG_DETACHING)) {
                throw new IllegalStateException(Component.class.getName()
                        + " has not been properly detached. Something in the hierarchy of " + getClass().getName()
                        + " has not called super.onDetach() in the override of onDetach() method");
            }

            // always detach models because they can be attached without the
            // component. eg component has a compoundpropertymodel and one of its
            // children component's getmodelobject is called
            detachModels();

            // detach any behaviors
            new Behaviors(this).detach();
        } catch (Exception x) {
            throw new WicketRuntimeException("An error occurred while detaching component: " + toString(true), x);
        }

        // always detach children because components can be attached
        // independently of their parents
        detachChildren();

        // reset the model to null when the current model is a IWrapModel and
        // the model that created it/wrapped in it is a IComponentInheritedModel
        // The model will be created next time.
        if (getFlag(FLAG_INHERITABLE_MODEL)) {
            setModelImpl(null);
            setFlag(FLAG_INHERITABLE_MODEL, false);
        }

        clearEnabledInHierarchyCache();
        clearVisibleInHierarchyCache();

        // clear request flags but keep super call verifications WICKET-5417
        requestFlags &= (RFLAG_INITIALIZE_SUPER_CALL_VERIFIED | RFLAG_ON_CONFIGURE_SUPER_CALL_VERIFIED
                | RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED);

        detachFeedback();

        internalDetach();

        // notify any detach listener
        IDetachListener detachListener = getApplication().getFrameworkSettings().getDetachListener();
        if (detachListener != null) {
            detachListener.onDetach(this);
        }
    }

    private void detachFeedback() {
        FeedbackMessages feedback = getMetaData(FEEDBACK_KEY);
        if (feedback != null) {
            feedback.clear(getApplication().getApplicationSettings().getFeedbackMessageCleanupFilter());

            if (feedback.isEmpty()) {
                setMetaData(FEEDBACK_KEY, null);
            } else {
                feedback.detach();
            }
        }
    }

    /**
     * Removes the cached markup at the end of the request. For the next request it will be get
     * either from the parent's markup or from {@link MarkupCache}.
     */
    private void internalDetach() {
        markup = null;
    }

    /**
     * Detaches all models
     */
    public void detachModels() {
        // Detach any detachable model from this component
        detachModel();
    }

    /**
     * Registers an error feedback message for this component
     * 
     * @param message
     *            The feedback message
     */
    @Override
    public final void error(final Serializable message) {
        getFeedbackMessages().error(this, message);
        addStateChange();
    }

    /**
     * Registers a fatal feedback message for this component
     * 
     * @param message
     *            The feedback message
     */
    @Override
    public final void fatal(final Serializable message) {
        getFeedbackMessages().fatal(this, message);
        addStateChange();
    }

    /**
     * Finds the first container parent of this component of the given class.
     * 
     * @param <Z>
     *            type of parent
     * 
     * 
     * @param c
     *            MarkupContainer class to search for
     * @return First container parent that is an instance of the given class, or null if none can be
     *         found
     */
    public final <Z> Z findParent(final Class<Z> c) {
        // Start with immediate parent
        MarkupContainer current = parent;

        // Walk up containment hierarchy
        while (current != null) {
            // Is current an instance of this class?
            if (c.isInstance(current)) {
                return c.cast(current);
            }

            // Check parent
            current = current.getParent();
        }

        // Failed to find component
        return null;
    }

    /**
     * @return The nearest markup container with associated markup
     */
    public final MarkupContainer findParentWithAssociatedMarkup() {
        MarkupContainer container = parent;
        while (container != null) {
            if (container.getAssociatedMarkup() != null) {
                return container;
            }
            container = container.getParent();
        }

        // This should never happen since Page always has associated markup
        throw new WicketRuntimeException("Unable to find parent with associated markup");
    }

    /**
     * Gets interface to application that this component is a part of.
     * 
     * @return The application associated with the session that this component is in.
     * @see Application
     */
    public final Application getApplication() {
        return Application.get();
    }

    /**
     * @return A path of the form [page-class-name]:[page-relative-path]
     * @see Component#getPageRelativePath()
     */
    public final String getClassRelativePath() {
        return getClass().getName() + PATH_SEPARATOR + getPageRelativePath();
    }

    /**
     * Get the converter that should be used by this component, delegates to
     * {@link #createConverter(Class)} and then to the application's
     * {@link IConverterLocator}.
     *
     * @param type
     *            The type to convert to
     *
     * @return The converter that should be used by this component
     */
    @SuppressWarnings("unchecked")
    @Override
    public <C> IConverter<C> getConverter(Class<C> type) {
        IConverter<?> converter = createConverter(type);
        if (converter != null) {
            return (IConverter<C>) converter;
        }
        return getApplication().getConverterLocator().getConverter(type);
    }

    /**
     * Factory method for converters to be used by this component,
     * returns {@code null} by default.
     *
     * @param type
     *            The type to convert to
     *
     * @return a converter to be used by this component
     */
    protected IConverter<?> createConverter(Class<?> type) {
        return null;
    }

    /**
     * Gets whether model strings should be escaped.
     * 
     * @return Returns whether model strings should be escaped
     */
    public final boolean getEscapeModelStrings() {
        return getFlag(FLAG_ESCAPE_MODEL_STRINGS);
    }

    /**
     * Gets the id of this component.
     * 
     * @return The id of this component
     */
    @Override
    public String getId() {
        return id;
    }

    /**
     * @return Innermost model for this component
     */
    public final IModel<?> getInnermostModel() {
        return getInnermostModel(getDefaultModel());
    }

    /**
     * Gets the locale for this component. By default, it searches its parents for a locale. If no
     * parents (it's a recursive search) returns a locale, it gets one from the session.
     * 
     * @return The locale to be used for this component
     * @see Session#getLocale()
     */
    public Locale getLocale() {
        if (parent != null) {
            return parent.getLocale();
        }
        return getSession().getLocale();
    }

    /**
     * Convenience method to provide easy access to the localizer object within any component.
     * 
     * @return The localizer object
     */
    public final Localizer getLocalizer() {
        return getApplication().getResourceSettings().getLocalizer();
    }

    /**
     * Get the first component tag in the associated markup
     * 
     * @return first component tag
     */
    private ComponentTag getMarkupTag() {
        IMarkupFragment markup = getMarkup();
        if (markup != null) {
            for (int i = 0; i < markup.size(); i++) {
                MarkupElement elem = markup.get(i);
                if (elem instanceof ComponentTag) {
                    return (ComponentTag) elem;
                }
            }
        }
        return null;
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * 
     * Get a copy of the markup's attributes which are associated with the component.
     * <p>
     * Modifications to the map returned don't change the tags attributes. It is just a copy.
     * <p>
     * Note: The component must have been added (directly or indirectly) to a container with an
     * associated markup file (Page, Panel or Border).
     * 
     * @return markup attributes
     */
    public final ValueMap getMarkupAttributes() {
        ComponentTag tag = getMarkupTag();
        if (tag != null) {
            ValueMap attrs = new ValueMap(tag.getAttributes());
            attrs.makeImmutable();
            return attrs;
        }
        return ValueMap.EMPTY_MAP;
    }

    /**
     * Get the markupId
     * 
     * @return MarkupId
     */
    public final Object getMarkupIdImpl() {
        if (generatedMarkupId != -1) {
            return generatedMarkupId;
        }

        String id = getMetaData(MARKUP_ID_KEY);

        // if still no markup id is found, and the component has been attached to a page, try to
        // retrieve the id from the markup file.
        if (id == null && findPage() != null) {
            id = getMarkupIdFromMarkup();
        }
        return id;
    }

    /**
     * Retrieves id by which this component is represented within the markup. This is either the id
     * attribute set explicitly via a call to {@link #setMarkupId(String)}, id attribute defined in
     * the markup, or an automatically generated id - in that order.
     * <p>
     * If no id is set and <code>createIfDoesNotExist</code> is false, this method will return null.
     * Otherwise it will generate an id value which by default will be unique in the page. This is
     * the preferred way as there is no chance of id collision. This will also enable
     * {@link #setOutputMarkupId(boolean)}.
     * <p>
     * 
     * <p>
     * Note: This method should only be called after the component or its parent have been added to
     * the page.
     * 
     * @param createIfDoesNotExist
     *            When there is no existing markup id, determines whether it should be generated or
     *            whether <code>null</code> should be returned.
     * 
     * @return markup id of the component
     */
    public String getMarkupId(boolean createIfDoesNotExist) {
        IMarkupIdGenerator markupIdGenerator = getApplication().getMarkupSettings().getMarkupIdGenerator();
        String markupId = markupIdGenerator.generateMarkupId(this, createIfDoesNotExist);
        return markupId;
    }

    /**
     * Retrieves id by which this component is represented within the markup. This is either the id
     * attribute set explicitly via a call to {@link #setMarkupId(String)}, id attribute defined in
     * the markup, or an automatically generated id - in that order.
     * <p>
     * If no explicit id is set this function will generate an id value that will be unique in the
     * page. This is the preferred way as there is no chance of id collision. This will also enable
     * {@link #setOutputMarkupId(boolean)}.
     * <p>
     * Note: This method should only be called after the component or its parent have been added to
     * the page.
     * 
     * @return markup id of the component
     */
    public String getMarkupId() {
        return getMarkupId(true);
    }

    /**
     * Gets metadata for this component using the given key.
     * 
     * @param <M>
     *            The type of the metadata.
     * 
     * @param key
     *            The key for the data
     * @return The metadata or null of no metadata was found for the given key
     * @see MetaDataKey
     */
    public final <M extends Serializable> M getMetaData(final MetaDataKey<M> key) {
        return key.get(getMetaData());
    }

    /**
     * Gets the meta data entries for this component as an array of {@link MetaDataEntry} objects.
     *
     * @return the meta data entries for this component
     */
    private MetaDataEntry<?>[] getMetaData() {
        MetaDataEntry<?>[] metaData = null;

        // index where we should expect the entry
        int index = getFlag(FLAG_MODEL_SET) ? 1 : 0;

        int length = data_length();

        if (index < length) {
            Object object = data_get(index);
            if (object instanceof MetaDataEntry<?>[]) {
                metaData = (MetaDataEntry<?>[]) object;
            } else if (object instanceof MetaDataEntry) {
                metaData = new MetaDataEntry[] { (MetaDataEntry<?>) object };
            }
        }

        return metaData;
    }

    /**
     * Gets the model. It returns the object that wraps the backing model.
     * 
     * @return The model
     */
    public final IModel<?> getDefaultModel() {
        IModel<?> model = getModelImpl();
        // If model is null
        if (model == null) {
            // give subclass a chance to lazy-init model
            model = initModel();
            setModelImpl(model);
        }

        return model;
    }

    /**
     * Gets the backing model object. Unlike getDefaultModel().getObject(), this method returns null
     * for a null model.
     * 
     * @return The backing model object
     */
    public final Object getDefaultModelObject() {
        final IModel<?> model = getDefaultModel();
        if (model != null) {
            try {
                // Get model value for this component.
                return model.getObject();
            } catch (Exception ex) {
                // wrap the exception so that it brings info about the component
                WicketRuntimeException rex = new WicketRuntimeException(
                        "An error occurred while getting the model object for Component: " + this.toString(true),
                        ex);
                throw rex;
            }
        }
        return null;
    }

    /**
     * Gets a model object as a string. Depending on the "escape model strings" flag of the
     * component, the string is either HTML escaped or not. "HTML escaped" meaning that only HTML
     * sensitive chars are escaped but not all none-ascii chars. Proper HTML encoding should be used
     * instead. In case you really need a fully escaped model string you may call
     * {@link Strings#escapeMarkup(CharSequence, boolean, boolean)} on the model string returned.
     * 
     * @see Strings#escapeMarkup(CharSequence, boolean, boolean)
     * @see #getEscapeModelStrings()
     * 
     * @return Model object for this component as a string
     */
    public final String getDefaultModelObjectAsString() {
        return getDefaultModelObjectAsString(getDefaultModelObject());
    }

    /**
     * Gets a model object as a string. Depending on the "escape model strings" flag of the
     * component, the string is either HTML escaped or not. "HTML escaped" meaning that only HTML
     * sensitive chars are escaped but not all none-ascii chars. Proper HTML encoding should be used
     * instead. In case you really need a fully escaped model string you may call
     * {@link Strings#escapeMarkup(CharSequence, boolean, boolean)} on the model string returned.
     * 
     * @see Strings#escapeMarkup(CharSequence, boolean, boolean)
     * @see #getEscapeModelStrings()
     * 
     * @param modelObject
     *            Model object to convert to string
     * @return The string
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public final String getDefaultModelObjectAsString(final Object modelObject) {
        if (modelObject != null) {
            // Get converter
            final Class<?> objectClass = modelObject.getClass();

            final IConverter converter = getConverter(objectClass);

            // Model string from property
            final String modelString = converter.convertToString(modelObject, getLocale());

            if (modelString != null) {
                // If we should escape the markup
                if (getFlag(FLAG_ESCAPE_MODEL_STRINGS)) {
                    // Escape HTML sensitive characters only. Not all none-ascii chars
                    return Strings.escapeMarkup(modelString, false, false).toString();
                }
                return modelString;
            }
        }
        return "";
    }

    /**
     * Gets whether or not component will output id attribute into the markup. id attribute will be
     * set to the value returned from {@link Component#getMarkupId()}.
     * 
     * @return whether or not component will output id attribute into the markup
     */
    public final boolean getOutputMarkupId() {
        return getFlag(FLAG_OUTPUT_MARKUP_ID);
    }

    /**
     * Gets whether or not an invisible component will render a placeholder tag.
     * 
     * @return true if a placeholder tag should be rendered
     */
    public final boolean getOutputMarkupPlaceholderTag() {
        return getFlag(FLAG_PLACEHOLDER);
    }

    /**
     * Gets the page holding this component.
     * 
     * @return The page holding this component
     * @throws WicketRuntimeException
     *             Thrown if component is not yet attached to a Page.
     * @see #findPage()
     */
    @Override
    public final Page getPage() {
        // Search for nearest Page
        final Page page = findPage();

        // If no Page was found
        if (page == null) {
            // Give up with a nice exception
            throw new WicketRuntimeException("No Page found for component: " + this.toString(true)
                    + ". You probably forgot to add it to its parent component.");
        }

        return page;
    }

    /**
     * Gets the path to this component relative to its containing page, i.e. without leading page
     * id.
     * 
     * @return The path to this component relative to the page it is in
     */
    @Override
    public final String getPageRelativePath() {
        return Strings.afterFirstPathComponent(getPath(), PATH_SEPARATOR);
    }

    /**
     * Gets any parent container, or null if there is none.
     * 
     * @return Any parent container, or null if there is none
     */
    @Override
    public final MarkupContainer getParent() {
        return parent;
    }

    /**
     * Gets this component's path.
     * 
     * @return Colon separated path to this component in the component hierarchy
     */
    public final String getPath() {
        final PrependingStringBuffer buffer = new PrependingStringBuffer(32);
        for (Component c = this; c != null; c = c.getParent()) {
            if (buffer.length() > 0) {
                buffer.prepend(PATH_SEPARATOR);
            }
            buffer.prepend(c.getId());
        }
        return buffer.toString();
    }

    /**
     * If false the component's tag will be printed as well as its body (which is default). If true
     * only the body will be printed, but not the component's tag.
     * 
     * @return If true, the component tag will not be printed
     */
    public final boolean getRenderBodyOnly() {
        return getFlag(FLAG_RENDER_BODY_ONLY);
    }

    /**
     * @return The request for this component's active request cycle
     */
    public final Request getRequest() {
        RequestCycle requestCycle = getRequestCycle();
        if (requestCycle == null) {
            // Happens often with WicketTester when one forgets to call
            // createRequestCycle()
            throw new WicketRuntimeException("No RequestCycle is currently set!");
        }
        return requestCycle.getRequest();
    }

    /**
     * Gets the active request cycle for this component
     * 
     * @return The request cycle
     */
    public final RequestCycle getRequestCycle() {
        return RequestCycle.get();
    }

    /**
     * @return The response for this component's active request cycle
     */
    public final Response getResponse() {
        return getRequestCycle().getResponse();
    }

    /**
     * Gets the current Session object.
     * 
     * @return The Session that this component is in
     */
    public Session getSession() {
        return Session.get();
    }

    /**
     * @return Size of this Component in bytes. Returns {@code 0} - if the size cannot be calculated for some reason
     */
    public long getSizeInBytes() {
        final MarkupContainer originalParent = parent;
        parent = null;
        long size = 0;
        try {
            size = WicketObjects.sizeof(this);
        } catch (Exception e) {
            log.error("Exception getting size for component " + this, e);
        }
        parent = originalParent;
        return size;
    }

    /**
     * @param key
     *            Key of string resource in property file
     * @return The String
     * @see Localizer
     */
    public final String getString(final String key) {
        return getString(key, null);
    }

    /**
     * @param key
     *            The resource key
     * @param model
     *            The model
     * @return The formatted string
     * @see Localizer
     */
    public final String getString(final String key, final IModel<?> model) {
        return getLocalizer().getString(key, this, model);
    }

    /**
     * @param key
     *            The resource key
     * @param model
     *            The model
     * @param defaultValue
     *            A default value if the string cannot be found
     * @return The formatted string
     * @see Localizer
     */
    public final String getString(final String key, final IModel<?> model, final String defaultValue) {
        return getLocalizer().getString(key, this, model, defaultValue);
    }

    /**
     * A convenience method to access the Sessions's style.
     * 
     * @return The style of this component respectively the style of the Session.
     * 
     * @see org.apache.wicket.Session#getStyle()
     */
    public final String getStyle() {
        Session session = getSession();
        if (session == null) {
            throw new WicketRuntimeException("Wicket Session object not available");
        }
        return session.getStyle();
    }

    /**
     * Gets the variation string of this component that will be used to look up markup for this
     * component. Subclasses can override this method to define by an instance what markup variation
     * should be picked up. By default it will return null or the value of a parent.
     * 
     * @return The variation of this component.
     */
    public String getVariation() {
        if (parent != null) {
            return parent.getVariation();
        }
        return null;
    }

    /**
     * Gets whether this component was rendered at least once.
     * 
     * @return true if the component has been rendered before, false if it is merely constructed
     */
    public final boolean hasBeenRendered() {
        return getFlag(FLAG_HAS_BEEN_RENDERED);
    }

    /**
     * Gets feedback messages for this component. This method will instantiate a
     * {@link FeedbackMessages} instance and add it to the component metadata, even when called on a
     * component that has no feedback messages, to avoid the overhead use
     * {@link #hasFeedbackMessage()}
     * 
     * @return feedback messages instance
     */
    public FeedbackMessages getFeedbackMessages() {
        FeedbackMessages messages = getMetaData(FEEDBACK_KEY);
        if (messages == null) {
            messages = new FeedbackMessages();
            setMetaData(FEEDBACK_KEY, messages);
        }
        return messages;
    }

    /**
     * @return True if this component has an error message
     */
    public final boolean hasErrorMessage() {
        FeedbackMessages messages = getMetaData(FEEDBACK_KEY);
        if (messages == null) {
            return false;
        }
        return messages.hasMessage(FeedbackMessage.ERROR);
    }

    /**
     * @return True if this component has some kind of feedback message
     * 
     */
    public final boolean hasFeedbackMessage() {
        FeedbackMessages messages = getMetaData(FEEDBACK_KEY);
        if (messages == null) {
            return false;
        }
        return messages.size() > 0;
    }

    /**
     * Registers an informational feedback message for this component
     * 
     * @param message
     *            The feedback message
     */
    @Override
    public final void info(final Serializable message) {
        getFeedbackMessages().info(this, message);
        addStateChange();
    }

    /**
     * Registers an success feedback message for this component
     * 
     * @param message
     *            The feedback message
     */
    @Override
    public final void success(final Serializable message) {
        getFeedbackMessages().success(this, message);
        addStateChange();
    }

    /**
     * Authorizes an action for a component.
     * 
     * @param action
     *            The action to authorize
     * @return True if the action is allowed
     * @throws AuthorizationException
     *             Can be thrown by implementation if action is unauthorized
     */
    public final boolean isActionAuthorized(Action action) {
        IAuthorizationStrategy authorizationStrategy = getSession().getAuthorizationStrategy();
        if (authorizationStrategy != null) {
            return authorizationStrategy.isActionAuthorized(this, action);
        }
        return true;
    }

    /**
     * @return true if this component is authorized to be enabled, false otherwise
     */
    public final boolean isEnableAllowed() {
        return isActionAuthorized(ENABLE);
    }

    /**
     * Gets whether this component is enabled. Specific components may decide to implement special
     * behavior that uses this property, like web form components that add a disabled='disabled'
     * attribute when enabled is false.
     * 
     * @return Whether this component is enabled.
     */
    public boolean isEnabled() {
        return getFlag(FLAG_ENABLED);
    }

    /**
     * Checks the security strategy if the {@link Component#RENDER} action is allowed on this
     * component
     * 
     * @return ture if {@link Component#RENDER} action is allowed, false otherwise
     */
    public final boolean isRenderAllowed() {
        return getFlag(FLAG_IS_RENDER_ALLOWED);
    }

    /**
     * Returns if the component is stateless or not. It checks the stateless hint if that is false
     * it returns directly false. If that is still true it checks all its behaviors if they can be
     * stateless.
     * 
     * @return whether the component is stateless.
     */
    public final boolean isStateless() {
        if ((isVisibleInHierarchy() && isEnabledInHierarchy()) == false && canCallListener() == false) {
            // the component is either invisible or disabled and it can't call listeners
            // then pretend the component is stateless
            return true;
        }

        if (!getStatelessHint()) {
            return false;
        }

        for (Behavior behavior : getBehaviors()) {
            if (!behavior.getStatelessHint(this)) {
                return false;
            }
        }
        return true;
    }

    /**
     * @return {@code true} if this component should notify its holding page about changes in its
     *         state. If a {@link Page} is not versioned then it wont track changes in its
     *         components and will use the same {@link Page#getPageId()} during its lifetime
     */
    public boolean isVersioned() {
        // Is the component itself versioned?
        if (!getFlag(FLAG_VERSIONED)) {
            return false;
        } else {
            // If there's a parent and this component is versioned
            if (parent != null) {
                // Check if the parent is unversioned. If any parent
                // (recursively) is unversioned, then this component is too
                if (!parent.isVersioned()) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * Gets whether this component and any children are visible.
     * <p>
     * WARNING: this method can be called multiple times during a request. If you override this
     * method, it is a good idea to keep it cheap in terms of processing. Alternatively, you can
     * call {@link #setVisible(boolean)}.
     * <p>
     * 
     * @return True if component and any children are visible
     */
    public boolean isVisible() {
        return getFlag(FLAG_VISIBLE);
    }

    /**
     * Checks if the component itself and all its parents are visible.
     * 
     * @return true if the component and all its parents are visible.
     */
    public final boolean isVisibleInHierarchy() {
        Component parent = getParent();
        if (parent != null && !parent.isVisibleInHierarchy()) {
            return false;
        } else {
            return determineVisibility();
        }
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * 
     * Sets the RENDERING flag and removes the PREPARED_FOR_RENDER flag on component and it's
     * children.
     * 
     * @param setRenderingFlag
     *            if this is false only the PREPARED_FOR_RENDER flag is removed from component, the
     *            RENDERING flag is not set.
     * 
     * @see #internalPrepareForRender(boolean)
     */
    public final void markRendering(boolean setRenderingFlag) {
        internalMarkRendering(setRenderingFlag);
    }

    /**
     * Called to indicate that the model content for this component has been changed
     */
    public final void modelChanged() {
        // Call user code
        internalOnModelChanged();
        onModelChanged();
    }

    /**
     * Called to indicate that the model content for this component is about to change
     */
    public final void modelChanging() {
        checkHierarchyChange(this);

        // Call user code
        onModelChanging();

        // Tell the page that our model changed
        final Page page = findPage();
        if (page != null) {
            page.componentModelChanging(this);
        }
    }

    /**
     * Redirects browser to an intermediate page such as a sign-in page. The current request's URL
     * is saved for future use by method {@link #continueToOriginalDestination()}; only use this method when
     * you plan to continue to the current URL at some later time; otherwise just set a new response page.
     * 
     * @param page
     *            The sign in page
     *
     * @see #setResponsePage(Class)
     * @see #setResponsePage(IRequestablePage)
     * @see #setResponsePage(Class, PageParameters)
     * @see Component#continueToOriginalDestination()
     */
    public final void redirectToInterceptPage(final Page page) {
        throw new RestartResponseAtInterceptPageException(page);
    }

    /**
     * Removes this component from its parent. It's important to remember that a component that is
     * removed cannot be referenced from the markup still.
     * <p>
     * You must not use this method in your callback to any of the
     * {@link MarkupContainer#visitChildren(IVisitor)} methods. See <a
     * href="https://issues.apache.org/jira/browse/WICKET-3229">WICKET-3329</a>.
     */
    public final void remove() {
        if (parent == null) {
            throw new IllegalStateException("Cannot remove " + this + " from null parent!");
        }
        parent.remove(this);
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * <p>
     * Renders this component as a part of a response - the caller has to
     * make sure that this component is prepared for render.
     * 
     * @see #beforeRender()
     */
    public final void renderPart() {
        Page page = getPage();

        page.startComponentRender(this);

        markRendering(true);

        render();

        page.endComponentRender(this);
    }

    /**
     * Render this component and all its children. Always calls hook {@link #onAfterRender()}
     * regardless of any exception.
     */
    public final void render() {
        if (isAuto()) {
            // auto components are prepared when rendered
            beforeRender();
        }

        // Do the render
        RuntimeException exception = null;
        try {
            setRequestFlag(RFLAG_RENDERING, true);

            internalRender();
        } catch (final RuntimeException ex) {
            // Remember it as the originating exception
            exception = ex;
        } finally {
            try {
                // Cleanup
                afterRender();
            } catch (RuntimeException ex2) {
                // Only remember it if not already another exception happened
                if (exception == null) {
                    exception = ex2;
                }
            }
        }

        // Re-throw if needed
        if (exception != null) {
            throw exception;
        }
    }

    /**
     * Performs a render of this component as part of a Page level render process.
     */
    private void internalRender() {
        // Make sure there is a markup available for the Component
        IMarkupFragment markup = getMarkup();
        if (markup == null) {
            throw new MarkupNotFoundException("Markup not found for Component: " + toString());
        }

        // MarkupStream is an Iterator for the markup
        MarkupStream markupStream = new MarkupStream(markup);

        MarkupElement elem = markup.get(0);
        if (elem instanceof ComponentTag) {
            // Guarantee that the markupStream is set and determineVisibility not yet tested
            // See WICKET-2049
            ((ComponentTag) elem).onBeforeRender(this, markupStream);
        }

        // Determine if component is visible using it's authorization status
        // and the isVisible property.
        if (determineVisibility()) {
            setFlag(FLAG_HAS_BEEN_RENDERED, true);

            // Rendering is beginning
            if (log.isDebugEnabled()) {
                log.debug("Begin render {}", this);
            }

            try {
                notifyBehaviorsComponentBeforeRender();
                onRender();
                notifyBehaviorsComponentRendered();

                // Component has been rendered
                rendered();
            } catch (RuntimeException ex) {
                onException(ex);
            }

            if (log.isDebugEnabled()) {
                log.debug("End render {}", this);
            }
        }
        // elem is null when rendering a page
        else if ((elem != null) && (elem instanceof ComponentTag)) {
            if (getFlag(FLAG_PLACEHOLDER)) {
                renderPlaceholderTag((ComponentTag) elem, getResponse());
            }
        }
    }

    /**
     * Called when a runtime exception is caught during the render process
     * 
     * @param ex
     *            The exception caught.
     */
    private void onException(final RuntimeException ex) {
        // Call each behaviors onException() to allow the
        // behavior to clean up
        for (Behavior behavior : getBehaviors()) {
            if (isBehaviorAccepted(behavior)) {
                try {
                    behavior.onException(this, ex);
                } catch (Exception ex2) {
                    log.error("Error while cleaning up after exception", ex2);
                }
            }
        }

        // Re-throw the exception
        throw ex;
    }

    /**
     * Renders a placeholder tag for the component when it is invisible and
     * {@link #setOutputMarkupPlaceholderTag(boolean)} has been called with <code>true</code>.
     * 
     * @param tag
     *            component tag
     * @param response
     *            response
     */
    protected void renderPlaceholderTag(final ComponentTag tag, final Response response) {
        String name = Strings.isEmpty(tag.getNamespace()) ? tag.getName()
                : tag.getNamespace() + ':' + tag.getName();

        response.write("<");
        response.write(name);
        response.write(" id=\"");
        response.write(getAjaxRegionMarkupId());
        response.write("\" style=\"display:none\" data-wicket-placeholder=\"\"></");
        response.write(name);
        response.write(">");
    }

    /**
     * Returns the id of the markup region that will be updated via ajax. This can be different to
     * the markup id of the component if a {@link IAjaxRegionMarkupIdProvider} behavior has been
     * added.
     * 
     * @return the markup id of the region to be updated via ajax.
     */
    public final String getAjaxRegionMarkupId() {
        String markupId = null;
        for (Behavior behavior : getBehaviors()) {
            if (behavior instanceof IAjaxRegionMarkupIdProvider && behavior.isEnabled(this)) {
                markupId = ((IAjaxRegionMarkupIdProvider) behavior).getAjaxRegionMarkupId(this);
                break;
            }
        }
        if (markupId == null) {
            if (this instanceof IAjaxRegionMarkupIdProvider) {
                markupId = ((IAjaxRegionMarkupIdProvider) this).getAjaxRegionMarkupId(this);
            }
        }
        if (markupId == null) {
            markupId = getMarkupId();
        }
        return markupId;
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * <p>
     * Renders the component at the current position in the given markup stream. The method
     * onComponentTag() is called to allow the component to mutate the start tag. The method
     * onComponentTagBody() is then called to permit the component to render its body.
     */
    protected final void internalRenderComponent() {
        final IMarkupFragment markup = getMarkup();
        if (markup == null) {
            throw new MarkupException("Markup not found. Component: " + toString());
        }

        final MarkupStream markupStream = new MarkupStream(markup);

        // Get mutable copy of next tag
        final ComponentTag openTag = markupStream.getTag();
        final ComponentTag tag = openTag.mutable();

        // call application-wide tag listeners
        getApplication().getOnComponentTagListeners().onComponentTag(this, tag);

        // Call any tag handler
        onComponentTag(tag);

        // If we're an openclose tag
        if (!tag.isOpenClose() && !tag.isOpen()) {
            // We were something other than <tag> or <tag/>
            markupStream.throwMarkupException("Method renderComponent called on bad markup element: " + tag);
        }

        if (tag.isOpenClose() && openTag.isOpen()) {
            markupStream.throwMarkupException("You can not modify a open tag to open-close: " + tag);
        }

        try {
            // Render open tag
            boolean renderBodyOnly = getRenderBodyOnly();
            if (renderBodyOnly) {
                ExceptionSettings.NotRenderableErrorStrategy notRenderableErrorStrategy = ExceptionSettings.NotRenderableErrorStrategy.LOG_WARNING;
                if (Application.exists()) {
                    notRenderableErrorStrategy = getApplication().getExceptionSettings()
                            .getNotRenderableErrorStrategy();
                }

                if (getFlag(FLAG_OUTPUT_MARKUP_ID)) {
                    String message = String.format("Markup id set on a component that renders its body only. "
                            + "Markup id: %s, component id: %s.", getMarkupId(), getId());
                    if (notRenderableErrorStrategy == ExceptionSettings.NotRenderableErrorStrategy.THROW_EXCEPTION) {
                        throw new IllegalStateException(message);
                    }
                    log.warn(message);
                }
                if (getFlag(FLAG_PLACEHOLDER)) {
                    String message = String.format(
                            "Placeholder tag set on a component that renders its body only. " + "Component id: %s.",
                            getId());
                    if (notRenderableErrorStrategy == ExceptionSettings.NotRenderableErrorStrategy.THROW_EXCEPTION) {
                        throw new IllegalStateException(message);
                    }
                    log.warn(message);
                }
            } else {
                renderComponentTag(tag);
            }
            markupStream.next();

            // Render the body only if open-body-close. Do not render if open-close.
            if (tag.isOpen()) {
                // Render the body. The default strategy will simply call the component's
                // onComponentTagBody() implementation.
                getMarkupSourcingStrategy().onComponentTagBody(this, markupStream, tag);

                // Render close tag
                if (openTag.isOpen()) {
                    renderClosingComponentTag(markupStream, tag, renderBodyOnly);
                } else if (renderBodyOnly == false) {
                    if (needToRenderTag(openTag)) {
                        // Close the manually opened tag. And since the user might have changed the
                        // tag name ...
                        getResponse().write(tag.syntheticCloseTagString());
                    }
                }
            }
        } catch (WicketRuntimeException wre) {
            throw wre;
        } catch (RuntimeException re) {
            throw new WicketRuntimeException("Exception in rendering component: " + this, re);
        }
    }

    /**
     * 
     * @param openTag
     * @return true, if the tag shall be rendered
     */
    private boolean needToRenderTag(final ComponentTag openTag) {
        // If a open-close tag has been modified to be open-body-close then a
        // synthetic close tag must be rendered.
        boolean renderTag = (openTag != null && !(openTag instanceof WicketTag));
        if (renderTag == false) {
            renderTag = !getApplication().getMarkupSettings().getStripWicketTags();
        }
        return renderTag;
    }

    /**
     * Called to indicate that a component has been rendered. This method should only very rarely be
     * called at all. Some components may render its children without calling render() on them.
     * These components need to call rendered() to indicate that its child components were actually
     * rendered, the framework would think they had never been rendered, and in development mode
     * this would result in a runtime exception.
     */
    public final void rendered() {
        Page page = findPage();
        if (page != null) {
            // Tell the page that the component rendered
            page.componentRendered(this);
        } else {
            log.error(
                    "Component is not connected to a Page. Cannot register the component as being rendered. Component: "
                            + toString());
        }
    }

    /**
     * Get the markup sourcing strategy for the component. If null,
     * {@link #newMarkupSourcingStrategy()} will be called.
     * 
     * @return Markup sourcing strategy
     */
    protected final IMarkupSourcingStrategy getMarkupSourcingStrategy() {
        if (markupSourcingStrategy == null) {
            markupSourcingStrategy = newMarkupSourcingStrategy();

            // If not strategy by provided, than we use a default one.
            if (markupSourcingStrategy == null) {
                markupSourcingStrategy = DefaultMarkupSourcingStrategy.get();
            }
        }
        return markupSourcingStrategy;
    }

    /**
     * If {@link #getMarkupSourcingStrategy()} returns null, this method will be called. By default
     * it returns null, which means that a default markup strategy will be attached to the
     * component.
     * <p>
     * Please note that markup source strategies are not persisted. Instead they get re-created by
     * calling this method again. That's ok since markup sourcing strategies usually do not maintain
     * a state.
     * 
     * @return Markup sourcing strategy
     */
    protected IMarkupSourcingStrategy newMarkupSourcingStrategy() {
        return null;
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * 
     * Print to the web response what ever the component wants to contribute to the head section.
     * Make sure that all attached behaviors are asked as well.
     * <p>
     * NOT intended for overriding by framework clients. Rather, use
     * {@link Component#renderHead(org.apache.wicket.markup.head.IHeaderResponse)}
     * </p>
     * 
     * @param container
     *            The HtmlHeaderContainer
     */
    public void internalRenderHead(final HtmlHeaderContainer container) {
        if (isVisibleInHierarchy() && isRenderAllowed()) {
            if (log.isDebugEnabled()) {
                log.debug("internalRenderHead: {}", toString(false));
            }

            IHeaderResponse response = container.getHeaderResponse();

            // Allow component to contribute
            if (response.wasRendered(this) == false) {
                StringResponse markupHeaderResponse = new StringResponse();
                Response oldResponse = getResponse();
                RequestCycle.get().setResponse(markupHeaderResponse);
                try {
                    // Make sure the markup source strategy contributes to the header first
                    // to be backward compatible. WICKET-3761
                    getMarkupSourcingStrategy().renderHead(this, container);
                    CharSequence headerContribution = markupHeaderResponse.getBuffer();
                    if (Strings.isEmpty(headerContribution) == false) {
                        response.render(StringHeaderItem.forString(headerContribution));
                    }
                } finally {
                    RequestCycle.get().setResponse(oldResponse);
                }
                // Then let the component itself to contribute to the header
                renderHead(response);

                response.markRendered(this);
            }

            // Then ask all behaviors
            for (Behavior behavior : getBehaviors()) {
                if (isBehaviorAccepted(behavior)) {
                    if (response.wasRendered(behavior) == false) {
                        behavior.renderHead(this, response);
                        List<IClusterable> pair = Arrays.asList(this, behavior);
                        response.markRendered(pair);
                    }
                }
            }
        }
    }

    /**
     * Replaces this component with another. The replacing component must have the same component id
     * as this component. This method serves as a shortcut to
     * 
     * <code>this.getParent().replace(replacement)</code>
     * 
     * and provides a better context for errors.
     * <p>
     * Usage: <code>component = component.replaceWith(replacement);</code>
     * </p>
     * 
     * @since 1.2.1
     * 
     * @param replacement
     *            component to replace this one
     * @return the component which replaced this one
     */
    public Component replaceWith(Component replacement) {
        Args.notNull(replacement, "replacement");

        if (!getId().equals(replacement.getId())) {
            throw new IllegalArgumentException(
                    "Replacement component must have the same id as the component it will replace. Replacement id [["
                            + replacement.getId() + "]], replaced id [[" + getId() + "]].");
        }
        if (parent == null) {
            throw new IllegalStateException(
                    "This method can only be called on a component that has already been added to its parent.");
        }
        parent.replace(replacement);
        return replacement;
    }

    /**
     * @param component
     *            The component to compare with
     * @return True if the given component's model is the same as this component's model.
     */
    public final boolean sameInnermostModel(final Component component) {
        return sameInnermostModel(component.getDefaultModel());
    }

    /**
     * @param model
     *            The model to compare with
     * @return True if the given component's model is the same as this component's model.
     */
    public final boolean sameInnermostModel(final IModel<?> model) {
        // Get the two models
        IModel<?> thisModel = getDefaultModel();

        // If both models are non-null they could be the same
        if (thisModel != null && model != null) {
            return getInnermostModel(thisModel) == getInnermostModel(model);
        }

        return false;
    }

    /**
     * Sets whether this component is enabled. Specific components may decide to implement special
     * behavior that uses this property, like web form components that add a disabled='disabled'
     * attribute when enabled is false. If it is not enabled, it will not be allowed to call any
     * listener method on it (e.g. Link.onClick) and the model object will be protected (for the
     * common use cases, not for programmer's misuse)
     * 
     * @param enabled
     *            whether this component is enabled
     * @return This
     */
    public final Component setEnabled(final boolean enabled) {
        // Is new enabled state a change?
        if (enabled != getFlag(FLAG_ENABLED)) {
            // Tell the page that this component's enabled was changed
            if (isVersioned()) {
                final Page page = findPage();
                if (page != null) {
                    addStateChange();
                }
            }

            // Change visibility
            setFlag(FLAG_ENABLED, enabled);
            onEnabledStateChanged();
        }
        return this;
    }

    void clearEnabledInHierarchyCache() {
        setRequestFlag(RFLAG_ENABLED_IN_HIERARCHY_SET, false);
    }

    void onEnabledStateChanged() {
        clearEnabledInHierarchyCache();
    }

    /**
     * Sets whether model strings should be escaped.
     * 
     * @param escapeMarkup
     *            True is model strings should be escaped
     * @return This
     */
    public final Component setEscapeModelStrings(final boolean escapeMarkup) {
        setFlag(FLAG_ESCAPE_MODEL_STRINGS, escapeMarkup);
        return this;
    }

    /**
     * Set markup ID, which must be String or Integer
     * 
     * @param markupId
     */
    public final void setMarkupIdImpl(Object markupId) {
        if (markupId != null && !(markupId instanceof String) && !(markupId instanceof Integer)) {
            throw new IllegalArgumentException("markupId must be String or Integer");
        }

        setOutputMarkupId(true);
        if (markupId instanceof Integer) {
            generatedMarkupId = (Integer) markupId;
            setMetaData(MARKUP_ID_KEY, null);
            return;
        }

        generatedMarkupId = -1;
        setMetaData(MARKUP_ID_KEY, (String) markupId);

    }

    /**
     * Copy markupId
     * 
     * @param comp
     */
    final void setMarkupId(Component comp) {
        Args.notNull(comp, "comp");

        generatedMarkupId = comp.generatedMarkupId;
        setMetaData(MARKUP_ID_KEY, comp.getMetaData(MARKUP_ID_KEY));
        if (comp.getOutputMarkupId()) {
            setOutputMarkupId(true);
        }
    }

    /**
     * Sets this component's markup id to a user defined value. It is up to the user to ensure this
     * value is unique.
     * <p>
     * The recommended way is to let wicket generate the value automatically, this method is here to
     * serve as an override for that value in cases where a specific id must be used.
     * <p>
     * If null is passed in the user defined value is cleared and markup id value will fall back on
     * automatically generated value
     * 
     * @see #getMarkupId()
     * 
     * @param markupId
     *            markup id value or null to clear any previous user defined value
     * @return this for chaining
     */
    public Component setMarkupId(String markupId) {
        Args.notEmpty(markupId, "markupId");

        // TODO check if an automatic id has already been generated or getmarkupid() called
        // previously and throw an illegalstateexception because something else might be depending
        // on previous id

        setMarkupIdImpl(markupId);
        return this;
    }

    /**
     * Sets the metadata for this component using the given key. If the metadata object is not of
     * the correct type for the metadata key, an IllegalArgumentException will be thrown. For
     * information on creating MetaDataKeys, see {@link MetaDataKey}.
     * 
     * @param <M>
     *            The type of the metadata
     * 
     * @param key
     *            The singleton key for the metadata
     * @param object
     *            The metadata object
     * @throws IllegalArgumentException
     * @see MetaDataKey
     */
    public final <M extends Serializable> Component setMetaData(final MetaDataKey<M> key, final M object) {
        MetaDataEntry<?>[] old = getMetaData();

        Object metaData = null;
        MetaDataEntry<?>[] metaDataArray = key.set(getMetaData(), object);
        if (metaDataArray != null && metaDataArray.length > 0) {
            metaData = (metaDataArray.length > 1) ? metaDataArray : metaDataArray[0];
        }

        int index = getFlag(FLAG_MODEL_SET) ? 1 : 0;

        if (old == null && metaData != null) {
            data_insert(index, metaData);
        } else if (old != null && metaData != null) {
            data_set(index, metaData);
        } else if (old != null && metaData == null) {
            data_remove(index);
        }
        return this;
    }

    /**
     * Sets the given model.
     * <p>
     * WARNING: DO NOT OVERRIDE THIS METHOD UNLESS YOU HAVE A VERY GOOD REASON FOR IT. OVERRIDING
     * THIS MIGHT OPEN UP SECURITY LEAKS AND BREAK BACK-BUTTON SUPPORT.
     * </p>
     * 
     * @param model
     *            The model
     * @return This
     */
    public Component setDefaultModel(final IModel<?> model) {
        IModel<?> prevModel = getModelImpl();

        IModel<?> wrappedModel = prevModel;
        if (prevModel instanceof IWrapModel) {
            wrappedModel = ((IWrapModel<?>) prevModel).getWrappedModel();
        }

        // Change model
        if (wrappedModel != model) {
            // Detach the old/current model
            if (prevModel != null) {
                prevModel.detach();
            }

            modelChanging();
            setModelImpl(wrap(model));
            modelChanged();

            // WICKET-3413 reset 'inherited model' when model is explicitely set
            setFlag(FLAG_INHERITABLE_MODEL, false);
        }

        return this;
    }

    /**
     * @return model
     */
    IModel<?> getModelImpl() {
        if (getFlag(FLAG_MODEL_SET)) {
            return (IModel<?>) data_get(0);
        }
        return null;
    }

    /**
     * 
     * @param model
     */
    void setModelImpl(IModel<?> model) {
        if (getFlag(FLAG_MODEL_SET)) {
            if (model != null) {
                data_set(0, model);
            } else {
                data_remove(0);
                setFlag(FLAG_MODEL_SET, false);
            }
        } else {
            if (model != null) {
                data_insert(0, model);
                setFlag(FLAG_MODEL_SET, true);
            }
        }
    }

    /**
     * Sets the backing model object. Unlike <code>getDefaultModel().setObject(object)</code>, this
     * method checks authorisation and model comparator, and invokes <code>modelChanging</code> and
     * <code>modelChanged</code> if the value really changes.
     * 
     * @param object
     *            The object to set
     * @return This
     * @throws IllegalStateException If the component has neither its own model nor any of its
     * parents uses {@link IComponentInheritedModel}
     */
    @SuppressWarnings("unchecked")
    public final Component setDefaultModelObject(final Object object) {
        final IModel<Object> model = (IModel<Object>) getDefaultModel();

        // Check whether anything can be set at all
        if (model == null) {
            throw new IllegalStateException("Attempt to set a model object on a component without a model! "
                    + "Either pass an IModel to the constructor or use #setDefaultModel(new SomeModel(object)). "
                    + "Component: " + getPageRelativePath());
        }

        // Check authorization
        if (!isActionAuthorized(ENABLE)) {
            throw new UnauthorizedActionException(this, ENABLE);
        }

        // Check whether this will result in an actual change
        if (!getModelComparator().compare(this, object)) {
            modelChanging();
            model.setObject(object);
            modelChanged();
        }

        return this;
    }

    /**
     * Sets whether or not component will output id attribute into the markup. id attribute will be
     * set to the value returned from {@link Component#getMarkupId()}.
     * 
     * @param output
     *            True if the component will output the id attribute into markup. Please note that
     *            the default behavior is to use the same id as the component. This means that your
     *            component must begin with [a-zA-Z] in order to generate a valid markup id
     *            according to: http://www.w3.org/TR/html401/types.html#type-name
     * 
     * @return this for chaining
     */
    public final Component setOutputMarkupId(final boolean output) {
        setFlag(FLAG_OUTPUT_MARKUP_ID, output);
        return this;
    }

    /**
     * Render a placeholder tag when the component is not visible. The tag is of form:
     * &lt;componenttag style="display:none;" id="markupid"/&gt;. This method will also call
     * <code>setOutputMarkupId(true)</code>.
     * 
     * This is useful, for example, in ajax situations where the component starts out invisible and
     * then becomes visible through an ajax update. With a placeholder tag already in the markup you
     * do not need to repaint this component's parent, instead you can repaint the component
     * directly.
     * 
     * When this method is called with parameter <code>false</code> the outputmarkupid flag is not
     * reverted to false.
     * 
     * @param outputTag
     * @return this for chaining
     */
    public final Component setOutputMarkupPlaceholderTag(final boolean outputTag) {
        if (outputTag != getFlag(FLAG_PLACEHOLDER)) {
            if (outputTag) {
                setOutputMarkupId(true);
                setFlag(FLAG_PLACEHOLDER, true);
            } else {
                setFlag(FLAG_PLACEHOLDER, false);
                // I think it's better to not setOutputMarkupId to false...
                // user can do it if she want
            }
        }
        return this;
    }

    /**
     * If false the component's tag will be printed as well as its body (which is default). If true
     * only the body will be printed, but not the component's tag.
     * 
     * @param renderTag
     *            If true, the component tag will not be printed
     * @return This
     */
    public final Component setRenderBodyOnly(final boolean renderTag) {
        setFlag(FLAG_RENDER_BODY_ONLY, renderTag);
        return this;
    }

    /**
     * Sets the page that will respond to this request
     * 
     * @param <C>
     * 
     * @param cls
     *            The response page class
     * @see RequestCycle#setResponsePage(Class)
     */
    public final <C extends IRequestablePage> void setResponsePage(final Class<C> cls) {
        getRequestCycle().setResponsePage(cls, (PageParameters) null);
    }

    /**
     * Sets the page class and its parameters that will respond to this request
     * 
     * @param <C>
     * 
     * @param cls
     *            The response page class
     * @param parameters
     *            The parameters for this bookmarkable page.
     * @see RequestCycle#setResponsePage(Class, PageParameters)
     */
    public final <C extends IRequestablePage> void setResponsePage(final Class<C> cls, PageParameters parameters) {
        getRequestCycle().setResponsePage(cls, parameters);
    }

    /**
     * Sets the page that will respond to this request
     * 
     * @param page
     *            The response page
     * 
     * @see RequestCycle#setResponsePage(org.apache.wicket.request.component.IRequestablePage)
     */
    public final void setResponsePage(final IRequestablePage page) {
        getRequestCycle().setResponsePage(page);
    }

    /**
     * @param versioned
     *            True to turn on versioning for this component, false to turn it off for this
     *            component and any children.
     * @return This
     */
    public Component setVersioned(boolean versioned) {
        setFlag(FLAG_VERSIONED, versioned);
        return this;
    }

    /**
     * Sets whether this component and any children are visible.
     * 
     * @param visible
     *            True if this component and any children should be visible
     * @return This
     */
    public final Component setVisible(final boolean visible) {
        // Is new visibility state a change?
        if (visible != getFlag(FLAG_VISIBLE)) {
            // record component's visibility change
            addStateChange();

            // Change visibility
            setFlag(FLAG_VISIBLE, visible);
            onVisibleStateChanged();
        }
        return this;
    }

    void clearVisibleInHierarchyCache() {
        setRequestFlag(RFLAG_VISIBLE_IN_HIERARCHY_SET, false);
    }

    void onVisibleStateChanged() {
        clearVisibleInHierarchyCache();
    }

    /**
     * Gets the string representation of this component.
     * 
     * @return The path to this component
     */
    @Override
    public String toString() {
        return toString(false);
    }

    /**
     * @param detailed
     *            True if a detailed string is desired
     * @return The string
     */
    public String toString(final boolean detailed) {
        try {
            final StringBuilder buffer = new StringBuilder();
            buffer.append("[Component id = ").append(getId());

            if (detailed) {
                final Page page = findPage();
                if (page == null) {
                    buffer.append(", page = <No Page>, path = ").append(getPath()).append('.')
                            .append(Classes.simpleName(getClass()));
                } else {
                    buffer.append(", page = ").append(Classes.name(getPage().getPageClass())).append(", path = ")
                            .append(getPageRelativePath()).append(", type = ").append(Classes.name(getClass()))
                            .append(", isVisible = ").append((determineVisibility())).append(", isVersioned = ")
                            .append(isVersioned());
                }

                if (markup != null) {
                    buffer.append(", markup = ").append(new MarkupStream(getMarkup()).toString());
                }
            }

            buffer.append(']');

            return buffer.toString();
        } catch (Exception e) {
            log.warn("Error while building toString()", e);
            return String.format(
                    "[Component id = %s <attributes are not available because exception %s was thrown during toString()>]",
                    getId(), e.getClass().getName());
        }
    }

    /**
     * Returns a bookmarkable URL that references a given page class using a given set of page
     * parameters. Since the URL which is returned contains all information necessary to instantiate
     * and render the page, it can be stored in a user's browser as a stable bookmark.
     * 
     * @param <C>
     * 
     * @see RequestCycle#urlFor(Class, org.apache.wicket.request.mapper.parameter.PageParameters)
     * 
     * @param pageClass
     *            Class of page
     * @param parameters
     *            Parameters to page
     * @return Bookmarkable URL to page
     */
    public final <C extends Page> CharSequence urlFor(final Class<C> pageClass, final PageParameters parameters) {
        return getRequestCycle().urlFor(pageClass, parameters);
    }

    /**
     * Gets a URL for the listener interface on a behavior (e.g. {@link IRequestListener} on
     * {@link org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigationBehavior}).
     * 
     * @param behaviour
     *            The behavior that the URL should point to
     * @param parameters
     *            The parameters that should be rendered into the urls
     * @return The URL
     */
    public final CharSequence urlForListener(final Behavior behaviour, final PageParameters parameters) {
        int id = getBehaviorId(behaviour);
        IRequestHandler handler = createRequestHandler(parameters, id);
        return getRequestCycle().urlFor(handler);
    }

    /**
     * Create a suitable request handler depending whether the page is stateless or bookmarkable.
     */
    private IRequestHandler createRequestHandler(PageParameters parameters, Integer id) {
        Page page = getPage();

        PageAndComponentProvider provider = new PageAndComponentProvider(page, this, parameters);

        if (page.isPageStateless() || (page.isBookmarkable() && page.wasCreatedBookmarkable())) {
            return new BookmarkableListenerRequestHandler(provider, id);
        } else {
            return new ListenerRequestHandler(provider, id);
        }
    }

    /**
     * Returns a URL that references the given request target.
     * 
     * @see RequestCycle#urlFor(IRequestHandler)
     * 
     * @param requestHandler
     *            the request target to reference
     * 
     * @return a URL that references the given request target
     */
    public final CharSequence urlFor(final IRequestHandler requestHandler) {
        return getRequestCycle().urlFor(requestHandler);
    }

    /**
     * Gets a URL for this {@link IRequestListener}.
     * 
     * @see RequestCycle#urlFor(IRequestHandler)
     * 
     * @param parameters
     *            The parameters that should be rendered into the URL
     * @return The URL
     */
    public final CharSequence urlForListener(final PageParameters parameters) {
        IRequestHandler handler = createRequestHandler(parameters, null);
        return getRequestCycle().urlFor(handler);
    }

    /**
     * Returns a URL that references a shared resource through the provided resource reference.
     * 
     * @see RequestCycle#urlFor(IRequestHandler)
     * 
     * @param resourceReference
     *            The resource reference
     * @param parameters
     *            parameters or {@code null} if none
     * @return The url for the shared resource
     */
    public final CharSequence urlFor(final ResourceReference resourceReference, PageParameters parameters) {
        return getRequestCycle().urlFor(resourceReference, parameters);
    }

    /**
     * Traverses all parent components of the given class in this parentClass, calling the visitor's
     * visit method at each one.
     * 
     * @param <R>
     *            the type of the result object
     * @param parentClass
     *            Class
     * @param visitor
     *            The visitor to call at each parent of the given type
     * @return First non-null value returned by visitor callback
     */
    public final <R, C extends MarkupContainer> R visitParents(final Class<C> parentClass,
            final IVisitor<C, R> visitor) {
        return visitParents(parentClass, visitor, IVisitFilter.ANY);
    }

    /**
     * Traverses all parent components of the given class in this parentClass, calling the visitor's
     * visit method at each one.
     * 
     * @param <R>
     *            the type of the result object
     * @param parentClass
     *            the class of the parent component
     * @param visitor
     *            The visitor to call at each parent of the given type
     * @param filter
     *            a filter that adds an additional logic to the condition whether a parent container
     *            matches
     * @return First non-null value returned by visitor callback
     */
    @SuppressWarnings("unchecked")
    public final <R, C extends MarkupContainer> R visitParents(final Class<C> parentClass,
            final IVisitor<C, R> visitor, IVisitFilter filter) {
        Args.notNull(filter, "filter");

        // Start here
        MarkupContainer current = getParent();

        Visit<R> visit = new Visit<R>();

        // Walk up containment hierarchy
        while (current != null) {
            // Is current an instance of this class?
            if (parentClass.isInstance(current) && filter.visitObject(current)) {
                visitor.component((C) current, visit);
                if (visit.isStopped()) {
                    return visit.getResult();
                }
            }

            // Check parent
            current = current.getParent();
        }
        return null;
    }

    /**
     * Registers a warning feedback message for this component.
     * 
     * @param message
     *            The feedback message
     */
    @Override
    public final void warn(final Serializable message) {
        getFeedbackMessages().warn(this, message);
        addStateChange();
    }

    /**
     * {@link Behavior#beforeRender(Component)} Notify all behaviors that are assigned to this
     * component that the component is about to be rendered.
     */
    private void notifyBehaviorsComponentBeforeRender() {
        for (Behavior behavior : getBehaviors()) {
            if (isBehaviorAccepted(behavior)) {
                behavior.beforeRender(this);
            }
        }
    }

    /**
     * {@link Behavior#afterRender(Component)} Notify all behaviors that are assigned to this
     * component that the component has rendered.
     */
    private void notifyBehaviorsComponentRendered() {
        // notify the behaviors that component has been rendered
        for (Behavior behavior : getBehaviors()) {
            if (isBehaviorAccepted(behavior)) {
                behavior.afterRender(this);
            }
        }
    }

    /**
     * TODO WICKET-NG rename to something more useful - like componentChanged(), this method used to
     * be called with a Change object
     * 
     * Adds state change to page.
     */
    protected final void addStateChange() {
        checkHierarchyChange(this);
        final Page page = findPage();
        if (page != null) {
            page.componentStateChanging(this);
        }
    }

    /**
     * Checks whether the given type has the expected name.
     * 
     * @param tag
     *            The tag to check
     * @param name
     *            The expected tag name
     * @throws MarkupException
     *             Thrown if the tag is not of the right name
     */
    protected final void checkComponentTag(final ComponentTag tag, final String name) {
        if (!tag.getName().equalsIgnoreCase(name)) {
            String msg = String.format(
                    "Component [%s] (path = [%s]) must be " + "applied to a tag of type [%s], not: %s", getId(),
                    getPath(), name, tag.toUserDebugString());

            findMarkupStream().throwMarkupException(msg);
        }
    }

    /**
     * Checks that a given tag has a required attribute value.
     * 
     * @param tag
     *            The tag
     * @param key
     *            The attribute key
     * @param values
     *            The required value for the attribute key
     * @throws MarkupException
     *             Thrown if the tag does not have the required attribute value
     */
    protected final void checkComponentTagAttribute(final ComponentTag tag, final String key,
            final String... values) {
        if (key != null) {
            final String tagAttributeValue = tag.getAttributes().getString(key);

            boolean found = false;
            if (tagAttributeValue != null) {
                for (String value : values) {
                    if (value.equalsIgnoreCase(tagAttributeValue)) {
                        found = true;
                        break;
                    }
                }
            }

            if (found == false) {
                String msg = String.format(
                        "Component [%s] (path = [%s]) must be applied to a tag "
                                + "with [%s] attribute matching any of %s, not [%s]",
                        getId(), getPath(), key, Arrays.toString(values), tagAttributeValue);

                findMarkupStream().throwMarkupException(msg);
            }
        }
    }

    /**
     * Checks whether the hierarchy may be changed at all, and throws an exception if this is not
     * the case.
     * 
     * @param component
     *            the component which is about to be added or removed
     */
    protected void checkHierarchyChange(final Component component) {
        // Throw exception if modification is attempted during rendering
        if (getRequestFlag(RFLAG_RENDERING) && !component.isAuto()) {
            throw new WicketRuntimeException(
                    "Cannot modify component hierarchy after render phase has started (page version cant change then anymore)");
        }
    }

    /**
     * Detaches the model for this component if it is detachable.
     */
    protected void detachModel() {
        IModel<?> model = getModelImpl();
        if (model != null) {
            model.detach();
        }
        // also detach the wrapped model of a component assigned wrap (not
        // inherited)
        if (model instanceof IWrapModel && !getFlag(FLAG_INHERITABLE_MODEL)) {
            ((IWrapModel<?>) model).getWrappedModel().detach();
        }
    }

    /**
     * Suffixes an exception message with useful information about this. component.
     * 
     * @param message
     *            The message
     * @return The modified message
     */
    protected final String exceptionMessage(final String message) {
        return message + ":\n" + toString();
    }

    /**
     * Finds the markup stream for this component.
     * 
     * @return The markup stream for this component. Since a Component cannot have a markup stream,
     *         we ask this component's parent to search for it.
     */
    protected final MarkupStream findMarkupStream() {
        return new MarkupStream(getMarkup());
    }

    /**
     * If this Component is a Page, returns self. Otherwise, searches for the nearest Page parent in
     * the component hierarchy. If no Page parent can be found, {@code null} is returned.
     * 
     * @return The Page or {@code null} if none can be found
     */
    protected final Page findPage() {
        // Search for page
        return (Page) (this instanceof Page ? this : findParent(Page.class));
    }

    /**
     * Gets the subset of the currently coupled {@link Behavior}s that are of the provided type as
     * an unmodifiable list. Returns an empty list if there are no behaviors coupled to this
     * component.
     * 
     * @param type
     *            The type or null for all
     * @return The subset of the currently coupled behaviors that are of the provided type as an
     *         unmodifiable list
     * @param <M>
     *            A class derived from Behavior
     */
    public <M extends Behavior> List<M> getBehaviors(Class<M> type) {
        return new Behaviors(this).getBehaviors(type);
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * 
     * @param flag
     *            The flag to test
     * @return True if the flag is set
     */
    protected final boolean getFlag(final int flag) {
        return (flags & flag) != 0;
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * 
     * @param flag
     *            The flag to test
     * @return True if the flag is set
     */
    protected final boolean getRequestFlag(final short flag) {
        return (requestFlags & flag) != 0;
    }

    /**
     * Finds the innermost IModel object for an IModel that might contain nested IModel(s).
     * 
     * @param model
     *            The model
     * @return The innermost (most nested) model
     */
    protected final IModel<?> getInnermostModel(final IModel<?> model) {
        IModel<?> nested = model;
        while (nested != null && nested instanceof IWrapModel) {
            final IModel<?> next = ((IWrapModel<?>) nested).getWrappedModel();
            if (nested == next) {
                throw new WicketRuntimeException("Model for " + nested + " is self-referential");
            }
            nested = next;
        }
        return nested;
    }

    /**
     * Gets the component's current model comparator. Implementations can be used for testing the
     * current value of the components model data with the new value that is given.
     * 
     * @return the value defaultModelComparator
     */
    public IModelComparator getModelComparator() {
        return defaultModelComparator;
    }

    /**
     * Returns whether the component can be stateless. Also the component behaviors must be
     * stateless, otherwise the component will be treat as stateful. In order for page to be
     * stateless (and not to be stored in session), all components (and component behaviors) must be
     * stateless.
     * 
     * @return whether the component can be stateless
     */
    protected boolean getStatelessHint() {
        return true;
    }

    /**
     * Called when a null model is about to be retrieved in order to allow a subclass to provide an
     * initial model.
     * <p>
     * By default this implementation looks components in the parent chain owning a
     * {@link IComponentInheritedModel} to provide a model for this component via
     * {@link IComponentInheritedModel#wrapOnInheritance(Component)}.
     * <p>
     * For example a {@link FormComponent} has the opportunity to instantiate a model on the fly
     * using its {@code id} and the containing {@link Form}'s model, if the form holds a
     * {@link CompoundPropertyModel}.
     * 
     * @return The model
     */
    protected IModel<?> initModel() {
        IModel<?> foundModel = null;
        // Search parents for IComponentInheritedModel (i.e. CompoundPropertyModel)
        for (Component current = getParent(); current != null; current = current.getParent()) {
            // Get model
            // Don't call the getModel() that could initialize many in between
            // completely useless models.
            // IModel model = current.getDefaultModel();
            IModel<?> model = current.getModelImpl();

            if (model instanceof IWrapModel && !(model instanceof IComponentInheritedModel)) {
                model = ((IWrapModel<?>) model).getWrappedModel();
            }

            if (model instanceof IComponentInheritedModel) {
                // return the shared inherited
                foundModel = ((IComponentInheritedModel<?>) model).wrapOnInheritance(this);
                setFlag(FLAG_INHERITABLE_MODEL, true);
                break;
            }
        }

        // No model for this component!
        return foundModel;
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL OR OVERRIDE.
     * 
     * <p>
     * Called anytime a model is changed via setModel or setModelObject.
     * </p>
     */
    protected void internalOnModelChanged() {
    }

    /**
     * Components are allowed to reject behavior modifiers.
     * 
     * @param behavior
     * @return False, if the component should not apply this behavior
     */
    protected boolean isBehaviorAccepted(final Behavior behavior) {
        // Ignore AttributeModifiers when FLAG_IGNORE_ATTRIBUTE_MODIFIER is set
        if ((behavior instanceof AttributeModifier) && (getFlag(FLAG_IGNORE_ATTRIBUTE_MODIFIER) != false)) {
            return false;
        }

        return behavior.isEnabled(this);
    }

    /**
     * If true, all attribute modifiers will be ignored
     * 
     * @return True, if attribute modifiers are to be ignored
     */
    protected final boolean isIgnoreAttributeModifier() {
        return getFlag(FLAG_IGNORE_ATTRIBUTE_MODIFIER);
    }

    /**
     * Called immediately after a component and all its children have been rendered,
     * regardless of any exception.
     */
    protected void onAfterRender() {
        setRequestFlag(RFLAG_AFTER_RENDER_SUPER_CALL_VERIFIED, true);
    }

    /**
     * Called on all visible components before any component is rendered.
     * <p>
     * <strong>NOTE</strong>: If you override this, you *must* call super.onBeforeRender() within
     * your implementation.
     * 
     * Because this method is responsible for cascading {@link #onBeforeRender()} call to its
     * children it is strongly recommended that super call is made at the end of the override.
     * </p>
     *
     * Changes to the component tree can be made only <strong>before</strong> calling
     * super.onBeforeRender().
     *
     * @see org.apache.wicket.MarkupContainer#addOrReplace(Component...) 
     */
    protected void onBeforeRender() {
        setRequestFlag(RFLAG_PREPARED_FOR_RENDER, true);
        onBeforeRenderChildren();
        setRequestFlag(RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED, true);
    }

    /**
     * Processes the component tag.
     * 
     * Overrides of this method most likely should call the super implementation.
     * 
     * @param tag
     *            Tag to modify
     */
    protected void onComponentTag(final ComponentTag tag) {
        // We can't try to get the ID from markup. This could be different than
        // id returned from getMarkupId() prior first rendering the component
        // (due to transparent resolvers and borders which break the 1:1
        // component <-> markup relation)
        if (getFlag(FLAG_OUTPUT_MARKUP_ID)) {
            tag.putInternal(MARKUP_ID_ATTR_NAME, getMarkupId());
        }

        DebugSettings debugSettings = getApplication().getDebugSettings();
        String componentPathAttributeName = debugSettings.getComponentPathAttributeName();
        if (Strings.isEmpty(componentPathAttributeName) == false) {
            String path = getPageRelativePath();
            path = path.replace("_", "__");
            path = path.replace(':', '_');
            tag.put(componentPathAttributeName, path);
        }

        // The markup sourcing strategy may also want to work on the tag
        getMarkupSourcingStrategy().onComponentTag(this, tag);
    }

    /**
     * Processes the body.
     * 
     * @param markupStream
     *            The markup stream
     * @param openTag
     *            The open tag for the body
     */
    public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {
    }

    /**
     * Called to allow a component to detach resources after use.
     * 
     * Overrides of this method MUST call the super implementation, the most logical place to do
     * this is the last line of the override method.
     */
    protected void onDetach() {
        setRequestFlag(RFLAG_DETACHING, false);
    }

    /**
     * Called to notify the component it is being removed from the component hierarchy
     * 
     * Overrides of this method MUST call the super implementation, the most logical place to do
     * this is the last line of the override method.
     */
    protected void onRemove() {
        setRequestFlag(RFLAG_REMOVING_FROM_HIERARCHY, false);
    }

    /**
     * Called anytime a model is changed after the change has occurred
     */
    protected void onModelChanged() {
    }

    /**
     * Called anytime a model is changed, but before the change actually occurs
     */
    protected void onModelChanging() {
    }

    /**
     * Implementation that renders this component.
     */
    protected abstract void onRender();

    /**
     * Writes a simple tag out to the response stream. Any components that might be referenced by
     * the tag are ignored. Also undertakes any tag attribute modifications if they have been added
     * to the component.
     * 
     * @param tag
     *            The tag to write
     */
    protected final void renderComponentTag(ComponentTag tag) {
        if (needToRenderTag(tag)) {
            // apply behaviors that are attached to the component tag.
            if (tag.hasBehaviors()) {
                Iterator<? extends Behavior> tagBehaviors = tag.getBehaviors();
                while (tagBehaviors.hasNext()) {
                    final Behavior behavior = tagBehaviors.next();
                    if (behavior.isEnabled(this)) {
                        behavior.onComponentTag(this, tag);
                    }
                    behavior.detach(this);
                }
            }

            // Apply behavior modifiers
            List<? extends Behavior> behaviors = getBehaviors();
            if ((behaviors != null) && !behaviors.isEmpty() && !tag.isClose()
                    && (isIgnoreAttributeModifier() == false)) {
                tag = tag.mutable();
                for (Behavior behavior : behaviors) {
                    // Components may reject some behavior components
                    if (isBehaviorAccepted(behavior)) {
                        behavior.onComponentTag(this, tag);
                    }
                }
            }

            if ((tag instanceof WicketTag) && !tag.isClose() && !getFlag(FLAG_IGNORE_ATTRIBUTE_MODIFIER)) {
                ExceptionSettings.NotRenderableErrorStrategy notRenderableErrorStrategy = ExceptionSettings.NotRenderableErrorStrategy.LOG_WARNING;
                if (Application.exists()) {
                    notRenderableErrorStrategy = getApplication().getExceptionSettings()
                            .getNotRenderableErrorStrategy();
                }

                String tagName = tag.getNamespace() + ":" + tag.getName();
                String componentId = getId();
                if (getFlag(FLAG_OUTPUT_MARKUP_ID)) {
                    String message = String.format(
                            "Markup id set on a component that is usually not rendered into markup. "
                                    + "Markup id: %s, component id: %s, component tag: %s.",
                            getMarkupId(), componentId, tagName);
                    if (notRenderableErrorStrategy == ExceptionSettings.NotRenderableErrorStrategy.THROW_EXCEPTION) {
                        throw new IllegalStateException(message);
                    }
                    log.warn(message);
                }
                if (getFlag(FLAG_PLACEHOLDER)) {
                    String message = String
                            .format("Placeholder tag set on a component that is usually not rendered into markup. "
                                    + "Component id: %s, component tag: %s.", componentId, tagName);
                    if (notRenderableErrorStrategy == ExceptionSettings.NotRenderableErrorStrategy.THROW_EXCEPTION) {
                        throw new IllegalStateException(message);
                    }
                    log.warn(message);
                }
            }

            // Write the tag
            tag.writeOutput(getResponse(), !needToRenderTag(null),
                    getMarkup().getMarkupResourceStream().getWicketNamespace());
        }
    }

    /**
     * Replaces the body with the given one.
     * 
     * @param markupStream
     *            The markup stream to replace the tag body in
     * @param tag
     *            The tag
     * @param body
     *            The new markup
     */
    protected final void replaceComponentTagBody(final MarkupStream markupStream, final ComponentTag tag,
            final CharSequence body) {
        // The tag might have been changed from open-close to open. Hence
        // we'll need what was in the markup itself
        ComponentTag markupOpenTag = null;

        // If tag has a body
        if (tag.isOpen()) {
            // Get what tag was in the markup; not what the user it might
            // have changed it to.
            markupOpenTag = markupStream.getPreviousTag();

            // If it was an open tag in the markup as well, than ...
            if (markupOpenTag.isOpen()) {
                // skip any raw markup in the body
                markupStream.skipRawMarkup();
            }
        }

        if (body != null) {
            // Write the new body
            getResponse().write(body);
        }

        // If we had an open tag (and not an openclose tag) and we found a
        // close tag, we're good
        if (tag.isOpen()) {
            // If it was an open tag in the markup, than there must be
            // a close tag as well.
            if ((markupOpenTag != null) && markupOpenTag.isOpen() && !markupStream.atCloseTag()) {
                // There must be a component in this discarded body
                markupStream.throwMarkupException(
                        "Expected close tag for '" + markupOpenTag + "' Possible attempt to embed component(s) '"
                                + markupStream.get() + "' in the body of this component which discards its body");
            }
        }
    }

    /**
     * @param auto
     *            True to put component into auto-add mode
     */
    protected final Component setAuto(final boolean auto) {
        setFlag(FLAG_AUTO, auto);
        return this;
    }

    /**
     * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
     * 
     * @param flag
     *            The flag to set
     * @param set
     *            True to turn the flag on, false to turn it off
     */
    protected final Component setFlag(final int flag, final boolean set) {
        if (set) {
            flags |= flag;
        } else {
            flags &= ~flag;
        }
        return this;
    }

    /**
     * @param flag
     *            The flag to set
     * @param set
     *            True to turn the flag on, false to turn it off
     */
    final Component setRequestFlag(final short flag, final boolean set) {
        if (set) {
            requestFlags |= flag;
        } else {
            requestFlags &= ~flag;
        }
        return this;
    }

    /**
     * If true, all attribute modifiers will be ignored
     * 
     * @param ignore
     *            If true, all attribute modifiers will be ignored
     * @return This
     */
    protected final Component setIgnoreAttributeModifier(final boolean ignore) {
        setFlag(FLAG_IGNORE_ATTRIBUTE_MODIFIER, ignore);
        return this;
    }

    /**
     * @param <V>
     *            The model type
     * @param model
     *            The model to wrap if need be
     * @return The wrapped model
     */
    protected final <V> IModel<V> wrap(final IModel<V> model) {
        if (model instanceof IComponentAssignedModel) {
            return ((IComponentAssignedModel<V>) model).wrapOnAssignment(this);
        }
        return model;
    }

    /**
     * Detaches any child components
     */
    void detachChildren() {
    }

    /**
     * Signals this components removal from hierarchy to all its children.
     */
    void removeChildren() {
    }

    /**
     * Gets the component at the given path.
     * 
     * @param path
     *            Path to component
     * @return The component at the path
     */
    @Override
    public Component get(final String path) {
        // Path to this component is an empty path
        if (path.length() == 0) {
            return this;
        }
        throw new IllegalArgumentException(
                exceptionMessage("Component is not a container and so does not contain the path " + path));
    }

    /**
     * @param setRenderingFlag
     *            rendering flag
     */
    void internalMarkRendering(boolean setRenderingFlag) {
        // WICKET-5460 no longer prepared for render
        setRequestFlag(RFLAG_PREPARED_FOR_RENDER, false);

        setRequestFlag(RFLAG_RENDERING, setRenderingFlag);
    }

    /**
     * @return True if this component or any of its parents is in auto-add mode
     */
    public final boolean isAuto() {
        // Search up hierarchy for FLAG_AUTO
        for (Component current = this; current != null; current = current.getParent()) {
            if (current.getFlag(FLAG_AUTO)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 
     * @return <code>true</code> if component has been prepared for render
     */
    boolean isPreparedForRender() {
        return getRequestFlag(RFLAG_PREPARED_FOR_RENDER);
    }

    /**
     * This method is here for {@link MarkupContainer}. It is broken out of
     * {@link #onBeforeRender()} so we can guarantee that it executes as the last in
     * onBeforeRender() chain no matter where user places the <code>super.onBeforeRender()</code>
     * call.
     */
    void onBeforeRenderChildren() {
    }

    /**
     * Renders the close tag at the current position in the markup stream.
     * 
     * @param markupStream
     *            the markup stream
     * @param openTag
     *            the tag to render
     * @param renderBodyOnly
     *            if true, the tag will not be written to the output
     */
    final void renderClosingComponentTag(final MarkupStream markupStream, final ComponentTag openTag,
            final boolean renderBodyOnly) {
        // Tag should be open tag and not openclose tag
        if (openTag.isOpen()) {
            // If we found a close tag and it closes the open tag, we're good
            if (markupStream.atCloseTag() && markupStream.getTag().closes(openTag)) {
                // Render the close tag
                if ((renderBodyOnly == false) && needToRenderTag(openTag)) {
                    getResponse().write(openTag.syntheticCloseTagString());
                }
            } else if (openTag.requiresCloseTag()) {
                // Missing close tag. Some tags, e.g. <p> are handled like <p/> by most browsers and
                // thus will not throw an exception.
                markupStream.throwMarkupException("Expected close tag for " + openTag);
            }
        }
    }

    /**
     * Sets the id of this component.
     * 
     * @param id
     *            The non-null id of this component
     */
    private void checkId(final String id) {
        if (!(this instanceof Page)) {
            if (Strings.isEmpty(id)) {
                throw new WicketRuntimeException("Null or empty component ID's are not allowed.");
            }
        }

        if ((id != null) && (id.indexOf(':') != -1 || id.indexOf('~') != -1)) {
            throw new WicketRuntimeException("The component ID must not contain ':' or '~' chars.");
        }
    }

    /**
     * THIS IS A WICKET INTERNAL API. DO NOT USE IT.
     * 
     * Sets the parent of a component. Typically what you really want is parent.add(child).
     * <p/>
     * Note that calling setParent() and not parent.add() will connect the child to the parent, but
     * the parent will not know the child. This might not be a problem in some cases, but e.g.
     * child.onDetach() will not be invoked (since the parent doesn't know it is his child).
     * 
     * @param parent
     *            The parent container
     */
    public final void setParent(final MarkupContainer parent) {
        if (this.parent != null && log.isDebugEnabled()) {
            log.debug("Replacing parent " + this.parent + " with " + parent);
        }
        this.parent = parent;
    }

    /**
     * Sets the render allowed flag.
     * 
     * @param renderAllowed
     */
    final void setRenderAllowed(boolean renderAllowed) {
        setFlag(FLAG_IS_RENDER_ALLOWED, renderAllowed);
    }

    /**
     * Sets the render allowed flag.
     * 
     * Visit all this page's children (overridden in MarkupContainer) to check rendering
     * authorization, as appropriate. We set any result; positive or negative as a temporary boolean
     * in the components, and when a authorization exception is thrown it will block the rendering
     * of this page
     */
    void setRenderAllowed() {
        setRenderAllowed(isActionAuthorized(RENDER));
    }

    /**
     * Sets whether or not this component is allowed to be visible. This method is meant to be used
     * by components to control visibility of other components. A call to
     * {@link #setVisible(boolean)} will not always have a desired effect because that component may
     * have {@link #isVisible()} overridden. Both {@link #setVisibilityAllowed(boolean)} and
     * {@link #isVisibilityAllowed()} are <code>final</code> so their contract is enforced always.
     * 
     * @param allowed
     * @return <code>this</code> for chaining
     */
    public final Component setVisibilityAllowed(boolean allowed) {
        setFlag(FLAG_VISIBILITY_ALLOWED, allowed);
        return this;
    }

    /**
     * Gets whether or not visibility is allowed on this component. See
     * {@link #setVisibilityAllowed(boolean)} for details.
     * 
     * @return true if this component is allowed to be visible, false otherwise.
     */
    public final boolean isVisibilityAllowed() {
        return getFlag(FLAG_VISIBILITY_ALLOWED);
    }

    /**
     * Determines whether or not a component should be visible, taking into account all the factors:
     * {@link #isVisible()}, {@link #isVisibilityAllowed()}, {@link #isRenderAllowed()}
     * 
     * @return <code>true</code> if the component should be visible, <code>false</code> otherwise
     */
    public final boolean determineVisibility() {
        return isVisible() && isRenderAllowed() && isVisibilityAllowed();
    }

    /**
     * Calculates enabled state of the component taking its hierarchy into account. A component is
     * enabled iff it is itself enabled ({@link #isEnabled()} and {@link #isEnableAllowed()} both
     * return <code>true</code>), and all of its parents are enabled.
     * 
     * @return <code>true</code> if this component is enabled</code>
     */
    public boolean isEnabledInHierarchy() {
        if (getRequestFlag(RFLAG_ENABLED_IN_HIERARCHY_SET)) {
            return getRequestFlag(RFLAG_ENABLED_IN_HIERARCHY_VALUE);
        }

        final boolean state;
        Component parent = getParent();
        if (parent != null && !parent.isEnabledInHierarchy()) {
            state = false;
        } else {
            state = isEnabled() && isEnableAllowed();
        }

        setRequestFlag(RFLAG_ENABLED_IN_HIERARCHY_SET, true);
        setRequestFlag(RFLAG_ENABLED_IN_HIERARCHY_VALUE, state);
        return state;
    }

    /**
     * Says if the component is rendering currently.
     * 
     * @return true if this component is rendering, false otherwise.
     */
    public final boolean isRendering() {
        return getRequestFlag(RFLAG_PREPARED_FOR_RENDER) || getRequestFlag(RFLAG_RENDERING);
    }

    /**
     * Checks whether or not an {@link IRequestListener} can be invoked on this component. Usually components
     * deny these invocations if they are either invisible or disabled in hierarchy.
     * <p>
     * WARNING: be careful when overriding this method because it may open security holes - such as
     * allowing a user to click on a link that should be disabled.
     * </p>
     * <p>
     * Example usecase for overriding: Suppose you are building an component that displays images.
     * The component generates a callback to itself using {@link IRequestListener} interface and
     * uses this callback to stream image data. If such a component is placed inside a disabled
     * {@code WebMarkupContainer} we still want to allow the invocation of the request listener callback
     * method so that image data can be streamed. Such a component would override this method and
     * return {@literal true}.
     * </p>
     * 
     * @return {@literal true} iff the listener method can be invoked on this component
     */
    public boolean canCallListener() {
        return isEnabledInHierarchy() && isVisibleInHierarchy();
    }

    /**
     * Render to the web response whatever the component wants to contribute to the head section.
     * 
     * @param response
     *            Response object
     */
    @Override
    public void renderHead(IHeaderResponse response) {
        // noop
    }

    /** {@inheritDoc} */
    @Override
    public void onEvent(IEvent<?> event) {
    }

    /** {@inheritDoc} */
    @Override
    public final <T> void send(IEventSink sink, Broadcast type, T payload) {
        new ComponentEventSender(this, getApplication().getFrameworkSettings()).send(sink, type, payload);
    }

    /**
     * Removes behavior from component
     * 
     * @param behaviors
     *            behaviors to remove
     * 
     * @return this (to allow method call chaining)
     */
    public Component remove(final Behavior... behaviors) {
        Behaviors helper = new Behaviors(this);
        for (Behavior behavior : behaviors) {
            helper.remove(behavior);
        }
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public final Behavior getBehaviorById(int id) {
        return new Behaviors(this).getBehaviorById(id);
    }

    /** {@inheritDoc} */
    @Override
    public final int getBehaviorId(Behavior behavior) {
        return new Behaviors(this).getBehaviorId(behavior);
    }

    /**
     * Adds a behavior modifier to the component.
     * 
     * @param behaviors
     *            The behavior modifier(s) to be added
     * @return this (to allow method call chaining)
     */
    public Component add(final Behavior... behaviors) {
        new Behaviors(this).add(behaviors);
        return this;
    }

    /**
     * Gets the currently coupled {@link Behavior}s as a unmodifiable list. Returns an empty list
     * rather than null if there are no behaviors coupled to this component.
     * 
     * @return The currently coupled behaviors as a unmodifiable list
     */
    public final List<? extends Behavior> getBehaviors() {
        return getBehaviors(null);
    }

    @Override
    public boolean canCallListenerAfterExpiry() {
        return getApplication().getPageSettings().getCallListenerAfterExpiry() || isStateless();
    }

    /**
     * This method is called whenever a component is re-added to the page's component tree, if it
     * had been removed at some earlier time, i.e., if it is already initialized
     * (see {@link org.apache.wicket.Component#isInitialized()}).
     *
     * This is similar to onInitialize, but only comes after the component has been removed and
     * then added again:
     *
     * <ul>
     * <li>onInitialize is only called the very first time a component is added</li>
     * <li>onReAdd is not called the first time, but every time it is re-added after having been
     * removed</li>
     * </ul>
     *
     * You can think of it as the opposite of onRemove. A component that was once removed will
     * not be re-initialized but only re-added.
     *
     * Subclasses that override this must call super.onReAdd().
     */
    protected void onReAdd() {
        setRequestFlag(RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED, true);
    }
}