/*******************************************************************************
 * 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.ofbiz.widget.model;

import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TimeZone;

import org.codehaus.groovy.control.CompilationFailedException;
import org.apache.ofbiz.base.conversion.ConversionException;
import org.apache.ofbiz.base.conversion.DateTimeConverters;
import org.apache.ofbiz.base.conversion.DateTimeConverters.StringToTimestamp;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.GroovyUtil;
import org.apache.ofbiz.base.util.ObjectType;
import org.apache.ofbiz.base.util.StringUtil;
import org.apache.ofbiz.base.util.UtilCodec;
import org.apache.ofbiz.base.util.UtilDateTime;
import org.apache.ofbiz.base.util.UtilFormatOut;
import org.apache.ofbiz.base.util.UtilGenerics;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.base.util.collections.FlexibleMapAccessor;
import org.apache.ofbiz.base.util.collections.MapStack;
import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntity;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.condition.EntityCondition;
import org.apache.ofbiz.entity.finder.EntityFinderUtil;
import org.apache.ofbiz.entity.model.ModelEntity;
import org.apache.ofbiz.entity.model.ModelUtil;
import org.apache.ofbiz.entity.util.EntityUtil;
import org.apache.ofbiz.widget.WidgetWorker;
import org.apache.ofbiz.widget.model.CommonWidgetModels.AutoEntityParameters;
import org.apache.ofbiz.widget.model.CommonWidgetModels.AutoServiceParameters;
import org.apache.ofbiz.widget.model.CommonWidgetModels.Image;
import org.apache.ofbiz.widget.model.CommonWidgetModels.Link;
import org.apache.ofbiz.widget.model.CommonWidgetModels.Parameter;
import org.apache.ofbiz.widget.model.ModelForm.UpdateArea;
import org.apache.ofbiz.widget.renderer.FormRenderer;
import org.apache.ofbiz.widget.renderer.FormStringRenderer;
import org.apache.ofbiz.widget.renderer.MenuStringRenderer;
import org.apache.ofbiz.widget.renderer.ScreenRenderer;
import org.w3c.dom.Element;

/**
 * Models the &lt;field&gt; element.
 * 
 * @see <code>widget-form.xsd</code>
 */
public class ModelFormField {

    /*
     * ----------------------------------------------------------------------- *
     *                     DEVELOPERS PLEASE READ
     * ----------------------------------------------------------------------- *
     * 
     * This model is intended to be a read-only data structure that represents
     * an XML element. Outside of object construction, the class should not
     * have any behaviors. All behavior should be contained in model visitors.
     * 
     * Instances of this class will be shared by multiple threads - therefore
     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
     * 
     */

    public static final String module = ModelFormField.class.getName();

    public static ModelFormField from(ModelFormFieldBuilder builder) {
        return new ModelFormField(builder);
    }

    private final FlexibleStringExpander action;
    private final String attributeName;
    private final boolean encodeOutput;
    private final String entityName;
    private final FlexibleMapAccessor<Object> entryAcsr;
    private final String event;
    private final FieldInfo fieldInfo;
    private final String fieldName;
    private final String headerLink;
    private final String headerLinkStyle;
    private final String idName;
    private final FlexibleMapAccessor<Map<String, ? extends Object>> mapAcsr;
    private final ModelForm modelForm;
    private final String name;
    private final List<UpdateArea> onChangeUpdateAreas;
    private final List<UpdateArea> onClickUpdateAreas;
    private final String parameterName;
    private final Integer position;
    private final String redWhen;
    private final Boolean requiredField;
    private final String requiredFieldStyle;
    private final boolean separateColumn;
    private final String serviceName;
    private final Boolean sortField;
    private final String sortFieldAscStyle;
    private final String sortFieldDescStyle;
    private final String sortFieldHelpText;
    private final String sortFieldStyle;
    private final FlexibleStringExpander title;
    private final String titleAreaStyle;
    private final String titleStyle;
    private final FlexibleStringExpander tooltip;
    private final String tooltipStyle;
    private final FlexibleStringExpander useWhen;
    private final FlexibleStringExpander ignoreWhen;
    private final String widgetAreaStyle;
    private final String widgetStyle;
    private final String parentFormName;
    private final String tabindex;

    private ModelFormField(ModelFormFieldBuilder builder) {
        this.action = builder.getAction();
        this.attributeName = builder.getAttributeName();
        this.encodeOutput = builder.getEncodeOutput();
        this.entityName = builder.getEntityName();
        this.entryAcsr = builder.getEntryAcsr();
        this.event = builder.getEvent();
        if (builder.getFieldInfo() != null) {
            this.fieldInfo = builder.getFieldInfo().copy(this);
        } else {
            this.fieldInfo = null;
        }
        this.fieldName = builder.getFieldName();
        this.headerLink = builder.getHeaderLink();
        this.headerLinkStyle = builder.getHeaderLinkStyle();
        this.idName = builder.getIdName();
        this.mapAcsr = builder.getMapAcsr();
        this.modelForm = builder.getModelForm();
        this.name = builder.getName();
        if (builder.getOnChangeUpdateAreas().isEmpty()) {
            this.onChangeUpdateAreas = Collections.emptyList();
        } else {
            this.onChangeUpdateAreas = Collections.unmodifiableList(new ArrayList<UpdateArea>(builder.getOnChangeUpdateAreas()));
        }
        if (builder.getOnClickUpdateAreas().isEmpty()) {
            this.onClickUpdateAreas = Collections.emptyList();
        } else {
            this.onClickUpdateAreas = Collections.unmodifiableList(new ArrayList<UpdateArea>(builder.getOnClickUpdateAreas()));
        }
        this.parameterName = builder.getParameterName();
        this.position = builder.getPosition();
        this.redWhen = builder.getRedWhen();
        this.requiredField = builder.getRequiredField();
        this.requiredFieldStyle = builder.getRequiredFieldStyle();
        this.separateColumn = builder.getSeparateColumn();
        this.serviceName = builder.getServiceName();
        this.sortField = builder.getSortField();
        this.sortFieldAscStyle = builder.getSortFieldAscStyle();
        this.sortFieldDescStyle = builder.getSortFieldDescStyle();
        this.sortFieldHelpText = builder.getSortFieldHelpText();
        this.sortFieldStyle = builder.getSortFieldStyle();
        this.title = builder.getTitle();
        this.titleAreaStyle = builder.getTitleAreaStyle();
        this.titleStyle = builder.getTitleStyle();
        this.tooltip = builder.getTooltip();
        this.tooltipStyle = builder.getTooltipStyle();
        this.useWhen = builder.getUseWhen();
        this.ignoreWhen = builder.getIgnoreWhen();
        this.widgetAreaStyle = builder.getWidgetAreaStyle();
        this.widgetStyle = builder.getWidgetStyle();
        this.parentFormName = builder.getParentFormName();
        this.tabindex = builder.getTabindex();
    }

    public FlexibleStringExpander getAction() {
        return action;
    }

    public String getAction(Map<String, ? extends Object> context) {
        if (UtilValidate.isNotEmpty(this.action))
            return action.expandString(context);
        return null;
    }

    /**
     * Gets the name of the Service Attribute (aka Parameter) that corresponds
     * with this field. This can be used to get additional information about the field.
     * Use the getServiceName() method to get the Entity name that the field is in.
     *
     * @return returns the name of the Service Attribute 
     */
    public String getAttributeName() {
        if (UtilValidate.isNotEmpty(this.attributeName))
            return this.attributeName;
        return this.name;
    }

    public String getCurrentContainerId(Map<String, Object> context) {
        ModelForm modelForm = this.getModelForm();
        String idName = FlexibleStringExpander.expandString(this.getIdName(), context);

        if (modelForm != null) {
            Integer itemIndex = (Integer) context.get("itemIndex");
            if ("list".equals(modelForm.getType()) || "multi".equals(modelForm.getType())) {
                if (itemIndex != null) {
                    return idName + modelForm.getItemIndexSeparator() + itemIndex.intValue();
                }
            }
        }
        return idName;
    }

    public boolean getEncodeOutput() {
        return this.encodeOutput;
    }

    public String getEntityName() {
        if (UtilValidate.isNotEmpty(this.entityName))
            return this.entityName;
        return this.modelForm.getDefaultEntityName();
    }

    /**
     * Gets the entry from the context that corresponds to this field; if this
     * form is being rendered in an error condition (ie isError in the context
     * is true) then the value will be retrieved from the parameters Map in
     * the context.
     *
     * @param context the context
     * @return returns the entry from the context that corresponds to this field
     */
    public String getEntry(Map<String, ? extends Object> context) {
        return this.getEntry(context, "");
    }

    public String getEntry(Map<String, ? extends Object> context, String defaultValue) {
        Boolean isError = (Boolean) context.get("isError");
        Boolean useRequestParameters = (Boolean) context.get("useRequestParameters");

        Locale locale = (Locale) context.get("locale");
        if (locale == null)
            locale = Locale.getDefault();
        TimeZone timeZone = (TimeZone) context.get("timeZone");
        if (timeZone == null)
            timeZone = TimeZone.getDefault();

        UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");

        String returnValue;

        // if useRequestParameters is TRUE then parameters will always be used, if FALSE then parameters will never be used
        // if isError is TRUE and useRequestParameters is not FALSE (ie is null or TRUE) then parameters will be used
        if ((Boolean.TRUE.equals(isError) && !Boolean.FALSE.equals(useRequestParameters))
                || (Boolean.TRUE.equals(useRequestParameters))) {
            //Debug.logInfo("Getting entry, isError true so getting from parameters for field " + this.getName() + " of form " + this.modelForm.getName(), module);
            Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"), String.class, Object.class);
            String parameterName = this.getParameterName(context);
            if (parameters != null && parameters.get(parameterName) != null) {
                Object parameterValue = parameters.get(parameterName);
                if (parameterValue instanceof String) {
                    returnValue = (String) parameterValue;
                } else {
                    // we might want to do something else here in the future, but for now this is probably best
                    Debug.logWarning("Found a non-String parameter value for field [" + this.getModelForm().getName() + "."
                            + this.getFieldName() + "]", module);
                    returnValue = defaultValue;
                }
            } else {
                returnValue = defaultValue;
            }
        } else {
            //Debug.logInfo("Getting entry, isError false so getting from Map in context for field " + this.getName() + " of form " + this.modelForm.getName(), module);
            Map<String, ? extends Object> dataMap = this.getMap(context);
            boolean dataMapIsContext = false;
            if (dataMap == null) {
                //Debug.logInfo("Getting entry, no Map found with name " + this.getMapName() + ", using context for field " + this.getName() + " of form " + this.modelForm.getName(), module);
                dataMap = context;
                dataMapIsContext = true;
            }
            Object retVal = null;
            if (UtilValidate.isNotEmpty(this.entryAcsr)) {
                if (dataMap instanceof GenericEntity) {
                    GenericEntity genEnt = (GenericEntity) dataMap;
                    if (genEnt.getModelEntity().isField(this.entryAcsr.getOriginalName())) {
                        retVal = genEnt.get(this.entryAcsr.getOriginalName(), locale);
                    } else {
                        //TODO: this may never come up, but if necessary use the FlexibleStringExander to eval the name first: String evaled = this.entryAcsr
                    }
                } else {
                    retVal = this.entryAcsr.get(dataMap, locale);
                }
            } else {
                // if no entry name was specified, use the field's name
                if (dataMap.containsKey(this.name)) {
                    retVal = dataMap.get(this.name);
                }
            }

            // this is a special case to fill in fields during a create by default from parameters passed in
            if (dataMapIsContext && retVal == null && !Boolean.FALSE.equals(useRequestParameters)) {
                Map<String, ? extends Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
                if (parameters != null) {
                    if (UtilValidate.isNotEmpty(this.entryAcsr))
                        retVal = this.entryAcsr.get(parameters);
                    else
                        retVal = parameters.get(this.name);
                }
            }

            if (retVal != null) {
                // format string based on the user's locale and time zone
                if (retVal instanceof Double || retVal instanceof Float || retVal instanceof BigDecimal) {
                    NumberFormat nf = NumberFormat.getInstance(locale);
                    nf.setMaximumFractionDigits(10);
                    return nf.format(retVal);
                } else if (retVal instanceof java.sql.Date) {
                    DateFormat df = UtilDateTime.toDateFormat(UtilDateTime.getDateFormat(), timeZone, null);
                    return df.format((java.util.Date) retVal);
                } else if (retVal instanceof java.sql.Time) {
                    DateFormat df = UtilDateTime.toTimeFormat(UtilDateTime.getTimeFormat(), timeZone, null);
                    return df.format((java.util.Date) retVal);
                } else if (retVal instanceof java.sql.Timestamp) {
                    DateFormat df = UtilDateTime.toDateTimeFormat(UtilDateTime.getDateTimeFormat(), timeZone, null);
                    return df.format((java.util.Date) retVal);
                } else if (retVal instanceof java.util.Date) {
                    DateFormat df = UtilDateTime.toDateTimeFormat("EEE MMM dd hh:mm:ss z yyyy", timeZone, null);
                    return df.format((java.util.Date) retVal);
                } else if (retVal instanceof Collection) {
                    Collection<Object> col = UtilGenerics.checkCollection(retVal);
                    Iterator<Object> iter = col.iterator();
                    List<Object> newCol = new ArrayList<Object>(col.size());
                    while (iter.hasNext()) {
                        Object item = iter.next();
                        if (item == null) {
                            continue;
                        }
                        if (simpleEncoder != null) {
                            newCol.add(simpleEncoder.encode(item.toString()));
                        }
                        else {
                            newCol.add(item.toString());
                        }
                    }
                    return newCol.toString();
                } else {
                    returnValue = retVal.toString();
                }
            } else {
                returnValue = defaultValue;
            }
        }

        if (this.getEncodeOutput() && returnValue != null) {
            if (simpleEncoder != null)
                returnValue = simpleEncoder.encode(returnValue);
        }
        return returnValue;
    }

    public FlexibleMapAccessor<Object> getEntryAcsr() {
        return entryAcsr;
    }

    public String getEntryName() {
        if (UtilValidate.isNotEmpty(this.entryAcsr))
            return this.entryAcsr.getOriginalName();
        return this.name;
    }

    public String getEvent() {
        return event;
    }

    public FieldInfo getFieldInfo() {
        return fieldInfo;
    }

    /**
     * Gets the name of the Entity Field that corresponds
     * with this field. This can be used to get additional information about the field.
     * Use the getEntityName() method to get the Entity name that the field is in.
     *
     * @return return the name of the Entity Field that corresponds with this field
     */
    public String getFieldName() {
        if (UtilValidate.isNotEmpty(this.fieldName))
            return this.fieldName;
        return this.name;
    }

    public String getHeaderLink() {
        return headerLink;
    }

    public String getHeaderLinkStyle() {
        return headerLinkStyle;
    }

    public String getIdName() {
        if (UtilValidate.isNotEmpty(idName))
            return idName;
        String parentFormName = this.getParentFormName();
        if (UtilValidate.isNotEmpty(parentFormName)) {
            return parentFormName + "_" + this.getFieldName();
        } else {
           return this.modelForm.getName() + "_" + this.getFieldName();
        }
    }

    public String getTabindex() {
        return tabindex;
    }

    public Map<String, ? extends Object> getMap(Map<String, ? extends Object> context) {
        if (UtilValidate.isEmpty(this.mapAcsr))
            return this.modelForm.getDefaultMap(context); //Debug.logInfo("Getting Map from default of the form because of no mapAcsr for field " + this.getName(), module);

        // Debug.logInfo("Getting Map from mapAcsr for field " + this.getName() + ", map-name=" + mapAcsr.getOriginalName() + ", context type=" + context.getClass().toString(), module);
        Map<String, ? extends Object> result = null;
        try {
            result = mapAcsr.get(context);
        } catch (ClassCastException e) {
            String errMsg = "Got an unexpected object type (not a Map) for map-name [" + mapAcsr.getOriginalName()
                    + "] in field with name [" + this.getName() + "]: " + e.getMessage();
            Debug.logError(errMsg, module);
            throw new ClassCastException(errMsg);
        }
        return result;
    }

    public FlexibleMapAccessor<Map<String, ? extends Object>> getMapAcsr() {
        return mapAcsr;
    }

    /** Get the name of the Map in the form context that contains the entry,
     * available from the getEntryName() method. This entry is used to
     * pre-populate the field widget when not in an error condition. In an
     * error condition the parameter name is used to get the value from the
     * parameters Map.
     *
     * @return returns the name of the Map in the form context that contains the entry
     */
    public String getMapName() {
        if (UtilValidate.isNotEmpty(this.mapAcsr))
            return this.mapAcsr.getOriginalName();
        return this.modelForm.getDefaultMapName();
    }

    public ModelForm getModelForm() {
        return modelForm;
    }

    public String getName() {
        return name;
    }

    public List<UpdateArea> getOnChangeUpdateAreas() {
        return onChangeUpdateAreas;
    }

    public List<UpdateArea> getOnClickUpdateAreas() {
        return onClickUpdateAreas;
    }

    public String getParameterName() {
        return parameterName;
    }

    /**
     * Get the name to use for the parameter for this field in the form interpreter.
     * For HTML forms this is the request parameter name.
     *
     * @return returns the name to use for the parameter for this field in the form interpreter
     */
    public String getParameterName(Map<String, ? extends Object> context) {
        String baseName;
        if (UtilValidate.isNotEmpty(this.parameterName))
            baseName = this.parameterName;
        else
            baseName = this.name;

        Integer itemIndex = (Integer) context.get("itemIndex");
        if (itemIndex != null && "multi".equals(this.modelForm.getType())) {
            return baseName + this.modelForm.getItemIndexSeparator() + itemIndex.intValue();
        } else {
            return baseName;
        }
    }

    public int getPosition() {
        if (this.position == null)
            return 1;
        return position.intValue();
    }

    public String getRedWhen() {
        return redWhen;
    }

    public boolean getRequiredField() {
        return this.requiredField != null ? this.requiredField : false;
    }

    public String getRequiredFieldStyle() {
        if (UtilValidate.isNotEmpty(this.requiredFieldStyle))
            return this.requiredFieldStyle;
        return this.modelForm.getDefaultRequiredFieldStyle();
    }

    public boolean getSeparateColumn() {
        return this.separateColumn;
    }

    public String getServiceName() {
        if (UtilValidate.isNotEmpty(this.serviceName))
            return this.serviceName;
        return this.modelForm.getDefaultServiceName();
    }

    public Boolean getSortField() {
        return sortField;
    }

    public String getSortFieldAscStyle() {
        return sortFieldAscStyle;
    }

    public String getSortFieldDescStyle() {
        return sortFieldDescStyle;
    }

    public String getSortFieldHelpText() {
        return sortFieldHelpText;
    }

    public String getSortFieldHelpText(Map<String, Object> context) {
        return FlexibleStringExpander.expandString(this.sortFieldHelpText, context);
    }

    public String getSortFieldStyle() {
        if (UtilValidate.isNotEmpty(this.sortFieldStyle))
            return this.sortFieldStyle;
        return this.modelForm.getDefaultSortFieldStyle();
    }

    public String getSortFieldStyleAsc() {
        if (UtilValidate.isNotEmpty(this.sortFieldAscStyle))
            return this.sortFieldAscStyle;
        return this.modelForm.getDefaultSortFieldAscStyle();
    }

    public String getSortFieldStyleDesc() {
        if (UtilValidate.isNotEmpty(this.sortFieldDescStyle))
            return this.sortFieldDescStyle;
        return this.modelForm.getDefaultSortFieldDescStyle();
    }

    public FlexibleStringExpander getTitle() {
        return title;
    }

    public String getTitle(Map<String, Object> context) {
        if (UtilValidate.isNotEmpty(this.title))
            return title.expandString(context);

        // create a title from the name of this field; expecting a Java method/field style name, ie productName or productCategoryId
        if (UtilValidate.isEmpty(this.name))
            return ""; // this should never happen, ie name is required

        // search for a localized label for the field's name
        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
        if (uiLabelMap != null) {
            String titleFieldName = "FormFieldTitle_" + this.name;
            String localizedName = uiLabelMap.get(titleFieldName);
            if (!localizedName.equals(titleFieldName)) {
                return localizedName;
            }
        } else {
            Debug.logWarning("Could not find uiLabelMap in context while rendering form " + this.modelForm.getName(), module);
        }

        // create a title from the name of this field; expecting a Java method/field style name, ie productName or productCategoryId
        StringBuilder autoTitlewriter = new StringBuilder();

        // always use upper case first letter...
        autoTitlewriter.append(Character.toUpperCase(this.name.charAt(0)));

        // just put spaces before the upper case letters
        for (int i = 1; i < this.name.length(); i++) {
            char curChar = this.name.charAt(i);
            if (Character.isUpperCase(curChar)) {
                autoTitlewriter.append(' ');
            }
            autoTitlewriter.append(curChar);
        }

        return autoTitlewriter.toString();
    }

    public String getTitleAreaStyle() {
        if (UtilValidate.isNotEmpty(this.titleAreaStyle))
            return this.titleAreaStyle;
        return this.modelForm.getDefaultTitleAreaStyle();
    }

    public String getTitleStyle() {
        if (UtilValidate.isNotEmpty(this.titleStyle))
            return this.titleStyle;
        return this.modelForm.getDefaultTitleStyle();
    }

    public FlexibleStringExpander getTooltip() {
        return tooltip;
    }

    public String getTooltip(Map<String, Object> context) {
        String tooltipString = "";
        if (UtilValidate.isNotEmpty(tooltip))
            tooltipString = tooltip.expandString(context);
        if (this.getEncodeOutput()) {
            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
            if (simpleEncoder != null)
                tooltipString = simpleEncoder.encode(tooltipString);
        }
        return tooltipString;
    }

    public String getTooltipStyle() {
        if (UtilValidate.isNotEmpty(this.tooltipStyle))
            return this.tooltipStyle;
        return this.modelForm.getDefaultTooltipStyle();
    }

    public FlexibleStringExpander getUseWhen() {
        return useWhen;
    }

    public String getUseWhen(Map<String, Object> context) {
        if (UtilValidate.isNotEmpty(this.useWhen))
            return this.useWhen.expandString(context);
        return "";
    }

    public String getIgnoreWhen(Map<String, Object> context) {
        if (UtilValidate.isNotEmpty(this.ignoreWhen))
            return this.ignoreWhen.expandString(context);
        return "";
    }

    public String getWidgetAreaStyle() {
        if (UtilValidate.isNotEmpty(this.widgetAreaStyle))
            return this.widgetAreaStyle;
        return this.modelForm.getDefaultWidgetAreaStyle();
    }

    public String getWidgetStyle() {
        if (UtilValidate.isNotEmpty(this.widgetStyle))
            return this.widgetStyle;
        return this.modelForm.getDefaultWidgetStyle();
    }

    public String getParentFormName() {
        if (UtilValidate.isNotEmpty(this.parentFormName)) 
            return this.parentFormName;
        return "";
    }

    /**
     * Checks if field is a row submit field.
     */
    public boolean isRowSubmit() {
        if (!"multi".equals(getModelForm().getType()))
            return false;
        if (getFieldInfo().getFieldType() != FieldInfo.CHECK)
            return false;
        if (!CheckField.ROW_SUBMIT_FIELD_NAME.equals(getName()))
            return false;
        return true;
    }

    public boolean isSortField() {
        return this.sortField != null && this.sortField.booleanValue();
    }

    public boolean isUseWhenEmpty() {
        if (this.useWhen == null) {
            return true;
        }

        return this.useWhen.isEmpty();
    }

    public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
            throws IOException {
        this.fieldInfo.renderFieldString(writer, context, formStringRenderer);
    }

    /**
     * the widget/interaction part will be red if the date value is
     *  before-now (for ex. thruDate), after-now (for ex. fromDate), or by-name (if the
     *  field's name or entry-name or fromDate or thruDate the corresponding
     *  action will be done); only applicable when the field is a timestamp
     *
     * @param context the context
     * @return true if the field should be read otherwise false
     */
    public boolean shouldBeRed(Map<String, Object> context) {
        // red-when (never | before-now | after-now | by-name) "by-name"

        String redCondition = this.redWhen;

        if ("never".equals(redCondition))
            return false;

        // for performance resaons we check this first, most fields will be eliminated here and the valueOfs will not be necessary
        if (UtilValidate.isEmpty(redCondition) || "by-name".equals(redCondition)) {
            if ("fromDate".equals(this.name) || (this.entryAcsr != null && "fromDate".equals(this.entryAcsr.getOriginalName()))) {
                redCondition = "after-now";
            } else if ("thruDate".equals(this.name)
                    || (this.entryAcsr != null && "thruDate".equals(this.entryAcsr.getOriginalName()))) {
                redCondition = "before-now";
            } else {
                return false;
            }
        }

        boolean isBeforeNow = false;
        if ("before-now".equals(redCondition)) {
            isBeforeNow = true;
        } else if ("after-now".equals(redCondition)) {
            isBeforeNow = false;
        } else {
            return false;
        }

        java.sql.Date dateVal = null;
        java.sql.Time timeVal = null;
        java.sql.Timestamp timestampVal = null;

        //now before going on, check to see if the current entry is a valid date and/or time and get the value
        String value = this.getEntry(context, null);
        try {
            timestampVal = java.sql.Timestamp.valueOf(value);
        } catch (IllegalArgumentException e) {
            // okay, not a timestamp...
        }

        if (timestampVal == null) {
            try {
                dateVal = java.sql.Date.valueOf(value);
            } catch (IllegalArgumentException e) {
                // okay, not a date...
            }
        }

        if (timestampVal == null && dateVal == null) {
            try {
                timeVal = java.sql.Time.valueOf(value);
            } catch (IllegalArgumentException e) {
                // okay, not a time...
            }
        }

        if (timestampVal == null && dateVal == null && timeVal == null) {
            return false;
        }

        long nowMillis = System.currentTimeMillis();
        if (timestampVal != null) {
            java.sql.Timestamp nowStamp = new java.sql.Timestamp(nowMillis);
            if (!timestampVal.equals(nowStamp)) {
                if (isBeforeNow) {
                    if (timestampVal.before(nowStamp)) {
                        return true;
                    }
                } else {
                    if (timestampVal.after(nowStamp)) {
                        return true;
                    }
                }
            }
        } else if (dateVal != null) {
            java.sql.Date nowDate = new java.sql.Date(nowMillis);
            if (!dateVal.equals(nowDate)) {
                if (isBeforeNow) {
                    if (dateVal.before(nowDate)) {
                        return true;
                    }
                } else {
                    if (dateVal.after(nowDate)) {
                        return true;
                    }
                }
            }
        } else if (timeVal != null) {
            java.sql.Time nowTime = new java.sql.Time(nowMillis);
            if (!timeVal.equals(nowTime)) {
                if (isBeforeNow) {
                    if (timeVal.before(nowTime)) {
                        return true;
                    }
                } else {
                    if (timeVal.after(nowTime)) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    public boolean shouldUse(Map<String, Object> context) {
        String useWhenStr = this.getUseWhen(context);
        if (UtilValidate.isEmpty(useWhenStr))
            return true;

        try {
            Object retVal = GroovyUtil.eval(StringUtil.convertOperatorSubstitutions(useWhenStr),context);
            boolean condTrue = false;
            // retVal should be a Boolean, if not something weird is up...
            if (retVal instanceof Boolean) {
                Boolean boolVal = (Boolean) retVal;
                condTrue = boolVal.booleanValue();
            } else {
                throw new IllegalArgumentException("Return value from use-when condition eval was not a Boolean: "
                        + (retVal != null ? retVal.getClass().getName() : "null") + " [" + retVal + "] on the field " + this.name
                        + " of form " + this.modelForm.getName());
            }

            return condTrue;
        } catch (CompilationFailedException e) {
            String errMsg = "Error evaluating groovy use-when condition [" + useWhenStr + "] on the field " + this.name
                    + " of form " + this.modelForm.getName() + ": " + e.toString();
            Debug.logError(e, errMsg, module);
            throw new IllegalArgumentException(errMsg);
        }
    }

    /**
     * Models the &lt;auto-complete&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class AutoComplete {
        private final String autoSelect;
        private final String choices;
        private final String frequency;
        private final String fullSearch;
        private final String ignoreCase;
        private final String minChars;
        private final String partialChars;
        private final String partialSearch;

        public AutoComplete(Element element) {
            this.autoSelect = element.getAttribute("auto-select");
            this.frequency = element.getAttribute("frequency");
            this.minChars = element.getAttribute("min-chars");
            this.choices = element.getAttribute("choices");
            this.partialSearch = element.getAttribute("partial-search");
            this.partialChars = element.getAttribute("partial-chars");
            this.ignoreCase = element.getAttribute("ignore-case");
            this.fullSearch = element.getAttribute("full-search");
        }

        public String getAutoSelect() {
            return this.autoSelect;
        }

        public String getChoices() {
            return this.choices;
        }

        public String getFrequency() {
            return this.frequency;
        }

        public String getFullSearch() {
            return this.fullSearch;
        }

        public String getIgnoreCase() {
            return this.ignoreCase;
        }

        public String getMinChars() {
            return this.minChars;
        }

        public String getPartialChars() {
            return this.partialChars;
        }

        public String getPartialSearch() {
            return this.partialSearch;
        }
    }

    /**
     * Models the &lt;check&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class CheckField extends FieldInfoWithOptions {
        public final static String ROW_SUBMIT_FIELD_NAME = "_rowSubmit";
        private final FlexibleStringExpander allChecked;

        private CheckField(CheckField original, ModelFormField modelFormField) {
            super(original, modelFormField);
            this.allChecked = original.allChecked;
        }

        public CheckField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            allChecked = FlexibleStringExpander.getInstance(element.getAttribute("all-checked"));
        }

        public CheckField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.CHECK, modelFormField);
            this.allChecked = FlexibleStringExpander.getInstance("");
        }

        public CheckField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.CHECK, modelFormField);
            this.allChecked = FlexibleStringExpander.getInstance("");
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new CheckField(this, modelFormField);
        }

        public FlexibleStringExpander getAllChecked() {
            return allChecked;
        }

        public Boolean isAllChecked(Map<String, Object> context) {
            String allCheckedStr = this.allChecked.expandString(context);
            if (!allCheckedStr.isEmpty())
                return Boolean.valueOf("true".equals(allCheckedStr));
            else
                return null;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderCheckField(writer, context, this);
        }
    }

    /**
     * Models the &lt;container&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class ContainerField extends FieldInfo {

        private ContainerField(ContainerField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
        }

        public ContainerField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
        }

        public ContainerField(int fieldSource, int fieldType, ModelFormField modelFormField) {
            super(fieldSource, fieldType, modelFormField);
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new ContainerField(this, modelFormField);
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderContainerFindField(writer, context, this);
        }
    }

    /**
     * Models the &lt;date-find&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class DateFindField extends DateTimeField {
        private final String defaultOptionFrom;
        private final String defaultOptionThru;

        private DateFindField(DateFindField original, ModelFormField modelFormField) {
            super(original, modelFormField);
            this.defaultOptionFrom = original.defaultOptionFrom;
            this.defaultOptionThru = original.defaultOptionThru;
        }

        public DateFindField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.defaultOptionFrom = element.getAttribute("default-option-from");
            this.defaultOptionThru = element.getAttribute("default-option-thru");
        }

        public DateFindField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, modelFormField);
            this.defaultOptionFrom = "greaterThanEqualTo";
            this.defaultOptionThru = "lessThanEqualTo";
        }

        public DateFindField(int fieldSource, String type) {
            super(fieldSource, type);
            this.defaultOptionFrom = "greaterThanEqualTo";
            this.defaultOptionThru = "lessThanEqualTo";
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new DateFindField(this, modelFormField);
        }

        public String getDefaultOptionFrom() {
            return this.defaultOptionFrom;
        }

        public String getDefaultOptionFrom(Map<String, Object> context) {
            String defaultOption = getDefaultOptionFrom();

            Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"), String.class, Object.class);
            if (UtilValidate.isNotEmpty(parameters)) {
                String fieldName = this.getModelFormField().getName();
                if (parameters.containsKey(fieldName.concat("_fld0_value"))){
                    defaultOption = (String)parameters.get(fieldName.concat("_fld0_op"));
                }
            }
            return defaultOption;
        }

        public String getDefaultOptionThru() {
            return this.defaultOptionThru;
        }

        public String getDefaultOptionThru(Map<String, Object> context) {
            String defaultOption = getDefaultOptionThru();

            Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"), String.class, Object.class);
            if (UtilValidate.isNotEmpty(parameters)) {
                String fieldName = this.getModelFormField().getName();
                if( parameters.containsKey(fieldName.concat("_fld1_value"))) {
                    defaultOption = (String)parameters.get(fieldName.concat("_fld1_op"));
                }
            }
            return defaultOption;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderDateFindField(writer, context, this);
        }
    }

    /**
     * Models the &lt;date-time&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class DateTimeField extends FieldInfo {
        private final String clock;
        private final FlexibleStringExpander defaultValue;
        private final String inputMethod;
        private final String mask;
        private final String step;
        private final String type;

        protected DateTimeField(DateTimeField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.defaultValue = original.defaultValue;
            this.type = original.type;
            this.inputMethod = original.inputMethod;
            this.clock = original.clock;
            this.mask = original.mask;
            this.step = original.step;
        }

        public DateTimeField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
            this.type = element.getAttribute("type");
            this.inputMethod = element.getAttribute("input-method");
            this.clock = element.getAttribute("clock");
            this.mask = element.getAttribute("mask");
            String step = element.getAttribute("step");
            if (step.isEmpty()) {
                step = "1";
            }
            this.step = step;
        }

        public DateTimeField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.DATE_TIME, modelFormField);
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.type = "";
            this.inputMethod = "";
            this.clock = "";
            this.mask = "";
            this.step = "1";
        }

        public DateTimeField(int fieldSource, String type) {
            super(fieldSource, FieldInfo.DATE_TIME, null);
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.type = type;
            this.inputMethod = "";
            this.clock = "";
            this.mask = "";
            this.step = "1";
        }

        public DateTimeField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DATE_TIME, modelFormField);
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.type = "";
            this.inputMethod = "";
            this.clock = "";
            this.mask = "";
            this.step = "1";
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new DateTimeField(this, modelFormField);
        }

        public String getClock() {
            return this.clock;
        }

        /**
         * Returns the default-value if specified, otherwise the current date, time or timestamp
         *
         * @param context Context Map
         * @return Default value string for date-time
         */
        public String getDefaultDateTimeString(Map<String, Object> context) {
            if (UtilValidate.isNotEmpty(this.defaultValue))
                return this.getDefaultValue(context);

            if ("date".equals(this.type))
                return (new java.sql.Date(System.currentTimeMillis())).toString();
            else if ("time".equals(this.type))
                return (new java.sql.Time(System.currentTimeMillis())).toString();
            else
                return UtilDateTime.nowTimestamp().toString();
        }

        public FlexibleStringExpander getDefaultValue() {
            return defaultValue;
        }

        public String getDefaultValue(Map<String, Object> context) {
            if (this.defaultValue != null) {
                return this.defaultValue.expandString(context);
            } else {
                return "";
            }
        }

        public String getInputMethod() {
            return this.inputMethod;
        }

        public String getMask() {
            return this.mask;
        }

        public String getStep() {
            return this.step;
        }

        public String getType() {
            return type;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderDateTimeField(writer, context, this);
        }
    }

    /**
     * Models the &lt;display-entity&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class DisplayEntityField extends DisplayField {
        private final boolean cache;
        private final String entityName;
        private final String keyFieldName;
        private final SubHyperlink subHyperlink;

        private DisplayEntityField(DisplayEntityField original, ModelFormField modelFormField) {
            super(original, modelFormField);
            this.cache = original.cache;
            this.entityName = original.entityName;
            this.keyFieldName = original.keyFieldName;
            if (original.subHyperlink != null) {
                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
            } else {
                this.subHyperlink = null;
            }
        }

        public DisplayEntityField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.cache = !"false".equals(element.getAttribute("cache"));
            this.entityName = element.getAttribute("entity-name");
            this.keyFieldName = element.getAttribute("key-field-name");
            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
            if (subHyperlinkElement != null) {
                this.subHyperlink = new SubHyperlink(subHyperlinkElement, modelFormField);
            } else {
                this.subHyperlink = null;
            }
        }

        public DisplayEntityField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.DISPLAY_ENTITY, modelFormField);
            this.cache = true;
            this.entityName = "";
            this.keyFieldName = "";
            this.subHyperlink = null;
        }

        public DisplayEntityField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DISPLAY_ENTITY, modelFormField);
            this.cache = true;
            this.entityName = "";
            this.keyFieldName = "";
            this.subHyperlink = null;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new DisplayEntityField(this, modelFormField);
        }

        public boolean getCache() {
            return cache;
        }

        @Override
        public String getDescription(Map<String, Object> context) {
            Locale locale = UtilMisc.ensureLocale(context.get("locale"));

            // rather than using the context to expand the string, lookup the given entity and use it to expand the string
            GenericValue value = null;
            String fieldKey = this.keyFieldName;
            if (UtilValidate.isEmpty(fieldKey))
                fieldKey = getModelFormField().fieldName;

            Delegator delegator = WidgetWorker.getDelegator(context);
            String fieldValue = getModelFormField().getEntry(context);
            try {
                value = delegator.findOne(this.entityName, this.cache, fieldKey, fieldValue);
            } catch (GenericEntityException e) {
                String errMsg = "Error getting value from the database for display of field [" + getModelFormField().getName()
                        + "] on form [" + getModelFormField().modelForm.getName() + "]: " + e.toString();
                Debug.logError(e, errMsg, module);
                throw new IllegalArgumentException(errMsg);
            }

            String retVal = null;
            if (value != null) {
                // expanding ${} stuff, passing locale explicitly to expand value string because it won't be found in the Entity
                MapStack<String> localContext = MapStack.create(context);
                // Rendering code might try to modify the GenericEntity instance,
                // so we make a copy of it.
                Map<String, Object> genericEntityClone = UtilGenerics.cast(value.clone());
                localContext.push(genericEntityClone);

                // expand with the new localContext, which is locale aware
                retVal = this.getDescription().expandString(localContext, locale);
            }
            // try to get the entry for the field if description doesn't expand to anything
            if (UtilValidate.isEmpty(retVal)) {
                retVal = fieldValue;
            } 
            if (UtilValidate.isEmpty(retVal)) {
                retVal = "";
            } else if (this.getModelFormField().getEncodeOutput()) {
                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                if (simpleEncoder != null) {
                    retVal = simpleEncoder.encode(retVal);
                }
            }
            return retVal;
        }

        public String getEntityName() {
            return entityName;
        }

        public String getKeyFieldName() {
            return keyFieldName;
        }

        public SubHyperlink getSubHyperlink() {
            return this.subHyperlink;
        }
    }

    /**
     * Models the &lt;display&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class DisplayField extends FieldInfo {
        private final boolean alsoHidden;
        private final FlexibleStringExpander currency;
        private final FlexibleStringExpander date;
        private final FlexibleStringExpander defaultValue;
        private final FlexibleStringExpander description;
        private final FlexibleStringExpander imageLocation;
        private final InPlaceEditor inPlaceEditor;
        private final String size; // maximum number of characters to display
        private final String type; // matches type of field, currently text or currency

        protected DisplayField(DisplayField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.alsoHidden = original.alsoHidden;
            this.currency = original.currency;
            this.date = original.date;
            this.defaultValue = original.defaultValue;
            this.description = original.description;
            this.imageLocation = original.imageLocation;
            this.inPlaceEditor = original.inPlaceEditor;
            this.size = original.size;
            this.type = original.type;
        }

        public DisplayField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.alsoHidden = !"false".equals(element.getAttribute("also-hidden"));
            this.currency = FlexibleStringExpander.getInstance(element.getAttribute("currency"));
            this.date = FlexibleStringExpander.getInstance(element.getAttribute("date"));
            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
            this.imageLocation = FlexibleStringExpander.getInstance(element.getAttribute("image-location"));
            Element inPlaceEditorElement = UtilXml.firstChildElement(element, "in-place-editor");
            if (inPlaceEditorElement != null) {
                this.inPlaceEditor = new InPlaceEditor(inPlaceEditorElement);
            } else {
                this.inPlaceEditor = null;
            }
            this.size = element.getAttribute("size");
            this.type = element.getAttribute("type");
        }

        public DisplayField(int fieldSource, int fieldType, ModelFormField modelFormField) {
            super(fieldSource, fieldType, modelFormField);
            this.alsoHidden = true;
            this.currency = FlexibleStringExpander.getInstance("");
            this.date = FlexibleStringExpander.getInstance("");
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.description = FlexibleStringExpander.getInstance("");
            this.imageLocation = FlexibleStringExpander.getInstance("");
            this.inPlaceEditor = null;
            this.size = "";
            this.type = "";
        }

        public DisplayField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.DISPLAY, modelFormField);
            this.alsoHidden = true;
            this.currency = FlexibleStringExpander.getInstance("");
            this.date = FlexibleStringExpander.getInstance("");
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.description = FlexibleStringExpander.getInstance("");
            this.imageLocation = FlexibleStringExpander.getInstance("");
            this.inPlaceEditor = null;
            this.size = "";
            this.type = "";
        }

        public DisplayField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DISPLAY, modelFormField);
            this.alsoHidden = true;
            this.currency = FlexibleStringExpander.getInstance("");
            this.date = FlexibleStringExpander.getInstance("");
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.description = FlexibleStringExpander.getInstance("");
            this.imageLocation = FlexibleStringExpander.getInstance("");
            this.inPlaceEditor = null;
            this.size = "";
            this.type = "";
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new DisplayField(this, modelFormField);
        }

        public boolean getAlsoHidden() {
            return alsoHidden;
        }

        public FlexibleStringExpander getCurrency() {
            return currency;
        }

        public FlexibleStringExpander getDate() {
            return date;
        }

        public FlexibleStringExpander getDefaultValue() {
            return defaultValue;
        }

        public String getDefaultValue(Map<String, Object> context) {
            if (this.defaultValue != null) {
                return this.defaultValue.expandString(context);
            } else {
                return "";
            }
        }

        public FlexibleStringExpander getDescription() {
            return description;
        }

        public String getDescription(Map<String, Object> context) {
            String retVal = null;
            if (UtilValidate.isNotEmpty(this.description))
                retVal = this.description.expandString(context);
            else
                retVal = getModelFormField().getEntry(context);

            if (UtilValidate.isEmpty(retVal)) {
                retVal = this.getDefaultValue(context);
            } else if ("currency".equals(type)) {
                retVal = retVal.replaceAll("&nbsp;", " "); // FIXME : encoding currency is a problem for some locale, we should not have any &nbsp; in retVal other case may arise in future...
                Locale locale = (Locale) context.get("locale");
                if (locale == null)
                    locale = Locale.getDefault();
                String isoCode = null;
                if (UtilValidate.isNotEmpty(this.currency))
                    isoCode = this.currency.expandString(context);

                try {
                    BigDecimal parsedRetVal = (BigDecimal) ObjectType.simpleTypeConvert(retVal, "BigDecimal", null, null, locale,
                            true);
                    retVal = UtilFormatOut.formatCurrency(parsedRetVal, isoCode, locale, 10); // we set the max to 10 digits as an hack to not round numbers in the ui
                } catch (GeneralException e) {
                    String errMsg = "Error formatting currency value [" + retVal + "]: " + e.toString();
                    Debug.logError(e, errMsg, module);
                    throw new IllegalArgumentException(errMsg);
                }
            } else if ("date".equals(this.type) && retVal.length() > 10) {
                Locale locale = (Locale) context.get("locale");
                if (locale == null) {
                    locale = Locale.getDefault();
                }

                StringToTimestamp stringToTimestamp = new DateTimeConverters.StringToTimestamp();
                Timestamp timestamp = null;
                try {
                    timestamp = stringToTimestamp.convert(retVal);
                    Date date = new Date(timestamp.getTime());

                    DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.SHORT, locale);
                    retVal = dateFormatter.format(date);
                } catch (ConversionException e) {
                    String errMsg = "Error formatting date using default instead [" + retVal + "]: " + e.toString();
                    Debug.logError(e, errMsg, module);
                    // create default date value from timestamp string
                    retVal = retVal.substring(0, 10);
                }

            } else if ("date-time".equals(this.type) && retVal.length() > 16) {
                Locale locale = (Locale) context.get("locale");
                TimeZone timeZone = (TimeZone) context.get("timeZone");
                if (locale == null) {
                    locale = Locale.getDefault();
                }
                if (timeZone == null) {
                    timeZone = TimeZone.getDefault();
                }

                StringToTimestamp stringToTimestamp = new DateTimeConverters.StringToTimestamp();
                Timestamp timestamp = null;
                try {
                    timestamp = stringToTimestamp.convert(retVal);
                    Date date = new Date(timestamp.getTime());

                    DateFormat dateFormatter = UtilDateTime.toDateTimeFormat(null, timeZone, locale);
                    retVal = dateFormatter.format(date);
                } catch (ConversionException e) {
                    String errMsg = "Error formatting date/time using default instead [" + retVal + "]: " + e.toString();
                    Debug.logError(e, errMsg, module);
                    // create default date/time value from timestamp string
                    retVal = retVal.substring(0, 16);
                }
            } else if ("accounting-number".equals(this.type)) {
                Locale locale = (Locale) context.get("locale");
                if (locale == null) {
                    locale = Locale.getDefault();
                }
                try {
                    Double parsedRetVal = (Double) ObjectType.simpleTypeConvert(retVal, "Double", null, locale, false);
                    String template = UtilProperties.getPropertyValue("arithmetic", "accounting-number.format",
                            "#,##0.00;(#,##0.00)");
                    retVal = UtilFormatOut.formatDecimalNumber(parsedRetVal.doubleValue(), template, locale);
                } catch (GeneralException e) {
                    String errMsg = "Error formatting number [" + retVal + "]: " + e.toString();
                    Debug.logError(e, errMsg, module);
                    throw new IllegalArgumentException(errMsg);
                }
            }
            if (UtilValidate.isNotEmpty(this.description) && retVal != null && this.getModelFormField().getEncodeOutput()) {
                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                if (simpleEncoder != null) {
                    retVal = simpleEncoder.encode(retVal);
                }
            }
            return retVal;
        }

        public FlexibleStringExpander getImageLocation() {
            return imageLocation;
        }

        public String getImageLocation(Map<String, Object> context) {
            if (this.imageLocation != null)
                return this.imageLocation.expandString(context);
            return "";
        }

        public InPlaceEditor getInPlaceEditor() {
            return this.inPlaceEditor;
        }

        public String getSize() {
            return this.size;
        }

        public String getType() {
            return this.type;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderDisplayField(writer, context, this);
        }
    }

    /**
     * Models the &lt;drop-down&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class DropDownField extends FieldInfoWithOptions {
        private final boolean allowEmpty;
        private final boolean allowMulti;
        private final AutoComplete autoComplete;
        private final String current;
        private final FlexibleStringExpander currentDescription;
        private final int otherFieldSize;
        private final String size;
        private final SubHyperlink subHyperlink;
        private final String textSize;

        private DropDownField(DropDownField original, ModelFormField modelFormField) {
            super(original, modelFormField);
            this.allowEmpty = original.allowEmpty;
            this.allowMulti = original.allowMulti;
            this.autoComplete = original.autoComplete;
            this.current = original.current;
            this.currentDescription = original.currentDescription;
            this.otherFieldSize = original.otherFieldSize;
            this.size = original.size;
            if (original.subHyperlink != null) {
                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
            } else {
                this.subHyperlink = null;
            }
            this.textSize = original.textSize;
        }

        public DropDownField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.allowEmpty = "true".equals(element.getAttribute("allow-empty"));
            this.allowMulti = "true".equals(element.getAttribute("allow-multiple"));
            Element autoCompleteElement = UtilXml.firstChildElement(element, "auto-complete");
            if (autoCompleteElement != null) {
                this.autoComplete = new AutoComplete(autoCompleteElement);
            } else {
                this.autoComplete = null;
            }
            this.current = element.getAttribute("current");
            this.currentDescription = FlexibleStringExpander.getInstance(element.getAttribute("current-description"));
            int otherFieldSize = 0;
            String sizeStr = element.getAttribute("other-field-size");
            if (!sizeStr.isEmpty()) {
                try {
                    otherFieldSize = Integer.parseInt(sizeStr);
                } catch (NumberFormatException e) {
                    Debug.logError("Could not parse the size value of the text element: [" + sizeStr
                            + "], setting to the default of 0", module);
                }
            }
            this.otherFieldSize = otherFieldSize;
            String size = element.getAttribute("size");
            if (size.isEmpty()) {
                size = "1";
            }
            this.size = size;
            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
            if (subHyperlinkElement != null) {
                this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField());
            } else {
                this.subHyperlink = null;
            }
            String textSize = element.getAttribute("text-size");
            if (textSize.isEmpty()) {
                textSize = "0";
            }
            this.textSize = textSize;
        }

        public DropDownField(int fieldSource, List<OptionSource> optionSources) {
            super(fieldSource, FieldInfo.DROP_DOWN, optionSources);
            this.allowEmpty = false;
            this.allowMulti = false;
            this.autoComplete = null;
            this.current = "";
            this.currentDescription = FlexibleStringExpander.getInstance("");
            this.otherFieldSize = 0;
            this.size = "1";
            this.subHyperlink = null;
            this.textSize = "0";
        }

        public DropDownField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.DROP_DOWN, modelFormField);
            this.allowEmpty = false;
            this.allowMulti = false;
            this.autoComplete = null;
            this.current = "";
            this.currentDescription = FlexibleStringExpander.getInstance("");
            this.otherFieldSize = 0;
            this.size = "1";
            this.subHyperlink = null;
            this.textSize = "0";
        }

        public DropDownField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.DROP_DOWN, modelFormField);
            this.allowEmpty = false;
            this.allowMulti = false;
            this.autoComplete = null;
            this.current = "";
            this.currentDescription = FlexibleStringExpander.getInstance("");
            this.otherFieldSize = 0;
            this.size = "1";
            this.subHyperlink = null;
            this.textSize = "0";
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new DropDownField(this, modelFormField);
        }

        public boolean getAllowMulti() {
            return allowMulti;
        }

        public AutoComplete getAutoComplete() {
            return this.autoComplete;
        }

        public String getCurrent() {
            if (UtilValidate.isEmpty(this.current))
                return "first-in-list";
            return this.current;
        }

        public FlexibleStringExpander getCurrentDescription() {
            return currentDescription;
        }

        public String getCurrentDescription(Map<String, Object> context) {
            if (this.currentDescription == null)
                return null;
            return this.currentDescription.expandString(context);
        }

        public int getOtherFieldSize() {
            return this.otherFieldSize;
        }

        /**
         * Get the name to use for the parameter for this field in the form interpreter.
         * For HTML forms this is the request parameter name.
         * @param context the context
         * @return returns the name to use for the parameter for this field in the form interpreter.
         */
        public String getParameterNameOther(Map<String, Object> context) {
            String baseName;
            if (UtilValidate.isNotEmpty(getModelFormField().parameterName))
                baseName = getModelFormField().parameterName;
            else
                baseName = getModelFormField().name;

            baseName += "_OTHER";
            Integer itemIndex = (Integer) context.get("itemIndex");
            if (itemIndex != null && "multi".equals(getModelFormField().modelForm.getType())) {
                return baseName + getModelFormField().modelForm.getItemIndexSeparator() + itemIndex.intValue();
            } else {
                return baseName;
            }
        }

        public String getSize() {
            return this.size;
        }

        public SubHyperlink getSubHyperlink() {
            return this.subHyperlink;
        }

        public String getTextSize() {
            return this.textSize;
        }

        public boolean getAllowEmpty() {
            return this.allowEmpty;
        }

        public boolean getAllowMultiple() {
            return this.allowMulti;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderDropDownField(writer, context, this);
        }
    }

    /**
     * Models the &lt;entity-options&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class EntityOptions extends OptionSource {
        private final boolean cache;
        private final List<EntityFinderUtil.ConditionExpr> constraintList;
        private final FlexibleStringExpander description;
        private final String entityName;
        private final String filterByDate;
        private final String keyFieldName;
        private final List<String> orderByList;

        public EntityOptions(Element entityOptionsElement, ModelFormField modelFormField) {
            super(modelFormField);
            this.cache = !"false".equals(entityOptionsElement.getAttribute("cache"));
            List<? extends Element> constraintElements = UtilXml.childElementList(entityOptionsElement, "entity-constraint");
            if (!constraintElements.isEmpty()) {
                List<EntityFinderUtil.ConditionExpr> constraintList = new ArrayList<EntityFinderUtil.ConditionExpr>(
                        constraintElements.size());
                for (Element constraintElement : constraintElements) {
                    constraintList.add(new EntityFinderUtil.ConditionExpr(constraintElement));
                }
                this.constraintList = Collections.unmodifiableList(constraintList);
            } else {
                this.constraintList = Collections.emptyList();
            }
            this.description = FlexibleStringExpander.getInstance(entityOptionsElement.getAttribute("description"));
            this.entityName = entityOptionsElement.getAttribute("entity-name");
            this.filterByDate = entityOptionsElement.getAttribute("filter-by-date");
            this.keyFieldName = entityOptionsElement.getAttribute("key-field-name");
            List<? extends Element> orderByElements = UtilXml.childElementList(entityOptionsElement, "entity-order-by");
            if (!orderByElements.isEmpty()) {
                List<String> orderByList = new ArrayList<String>(orderByElements.size());
                for (Element orderByElement : orderByElements) {
                    orderByList.add(orderByElement.getAttribute("field-name"));
                }
                this.orderByList = Collections.unmodifiableList(orderByList);
            } else {
                this.orderByList = Collections.emptyList();
            }
        }

        private EntityOptions(EntityOptions original, ModelFormField modelFormField) {
            super(modelFormField);
            this.cache = original.cache;
            this.constraintList = original.constraintList;
            this.description = original.description;
            this.entityName = original.entityName;
            this.filterByDate = original.filterByDate;
            this.keyFieldName = original.keyFieldName;
            this.orderByList = original.orderByList;
        }

        public EntityOptions(ModelFormField modelFormField) {
            super(modelFormField);
            this.cache = true;
            this.constraintList = Collections.emptyList();
            this.description = FlexibleStringExpander.getInstance("");
            this.entityName = "";
            this.filterByDate = "";
            this.keyFieldName = "";
            this.orderByList = Collections.emptyList();
        }

        @Override
        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
            // first expand any conditions that need expanding based on the current context
            EntityCondition findCondition = null;
            if (UtilValidate.isNotEmpty(this.constraintList)) {
                List<EntityCondition> expandedConditionList = new LinkedList<EntityCondition>();
                for (EntityFinderUtil.Condition condition : constraintList) {
                    ModelEntity modelEntity = delegator.getModelEntity(this.entityName);
                    if (modelEntity == null) {
                        throw new IllegalArgumentException("Error in entity-options: could not find entity [" + this.entityName
                                + "]");
                    }
                    EntityCondition createdCondition = condition.createCondition(context, modelEntity,
                            delegator.getModelFieldTypeReader(modelEntity));
                    if (createdCondition != null) {
                        expandedConditionList.add(createdCondition);
                    }
                }
                findCondition = EntityCondition.makeCondition(expandedConditionList);
            }

            try {
                Locale locale = UtilMisc.ensureLocale(context.get("locale"));
                ModelEntity modelEntity = delegator.getModelEntity(this.entityName);
                Boolean localizedOrderBy = UtilValidate.isNotEmpty(this.orderByList)
                        && ModelUtil.isPotentialLocalizedFields(modelEntity, this.orderByList);

                List<GenericValue> values = null;
                if (!localizedOrderBy) {
                    values = delegator.findList(this.entityName, findCondition, null, this.orderByList, null, this.cache);
                } else {
                    //if entity has localized label 
                    values = delegator.findList(this.entityName, findCondition, null, null, null, this.cache);
                    values = EntityUtil.localizedOrderBy(values, this.orderByList, locale);
                }

                // filter-by-date if requested
                if ("true".equals(this.filterByDate)) {
                    values = EntityUtil.filterByDate(values, true);
                } else if (!"false".equals(this.filterByDate)) {
                    // not explicitly true or false, check to see if has fromDate and thruDate, if so do the filter
                    if (modelEntity != null && modelEntity.isField("fromDate") && modelEntity.isField("thruDate")) {
                        values = EntityUtil.filterByDate(values, true);
                    }
                }

                for (GenericValue value : values) {
                    // add key and description with string expansion, ie expanding ${} stuff, passing locale explicitly to expand value string because it won't be found in the Entity
                    MapStack<String> localContext = MapStack.create(context);
                    // Rendering code might try to modify the GenericEntity instance,
                    // so we make a copy of it.
                    Map<String, Object> genericEntityClone = UtilGenerics.cast(value.clone());
                    localContext.push(genericEntityClone);

                    // expand with the new localContext, which is locale aware
                    String optionDesc = this.description.expandString(localContext, locale);

                    Object keyFieldObject = value.get(this.getKeyFieldName());
                    if (keyFieldObject == null) {
                        throw new IllegalArgumentException(
                                "The entity-options identifier (from key-name attribute, or default to the field name) ["
                                        + this.getKeyFieldName() + "], may not be a valid key field name for the entity ["
                                        + this.entityName + "].");
                    }
                    String keyFieldValue = keyFieldObject.toString();
                    optionValues.add(new OptionValue(keyFieldValue, optionDesc));
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, "Error getting entity options in form", module);
            }
        }

        @Override
        public OptionSource copy(ModelFormField modelFormField) {
            return new EntityOptions(this, modelFormField);
        }

        public boolean getCache() {
            return cache;
        }

        public List<EntityFinderUtil.ConditionExpr> getConstraintList() {
            return constraintList;
        }

        public FlexibleStringExpander getDescription() {
            return description;
        }

        public String getEntityName() {
            return entityName;
        }

        public String getFilterByDate() {
            return filterByDate;
        }

        public String getKeyFieldName() {
            if (UtilValidate.isNotEmpty(this.keyFieldName))
                return this.keyFieldName;
            return getModelFormField().getFieldName(); // get the modelFormField fieldName
        }

        public List<String> getOrderByList() {
            return orderByList;
        }
    }

    public static abstract class FieldInfoWithOptions extends FieldInfo {

        public static String getDescriptionForOptionKey(String key, List<OptionValue> allOptionValues) {
            if (UtilValidate.isEmpty(key))
                return "";

            if (UtilValidate.isEmpty(allOptionValues))
                return key;

            for (OptionValue optionValue : allOptionValues) {
                if (key.equals(optionValue.getKey())) {
                    return optionValue.getDescription();
                }
            }

            // if we get here we didn't find a match, just return the key
            return key;
        }

        private final FlexibleStringExpander noCurrentSelectedKey;
        private final List<OptionSource> optionSources;

        public FieldInfoWithOptions(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.noCurrentSelectedKey = FlexibleStringExpander.getInstance(element.getAttribute("no-current-selected-key"));
            // read all option and entity-options sub-elements, maintaining order
            ArrayList<OptionSource> optionSources = new ArrayList<OptionSource>();
            List<? extends Element> childElements = UtilXml.childElementList(element);
            if (childElements.size() > 0) {
                for (Element childElement : childElements) {
                    if ("option".equals(childElement.getTagName())) {
                        optionSources.add(new SingleOption(childElement, modelFormField));
                    } else if ("list-options".equals(childElement.getTagName())) {
                        optionSources.add(new ListOptions(childElement, modelFormField));
                    } else if ("entity-options".equals(childElement.getTagName())) {
                        optionSources.add(new EntityOptions(childElement, modelFormField));
                    }
                }
            } else {
                // this must be added or the multi-form select box options would not show up
                optionSources.add(new SingleOption("Y", " ", modelFormField));
            }
            optionSources.trimToSize();
            this.optionSources = Collections.unmodifiableList(optionSources);
        }

        // Copy constructor.
        protected FieldInfoWithOptions(FieldInfoWithOptions original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.noCurrentSelectedKey = original.noCurrentSelectedKey;
            if (original.optionSources.isEmpty()) {
                this.optionSources = original.optionSources;
            } else {
                List<OptionSource> optionSources = new ArrayList<OptionSource>(original.optionSources.size());
                for (OptionSource source : original.optionSources) {
                    optionSources.add(source.copy(modelFormField));
                }
                this.optionSources = Collections.unmodifiableList(optionSources);
            }
        }

        protected FieldInfoWithOptions(int fieldSource, int fieldType, List<OptionSource> optionSources) {
            super(fieldSource, fieldType, null);
            this.noCurrentSelectedKey = FlexibleStringExpander.getInstance("");
            this.optionSources = Collections.unmodifiableList(new ArrayList<OptionSource>(optionSources));
        }

        public FieldInfoWithOptions(int fieldSource, int fieldType, ModelFormField modelFormField) {
            super(fieldSource, fieldType, modelFormField);
            this.noCurrentSelectedKey = FlexibleStringExpander.getInstance("");
            this.optionSources = Collections.emptyList();
        }

        public List<OptionValue> getAllOptionValues(Map<String, Object> context, Delegator delegator) {
            List<OptionValue> optionValues = new LinkedList<OptionValue>();
            for (OptionSource optionSource : this.optionSources) {
                optionSource.addOptionValues(optionValues, context, delegator);
            }
            return optionValues;
        }

        public FlexibleStringExpander getNoCurrentSelectedKey() {
            return noCurrentSelectedKey;
        }

        public String getNoCurrentSelectedKey(Map<String, Object> context) {
            return this.noCurrentSelectedKey.expandString(context);
        }

        public List<OptionSource> getOptionSources() {
            return optionSources;
        }
    }

    /**
     * Models the &lt;file&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class FileField extends TextField {

        public FileField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
        }

        private FileField(FileField original, ModelFormField modelFormField) {
            super(original, modelFormField);
        }

        public FileField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, modelFormField);
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new FileField(this, modelFormField);
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderFileField(writer, context, this);
        }
    }
    
    /**
     * Models the &lt;include-form&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class FormField extends FieldInfo {
        private final FlexibleStringExpander formName;
        private final FlexibleStringExpander formLocation;

        public FormField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.formName = FlexibleStringExpander.getInstance(element.getAttribute("name"));
            this.formLocation = FlexibleStringExpander.getInstance(element.getAttribute("location"));
        }

        private FormField(FormField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.formName = original.formName;
            this.formLocation = original.formLocation;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new FormField(this, modelFormField);
        }

        public String getFormName(Map<String, Object> context) {
            return this.formName.expandString(context);
        }

        public FlexibleStringExpander getFormName() {
            return formName;
        }

        public String getFormLocation(Map<String, Object> context) {
            return this.formLocation.expandString(context);
        }

        public FlexibleStringExpander getFormLocation() {
            return formLocation;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            // Output format might not support menus, so make menu rendering optional.
            ModelForm modelForm = getModelForm(context);
            try {
                FormRenderer renderer = new FormRenderer(modelForm, formStringRenderer);
                renderer.render(writer, context);
            } catch (Exception e) {
                String errMsg = "Error rendering included form named [" + modelForm.getName() + "] at location [" + modelForm.getFormLocation() + "]: " + e.toString();
                Debug.logError(e, errMsg, module);
                throw new RuntimeException(errMsg + e);
            }
        }

        public ModelForm getModelForm(Map<String, Object> context) {
            String name = this.getFormName(context);
            String location = this.getFormLocation(context);
            ModelForm modelForm = null;
            try {
                org.apache.ofbiz.entity.model.ModelReader entityModelReader = ((org.apache.ofbiz.entity.Delegator)context.get("delegator")).getModelReader();
                org.apache.ofbiz.service.DispatchContext dispatchContext = ((org.apache.ofbiz.service.LocalDispatcher)context.get("dispatcher")).getDispatchContext();
                modelForm = FormFactory.getFormFromLocation(location, name, entityModelReader, dispatchContext);
            } catch (Exception e) {
                String errMsg = "Error rendering form named [" + name + "] at location [" + location + "]: ";
                Debug.logError(e, errMsg, module);
                throw new RuntimeException(errMsg + e);
            }
            return modelForm;
        }
    }
    
    /**
     * Models the &lt;include-grid&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class GridField extends FieldInfo {
        private final FlexibleStringExpander gridName;
        private final FlexibleStringExpander gridLocation;

        public GridField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.gridName = FlexibleStringExpander.getInstance(element.getAttribute("name"));
            this.gridLocation = FlexibleStringExpander.getInstance(element.getAttribute("location"));
        }

        private GridField(GridField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.gridName = original.gridName;
            this.gridLocation = original.gridLocation;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new GridField(this, modelFormField);
        }

        public String getGridName(Map<String, Object> context) {
            return this.gridName.expandString(context);
        }

        public FlexibleStringExpander getGridName() {
            return gridName;
        }

        public String getGridLocation(Map<String, Object> context) {
            return this.gridLocation.expandString(context);
        }

        public FlexibleStringExpander getGridLocation() {
            return gridLocation;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            // Output format might not support menus, so make menu rendering optional.
            ModelForm modelGrid = getModelGrid(context);
            try {
                FormRenderer renderer = new FormRenderer(modelGrid, formStringRenderer);
                renderer.render(writer, context);
            } catch (Exception e) {
                String errMsg = "Error rendering included grid named [" + modelGrid.getName() + "] at location [" + modelGrid.getFormLocation() + "]: " + e.toString();
                Debug.logError(e, errMsg, module);
                throw new RuntimeException(errMsg + e);
            }
        }

        public ModelForm getModelGrid(Map<String, Object> context) {
            String name = this.getGridName(context);
            String location = this.getGridLocation(context);
            ModelForm modelForm = null;
            try {
                org.apache.ofbiz.entity.model.ModelReader entityModelReader = ((org.apache.ofbiz.entity.Delegator)context.get("delegator")).getModelReader();
                org.apache.ofbiz.service.DispatchContext dispatchContext = ((org.apache.ofbiz.service.LocalDispatcher)context.get("dispatcher")).getDispatchContext();
                modelForm = GridFactory.getGridFromLocation(location, name, entityModelReader, dispatchContext);
            } catch (Exception e) {
                String errMsg = "Error rendering grid named [" + name + "] at location [" + location + "]: ";
                Debug.logError(e, errMsg, module);
                throw new RuntimeException(errMsg + e);
            }
            return modelForm;
        }
    }

    /**
     * Models the &lt;hidden&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class HiddenField extends FieldInfo {
        private final FlexibleStringExpander value;

        public HiddenField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.value = FlexibleStringExpander.getInstance(element.getAttribute("value"));
        }

        private HiddenField(HiddenField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.value = original.value;
        }

        public HiddenField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.HIDDEN, modelFormField);
            this.value = FlexibleStringExpander.getInstance("");
        }

        public HiddenField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.HIDDEN, modelFormField);
            this.value = FlexibleStringExpander.getInstance("");
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new HiddenField(this, modelFormField);
        }

        public FlexibleStringExpander getValue() {
            return value;
        }

        public String getValue(Map<String, Object> context) {
            if (UtilValidate.isNotEmpty(this.value)) {
                String valueEnc = this.value.expandString(context);
                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                if (simpleEncoder != null) {
                    valueEnc = simpleEncoder.encode(valueEnc);
                }
                return valueEnc;
            } else {
                return getModelFormField().getEntry(context);
            }
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderHiddenField(writer, context, this);
        }
    }

    /**
     * Models the &lt;hyperlink&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class HyperlinkField extends FieldInfo {

        private final boolean alsoHidden;
        private final FlexibleStringExpander description;
        private final Link link;

        public HyperlinkField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.alsoHidden = !"false".equals(element.getAttribute("also-hidden"));
            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
            // Backwards-compatible fix
            element.setAttribute("url-mode", element.getAttribute("target-type"));
            this.link = new Link(element);
        }

        private HyperlinkField(HyperlinkField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.alsoHidden = original.alsoHidden;
            this.description = original.description;
            this.link = original.link;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new HyperlinkField(this, modelFormField);
        }

        public boolean getAlsoHidden() {
            return this.alsoHidden;
        }

        public String getConfirmation(Map<String, Object> context) {
            String message = getConfirmationMsg(context);
            if (UtilValidate.isNotEmpty(message))
                return message;
            if (getRequestConfirmation()) {
                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message",
                        "${uiLabelMap.CommonConfirm}");
                return FlexibleStringExpander.expandString(defaultMessage, context);
            }
            return "";
        }

        public String getAlternate(Map<String, Object> context) {
            if (link.getImage() != null) {
                return link.getImage().getAlt(context);
            }
            return "";
        }

        public String getImageTitle(Map<String, Object> context) {
            if (link.getImage() != null) {
                return link.getImage().getTitleExdr().expandString(context);
            }
            return "";
        }

        public String getImageLocation(Map<String, Object> context) {
            if (link.getImage() != null) {
                return link.getImage().getSrc(context);
            }
            return "";
        }

        public String getConfirmationMsg(Map<String, Object> context) {
            return link.getConfirmationMsg(context);
        }

        public FlexibleStringExpander getConfirmationMsgExdr() {
            return link.getConfirmationMsgExdr();
        }

        public FlexibleStringExpander getDescription() {
            return description;
        }

        public String getDescription(Map<String, Object> context) {
            return this.description.expandString(context);
        }

        public boolean getRequestConfirmation() {
            return link.getRequestConfirmation();
        }

        public Link getLink() {
            return link;
        }

        public AutoEntityParameters getAutoEntityParameters() {
            return link.getAutoEntityParameters();
        }

        public AutoServiceParameters getAutoServiceParameters() {
            return link.getAutoServiceParameters();
        }

        public boolean getEncode() {
            return link.getEncode();
        }

        public boolean getFullPath() {
            return link.getFullPath();
        }

        public String getHeight() {
            return link.getHeight();
        }

        public String getId(Map<String, Object> context) {
            return link.getId(context);
        }

        public FlexibleStringExpander getIdExdr() {
            return link.getIdExdr();
        }

        public Image getImage() {
            return link.getImage();
        }

        public String getLinkType() {
            return link.getLinkType();
        }

        public String getName() {
            return link.getName();
        }

        public String getName(Map<String, Object> context) {
            return link.getName(context);
        }

        public FlexibleStringExpander getNameExdr() {
            return link.getNameExdr();
        }

        public List<Parameter> getParameterList() {
            return link.getParameterList();
        }
        
        public Map<String, String> getParameterMap(Map<String, Object> context, String defaultEntityName, String defaultServiceName) {
            return link.getParameterMap(context, defaultEntityName, defaultServiceName);
        }

        public Map<String, String> getParameterMap(Map<String, Object> context) {
            return link.getParameterMap(context);
        }

        public String getPrefix(Map<String, Object> context) {
            return link.getPrefix(context);
        }

        public FlexibleStringExpander getPrefixExdr() {
            return link.getPrefixExdr();
        }

        public boolean getSecure() {
            return link.getSecure();
        }

        public Integer getSize() {
            return link.getSize();
        }

        public String getStyle(Map<String, Object> context) {
            return link.getStyle(context);
        }

        public FlexibleStringExpander getStyleExdr() {
            return link.getStyleExdr();
        }

        public String getTarget(Map<String, Object> context) {
            return link.getTarget(context);
        }

        public FlexibleStringExpander getTargetExdr() {
            return link.getTargetExdr();
        }

        public String getTargetWindow(Map<String, Object> context) {
            return link.getTargetWindow(context);
        }

        public FlexibleStringExpander getTargetWindowExdr() {
            return link.getTargetWindowExdr();
        }

        public String getText(Map<String, Object> context) {
            return link.getText(context);
        }

        public FlexibleStringExpander getTextExdr() {
            return link.getTextExdr();
        }

        public String getUrlMode() {
            return link.getUrlMode();
        }

        public String getWidth() {
            return link.getWidth();
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderHyperlinkField(writer, context, this);
        }
    }

    /**
     * Models the &lt;ignored&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class IgnoredField extends FieldInfo {

        public IgnoredField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
        }

        private IgnoredField(IgnoredField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
        }

        public IgnoredField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.IGNORED, modelFormField);
        }

        public IgnoredField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.IGNORED, modelFormField);
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new IgnoredField(this, modelFormField);
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderIgnoredField(writer, context, this);
        }
    }

    /**
     * Models the &lt;image&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class ImageField extends FieldInfo {
        private final FlexibleStringExpander alternate;
        private final FlexibleStringExpander defaultValue;
        private final FlexibleStringExpander description;
        private final FlexibleStringExpander style;
        private final SubHyperlink subHyperlink;
        private final FlexibleStringExpander value;

        public ImageField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.alternate = FlexibleStringExpander.getInstance(element.getAttribute("alternate"));
            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
            this.style = FlexibleStringExpander.getInstance(element.getAttribute("style"));
            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
            if (subHyperlinkElement != null) {
                this.subHyperlink = new SubHyperlink(subHyperlinkElement, modelFormField);
            } else {
                this.subHyperlink = null;
            }
            this.value = FlexibleStringExpander.getInstance(element.getAttribute("value"));
        }

        public ImageField(ImageField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.alternate = original.alternate;
            this.defaultValue = original.defaultValue;
            this.description = original.description;
            this.style = original.style;
            if (original.subHyperlink != null) {
                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
            } else {
                this.subHyperlink = null;
            }
            this.value = original.value;
        }

        public ImageField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.IMAGE, modelFormField);
            this.alternate = FlexibleStringExpander.getInstance("");
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.description = FlexibleStringExpander.getInstance("");
            this.style = FlexibleStringExpander.getInstance("");
            this.subHyperlink = null;
            this.value = FlexibleStringExpander.getInstance("");
        }

        public ImageField(ModelFormField modelFormField) {
            this(FieldInfo.SOURCE_EXPLICIT, modelFormField);
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new ImageField(this, modelFormField);
        }

        public FlexibleStringExpander getAlternate() {
            return alternate;
        }

        public String getAlternate(Map<String, Object> context) {
            if (UtilValidate.isNotEmpty(this.alternate))
                return this.alternate.expandString(context);
            return "";
        }

        public FlexibleStringExpander getDefaultValue() {
            return defaultValue;
        }

        public String getDefaultValue(Map<String, Object> context) {
            if (this.defaultValue != null) {
                return this.defaultValue.expandString(context);
            } else {
                return "";
            }
        }

        public FlexibleStringExpander getDescription() {
            return description;
        }

        public String getDescription(Map<String, Object> context) {
            if (UtilValidate.isNotEmpty(this.description))
                return this.description.expandString(context);
            return "";
        }

        public FlexibleStringExpander getStyle() {
            return style;
        }

        public String getStyle(Map<String, Object> context) {
            if (UtilValidate.isNotEmpty(this.style))
                return this.style.expandString(context);
            return "";
        }

        public SubHyperlink getSubHyperlink() {
            return this.subHyperlink;
        }

        public FlexibleStringExpander getValue() {
            return value;
        }

        public String getValue(Map<String, Object> context) {
            if (UtilValidate.isNotEmpty(this.value))
                return this.value.expandString(context);
            return getModelFormField().getEntry(context);
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderImageField(writer, context, this);
        }
    }

    /**
     * Models the &lt;in-place-editor&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class InPlaceEditor {
        private final String cancelControl;
        private final String cancelText;
        private final String clickToEditText;
        private final String cols;
        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
        private final String fieldPostCreation;
        private final String formClassName;
        private final String highlightColor;
        private final String highlightEndColor;
        private final String hoverClassName;
        private final String htmlResponse;
        private final String loadingClassName;
        private final String loadingText;
        private final String okControl;
        private final String okText;
        private final String paramName;
        private final String rows;
        private final String savingClassName;
        private final String savingText;
        private final String submitOnBlur;
        private final String textAfterControls;
        private final String textBeforeControls;
        private final String textBetweenControls;
        private final String updateAfterRequestCall;
        private final FlexibleStringExpander url;

        public InPlaceEditor(Element element) {
            this.cancelControl = element.getAttribute("cancel-control");
            this.cancelText = element.getAttribute("cancel-text");
            this.clickToEditText = element.getAttribute("click-to-edit-text");
            this.fieldPostCreation = element.getAttribute("field-post-creation");
            this.formClassName = element.getAttribute("form-class-name");
            this.highlightColor = element.getAttribute("highlight-color");
            this.highlightEndColor = element.getAttribute("highlight-end-color");
            this.hoverClassName = element.getAttribute("hover-class-name");
            this.htmlResponse = element.getAttribute("html-response");
            this.loadingClassName = element.getAttribute("loading-class-name");
            this.loadingText = element.getAttribute("loading-text");
            this.okControl = element.getAttribute("ok-control");
            this.okText = element.getAttribute("ok-text");
            this.paramName = element.getAttribute("param-name");
            this.savingClassName = element.getAttribute("saving-class-name");
            this.savingText = element.getAttribute("saving-text");
            this.submitOnBlur = element.getAttribute("submit-on-blur");
            this.textBeforeControls = element.getAttribute("text-before-controls");
            this.textAfterControls = element.getAttribute("text-after-controls");
            this.textBetweenControls = element.getAttribute("text-between-controls");
            this.updateAfterRequestCall = element.getAttribute("update-after-request-call");
            Element simpleElement = UtilXml.firstChildElement(element, "simple-editor");
            if (simpleElement != null) {
                this.rows = simpleElement.getAttribute("rows");
                this.cols = simpleElement.getAttribute("cols");
            } else {
                this.rows = "";
                this.cols = "";
            }
            this.fieldMap = EntityFinderUtil.makeFieldMap(element);
            this.url = FlexibleStringExpander.getInstance(element.getAttribute("url"));
        }

        public String getCancelControl() {
            return this.cancelControl;
        }

        public String getCancelText() {
            return this.cancelText;
        }

        public String getClickToEditText() {
            return this.clickToEditText;
        }

        public String getCols() {
            return this.cols;
        }

        public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() {
            return fieldMap;
        }

        public Map<String, Object> getFieldMap(Map<String, Object> context) {
            Map<String, Object> inPlaceEditorContext = new HashMap<String, Object>();
            EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, inPlaceEditorContext);
            return inPlaceEditorContext;
        }

        public String getFieldPostCreation() {
            return this.fieldPostCreation;
        }

        public String getFormClassName() {
            return this.formClassName;
        }

        public String getHighlightColor() {
            return this.highlightColor;
        }

        public String getHighlightEndColor() {
            return this.highlightEndColor;
        }

        public String getHoverClassName() {
            return this.hoverClassName;
        }

        public String getHtmlResponse() {
            return this.htmlResponse;
        }

        public String getLoadingClassName() {
            return this.loadingClassName;
        }

        public String getLoadingText() {
            return this.loadingText;
        }

        public String getOkControl() {
            return this.okControl;
        }

        public String getOkText() {
            return this.okText;
        }

        public String getParamName() {
            return this.paramName;
        }

        public String getRows() {
            return this.rows;
        }

        public String getSavingClassName() {
            return this.savingClassName;
        }

        public String getSavingText() {
            return this.savingText;
        }

        public String getSubmitOnBlur() {
            return this.submitOnBlur;
        }

        public String getTextAfterControls() {
            return this.textAfterControls;
        }

        public String getTextBeforeControls() {
            return this.textBeforeControls;
        }

        public String getTextBetweenControls() {
            return this.textBetweenControls;
        }

        public String getUpdateAfterRequestCall() {
            return this.updateAfterRequestCall;
        }

        public FlexibleStringExpander getUrl() {
            return url;
        }

        public String getUrl(Map<String, Object> context) {
            if (this.url != null) {
                return this.url.expandString(context);
            } else {
                return "";
            }
        }
    }

    /**
     * Models the &lt;list-options&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class ListOptions extends OptionSource {
        private final FlexibleStringExpander description;
        private final FlexibleMapAccessor<Object> keyAcsr;
        private final FlexibleMapAccessor<List<? extends Object>> listAcsr;
        private final String listEntryName;

        public ListOptions(Element optionElement, ModelFormField modelFormField) {
            super(modelFormField);
            this.listEntryName = optionElement.getAttribute("list-entry-name");
            this.keyAcsr = FlexibleMapAccessor.getInstance(optionElement.getAttribute("key-name"));
            this.listAcsr = FlexibleMapAccessor.getInstance(optionElement.getAttribute("list-name"));
            this.description = FlexibleStringExpander.getInstance(optionElement.getAttribute("description"));
        }

        private ListOptions(ListOptions original, ModelFormField modelFormField) {
            super(modelFormField);
            this.listAcsr = original.listAcsr;
            this.listEntryName = original.listEntryName;
            this.keyAcsr = original.keyAcsr;
            this.description = original.description;
        }

        public ListOptions(String listName, String listEntryName, String keyName, String description,
                ModelFormField modelFormField) {
            super(modelFormField);
            this.listAcsr = FlexibleMapAccessor.getInstance(listName);
            this.listEntryName = listEntryName;
            this.keyAcsr = FlexibleMapAccessor.getInstance(keyName);
            this.description = FlexibleStringExpander.getInstance(description);
        }

        @Override
        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
            List<? extends Object> dataList = UtilGenerics.checkList(this.listAcsr.get(context));
            if (dataList != null && dataList.size() != 0) {
                for (Object data : dataList) {
                    Map<String, Object> localContext = new HashMap<String, Object>();
                    localContext.putAll(context);
                    if (UtilValidate.isNotEmpty(this.listEntryName)) {
                        localContext.put(this.listEntryName, data);
                    } else {
                        Map<String, Object> dataMap = UtilGenerics.checkMap(data);
                        localContext.putAll(dataMap);
                    }
                    Object keyObj = keyAcsr.get(localContext);
                    String key = null;
                    if (keyObj instanceof String) {
                        key = (String) keyObj;
                    } else {
                        try {
                            key = (String) ObjectType.simpleTypeConvert(keyObj, "String", null, null);
                        } catch (GeneralException e) {
                            String errMsg = "Could not convert field value for the field: [" + this.keyAcsr.toString()
                                    + "] to String for the value [" + keyObj + "]: " + e.toString();
                            Debug.logError(e, errMsg, module);
                        }
                    }
                    optionValues.add(new OptionValue(key, description.expandString(localContext)));
                }
            }
        }

        @Override
        public OptionSource copy(ModelFormField modelFormField) {
            return new ListOptions(this, modelFormField);
        }

        public FlexibleStringExpander getDescription() {
            return description;
        }

        public FlexibleMapAccessor<Object> getKeyAcsr() {
            return keyAcsr;
        }

        public FlexibleMapAccessor<List<? extends Object>> getListAcsr() {
            return listAcsr;
        }

        public String getListEntryName() {
            return listEntryName;
        }
    }

    /**
     * Models the &lt;lookup&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class LookupField extends TextField {
        private final String descriptionFieldName;
        private final String fadeBackground;
        private final FlexibleStringExpander formName;
        private final String initiallyCollapsed;
        private final String lookupHeight;
        private final String lookupPosition;
        private final String lookupPresentation;
        private final String lookupWidth;
        private final String showDescription;
        private final String targetParameter;

        public LookupField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.descriptionFieldName = element.getAttribute("description-field-name");
            this.fadeBackground = element.getAttribute("fade-background");
            this.formName = FlexibleStringExpander.getInstance(element.getAttribute("target-form-name"));
            this.initiallyCollapsed = element.getAttribute("initially-collapsed");
            this.lookupHeight = element.getAttribute("height");
            this.lookupPosition = element.getAttribute("position");
            this.lookupPresentation = element.getAttribute("presentation");
            this.lookupWidth = element.getAttribute("width");
            this.showDescription = element.getAttribute("show-description");
            this.targetParameter = element.getAttribute("target-parameter");
        }

        public LookupField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, modelFormField);
            this.descriptionFieldName = "";
            this.fadeBackground = "";
            this.formName = FlexibleStringExpander.getInstance("");
            this.initiallyCollapsed = "";
            this.lookupHeight = "";
            this.lookupPosition = "";
            this.lookupPresentation = "";
            this.lookupWidth = "";
            this.showDescription = "";
            this.targetParameter = "";
        }

        public LookupField(LookupField original, ModelFormField modelFormField) {
            super(original, modelFormField);
            this.descriptionFieldName = original.descriptionFieldName;
            this.fadeBackground = original.fadeBackground;
            this.formName = original.formName;
            this.initiallyCollapsed = original.initiallyCollapsed;
            this.lookupHeight = original.lookupHeight;
            this.lookupPosition = original.lookupPosition;
            this.lookupPresentation = original.lookupPresentation;
            this.lookupWidth = original.lookupWidth;
            this.showDescription = original.showDescription;
            this.targetParameter = original.targetParameter;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new LookupField(this, modelFormField);
        }

        public String getDescriptionFieldName() {
            return this.descriptionFieldName;
        }

        public String getFadeBackground() {
            return this.fadeBackground;
        }

        public FlexibleStringExpander getFormName() {
            return formName;
        }

        public String getFormName(Map<String, Object> context) {
            return this.formName.expandString(context);
        }

        //initially-collapsed status
        public boolean getInitiallyCollapsed() {
            return "true".equals(this.initiallyCollapsed);
        }

        public String getLookupHeight() {
            return this.lookupHeight;
        }

        public String getLookupPosition() {
            return this.lookupPosition;
        }

        public String getLookupPresentation() {
            return this.lookupPresentation;
        }

        public String getLookupWidth() {
            return this.lookupWidth;
        }

        public Boolean getShowDescription() {
            return UtilValidate.isEmpty(this.showDescription) ? null : "true".equals(this.showDescription);
        }

        public String getTargetParameter() {
            return targetParameter;
        }

        public List<String> getTargetParameterList() {
            List<String> paramList = new LinkedList<String>();
            if (UtilValidate.isNotEmpty(this.targetParameter)) {
                StringTokenizer stk = new StringTokenizer(this.targetParameter, ", ");
                while (stk.hasMoreTokens()) {
                    paramList.add(stk.nextToken());
                }
            }
            return paramList;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderLookupField(writer, context, this);
        }
    }

    /**
     * Models the &lt;include-menu&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class MenuField extends FieldInfo {
        private final FlexibleStringExpander menuName;
        private final FlexibleStringExpander menuLocation;

        public MenuField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.menuName = FlexibleStringExpander.getInstance(element.getAttribute("name"));
            this.menuLocation = FlexibleStringExpander.getInstance(element.getAttribute("location"));
        }

        private MenuField(MenuField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.menuName = original.menuName;
            this.menuLocation = original.menuLocation;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new MenuField(this, modelFormField);
        }

        public String getMenuName(Map<String, Object> context) {
            return this.menuName.expandString(context);
        }

        public FlexibleStringExpander getMenuName() {
            return menuName;
        }

        public String getMenuLocation(Map<String, Object> context) {
            return this.menuLocation.expandString(context);
        }

        public FlexibleStringExpander getMenuLocation() {
            return menuLocation;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            // Output format might not support menus, so make menu rendering optional.
            MenuStringRenderer menuStringRenderer = (MenuStringRenderer) context.get("menuStringRenderer");
            if (menuStringRenderer == null) {
                Debug.logVerbose("MenuStringRenderer instance not found in rendering context, menu not rendered.", module);
                return;
            }
            ModelMenu modelMenu = getModelMenu(context);
            modelMenu.renderMenuString(writer, context, menuStringRenderer);
        }

        public ModelMenu getModelMenu(Map<String, Object> context) {
            String name = this.getMenuName(context);
            String location = this.getMenuLocation(context);
            ModelMenu modelMenu = null;
            try {
                modelMenu = MenuFactory.getMenuFromLocation(location, name);
            } catch (Exception e) {
                String errMsg = "Error rendering menu named [" + name + "] at location [" + location + "]: ";
                Debug.logError(e, errMsg, module);
                throw new RuntimeException(errMsg + e);
            }
            return modelMenu;
        }
    }

    public static abstract class OptionSource {

        private final ModelFormField modelFormField;

        protected OptionSource(ModelFormField modelFormField) {
            this.modelFormField = modelFormField;
        }

        public abstract void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator);

        public abstract OptionSource copy(ModelFormField modelFormField);

        public ModelFormField getModelFormField() {
            return modelFormField;
        }
    }

    public static class OptionValue {
        private final String description;
        private final String key;

        public OptionValue(String key, String description) {
            this.key = key;
            this.description = description;
        }

        public String getDescription() {
            return description;
        }

        public String getKey() {
            return key;
        }
    }

    /**
     * Models the &lt;password&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class PasswordField extends TextField {

        public PasswordField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
        }

        public PasswordField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, modelFormField);
        }

        private PasswordField(PasswordField original, ModelFormField modelFormField) {
            super(original, modelFormField);
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new PasswordField(this, modelFormField);
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderPasswordField(writer, context, this);
        }
    }

    /**
     * Models the &lt;radio&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class RadioField extends FieldInfoWithOptions {

        public RadioField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
        }

        public RadioField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.RADIO, modelFormField);
        }

        public RadioField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.RADIO, modelFormField);
        }

        private RadioField(RadioField original, ModelFormField modelFormField) {
            super(original, modelFormField);
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new RadioField(this, modelFormField);
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderRadioField(writer, context, this);
        }
    }

    /**
     * Models the &lt;range-find&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class RangeFindField extends TextField {
        private final String defaultOptionFrom;
        private final String defaultOptionThru;

        public RangeFindField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.defaultOptionFrom = element.getAttribute("default-option-from");
            this.defaultOptionThru = element.getAttribute("default-option-thru");
        }

        public RangeFindField(int fieldSource, int size, ModelFormField modelFormField) {
            super(fieldSource, size, null, modelFormField, FieldInfo.RANGEQBE);
            this.defaultOptionFrom = "greaterThanEqualTo";
            this.defaultOptionThru = "lessThanEqualTo";
        }

        private RangeFindField(RangeFindField original, ModelFormField modelFormField) {
            super(original, modelFormField);
            this.defaultOptionFrom = original.defaultOptionFrom;
            this.defaultOptionThru = original.defaultOptionThru;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new RangeFindField(this, modelFormField);
        }

        public String getDefaultOptionFrom() {
            return this.defaultOptionFrom;
        }

        public String getDefaultOptionThru() {
            return this.defaultOptionThru;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderRangeFindField(writer, context, this);
        }
    }

    /**
     * Models the &lt;reset&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class ResetField extends FieldInfo {

        public ResetField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
        }

        public ResetField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.RESET, modelFormField);
        }

        public ResetField(ModelFormField modelFormField) {
            super(FieldInfo.SOURCE_EXPLICIT, FieldInfo.RESET, modelFormField);
        }

        private ResetField(ResetField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new ResetField(this, modelFormField);
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderResetField(writer, context, this);
        }
    }
    
    /**
     * Models the &lt;include-screen&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class ScreenField extends FieldInfo {
        private final FlexibleStringExpander screenName;
        private final FlexibleStringExpander screenLocation;

        public ScreenField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.screenName = FlexibleStringExpander.getInstance(element.getAttribute("name"));
            this.screenLocation = FlexibleStringExpander.getInstance(element.getAttribute("location"));
        }

        private ScreenField(ScreenField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.screenName = original.screenName;
            this.screenLocation = original.screenLocation;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new ScreenField(this, modelFormField);
        }

        public String getScreenName(Map<String, Object> context) {
            return this.screenName.expandString(context);
        }

        public FlexibleStringExpander getScreenName() {
            return screenName;
        }

        public String getScreenLocation(Map<String, Object> context) {
            return this.screenLocation.expandString(context);
        }

        public FlexibleStringExpander getScreenLocation() {
            return screenLocation;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            String name = this.getScreenName(context);
            String location = this.getScreenLocation(context);
            try {
                ScreenRenderer renderer = (ScreenRenderer)context.get("screens");
                if (renderer != null) {
                    @SuppressWarnings("unchecked")
                    MapStack<String> mapStack = (MapStack)UtilGenerics.cast(context);
                    ScreenRenderer subRenderer = new ScreenRenderer(writer, mapStack, renderer.getScreenStringRenderer());
                    writer.append(subRenderer.render(location, name));
                }
            } catch (Exception e) {
                String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
                Debug.logError(e, errMsg, module);
                throw new RuntimeException(errMsg + e);
            }
        }
    }

    /**
     * Models the &lt;option&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class SingleOption extends OptionSource {
        private final FlexibleStringExpander description;
        private final FlexibleStringExpander key;

        public SingleOption(Element optionElement, ModelFormField modelFormField) {
            super(modelFormField);
            this.key = FlexibleStringExpander.getInstance(optionElement.getAttribute("key"));
            this.description = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(optionElement.getAttribute("description"),
                    optionElement.getAttribute("key")));
        }

        private SingleOption(SingleOption original, ModelFormField modelFormField) {
            super(modelFormField);
            this.key = original.key;
            this.description = original.description;
        }

        public SingleOption(String key, String description, ModelFormField modelFormField) {
            super(modelFormField);
            this.key = FlexibleStringExpander.getInstance(key);
            this.description = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(description, key));
        }

        @Override
        public void addOptionValues(List<OptionValue> optionValues, Map<String, Object> context, Delegator delegator) {
            optionValues.add(new OptionValue(key.expandString(context), description.expandString(context)));
        }

        @Override
        public OptionSource copy(ModelFormField modelFormField) {
            return new SingleOption(this, modelFormField);
        }

        public FlexibleStringExpander getDescription() {
            return description;
        }

        public FlexibleStringExpander getKey() {
            return key;
        }
    }

    /**
     * Models the &lt;sub-hyperlink&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class SubHyperlink {
        private final FlexibleStringExpander description;
        private final FlexibleStringExpander useWhen;
        private final Link link;
        private final ModelFormField modelFormField;

        public SubHyperlink(Element element, ModelFormField modelFormField) {
            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
            this.useWhen = FlexibleStringExpander.getInstance(element.getAttribute("use-when"));
            // Backwards compatible support
            element.setAttribute("style", element.getAttribute("link-style"));
            element.setAttribute("url-mode", element.getAttribute("target-type"));
            this.link = new Link(element);
            this.modelFormField = modelFormField;
        }

        public SubHyperlink(SubHyperlink original, ModelFormField modelFormField) {
            this.description = original.description;
            this.useWhen = original.useWhen;
            this.link = original.link;
            this.modelFormField = modelFormField;
        }

        public AutoEntityParameters getAutoEntityParameters() {
            return link.getAutoEntityParameters();
        }

        public AutoServiceParameters getAutoServiceParameters() {
            return link.getAutoServiceParameters();
        }

        public boolean getEncode() {
            return link.getEncode();
        }

        public boolean getFullPath() {
            return link.getFullPath();
        }

        public String getHeight() {
            return link.getHeight();
        }

        public String getId(Map<String, Object> context) {
            return link.getId(context);
        }

        public FlexibleStringExpander getIdExdr() {
            return link.getIdExdr();
        }

        public Image getImage() {
            return link.getImage();
        }

        public String getLinkType() {
            return link.getLinkType();
        }

        public String getName() {
            return link.getName();
        }

        public String getName(Map<String, Object> context) {
            return link.getName(context);
        }

        public FlexibleStringExpander getNameExdr() {
            return link.getNameExdr();
        }

        public List<Parameter> getParameterList() {
            return link.getParameterList();
        }

        public Map<String, String> getParameterMap(Map<String, Object> context, String defaultEntityName, String defaultServiceName) {
            return link.getParameterMap(context, defaultEntityName, defaultServiceName);
        }
        
        public Map<String, String> getParameterMap(Map<String, Object> context) {
            return link.getParameterMap(context);
        }

        public String getPrefix(Map<String, Object> context) {
            return link.getPrefix(context);
        }

        public FlexibleStringExpander getPrefixExdr() {
            return link.getPrefixExdr();
        }

        public boolean getSecure() {
            return link.getSecure();
        }

        public Integer getSize() {
            return link.getSize();
        }

        public String getStyle(Map<String, Object> context) {
            return link.getStyle(context);
        }

        public FlexibleStringExpander getStyleExdr() {
            return link.getStyleExdr();
        }

        public String getTarget(Map<String, Object> context) {
            return link.getTarget(context);
        }

        public FlexibleStringExpander getTargetExdr() {
            return link.getTargetExdr();
        }

        public String getTargetWindow(Map<String, Object> context) {
            return link.getTargetWindow(context);
        }

        public FlexibleStringExpander getTargetWindowExdr() {
            return link.getTargetWindowExdr();
        }

        public String getText(Map<String, Object> context) {
            return link.getText(context);
        }

        public FlexibleStringExpander getTextExdr() {
            return link.getTextExdr();
        }

        public String getUrlMode() {
            return link.getUrlMode();
        }

        public String getWidth() {
            return link.getWidth();
        }

        public FlexibleStringExpander getDescription() {
            return description;
        }

        public String getDescription(Map<String, Object> context) {
            return description.expandString(context);
        }

        public FlexibleStringExpander getUseWhen() {
            return useWhen;
        }

        public Link getLink() {
            return link;
        }

        public String getUseWhen(Map<String, Object> context) {
            return this.useWhen.expandString(context);
        }

        public ModelFormField getModelFormField() {
            return modelFormField;
        }

        public boolean shouldUse(Map<String, Object> context) {
            boolean shouldUse = true;
            String useWhen = this.getUseWhen(context);
            if (UtilValidate.isNotEmpty(useWhen)) {
                try {
                    Object retVal = GroovyUtil.eval(StringUtil.convertOperatorSubstitutions(useWhen),context);
                    boolean condTrue = false;

                    // retVal should be a Boolean, if not something weird is up...
                    if (retVal instanceof Boolean) {
                        Boolean boolVal = (Boolean) retVal;
                        shouldUse = boolVal.booleanValue();
                    } else {
                        throw new IllegalArgumentException("Return value from target condition eval was not a Boolean: "
                                + retVal.getClass().getName() + " [" + retVal + "]");
                    }
                } catch (CompilationFailedException e) {
                    String errmsg = "Error evaluating Groovy target conditions";
                    Debug.logError(e, errmsg, module);
                    throw new IllegalArgumentException(errmsg);
                }
            }
            return shouldUse;
        }
    }

    public boolean shouldIgnore(Map<String, Object> context) {
        boolean shouldIgnore = true;
        String ignoreWhen = this.getIgnoreWhen(context);
        if (UtilValidate.isEmpty(ignoreWhen)) return false;

        try {
            Object retVal = GroovyUtil.eval(StringUtil.convertOperatorSubstitutions(ignoreWhen),context);
            boolean condTrue = false;

            if (retVal instanceof Boolean) {
                shouldIgnore =(Boolean) retVal;
            } else {
                throw new IllegalArgumentException("Return value from ignore-when condition eval was not a Boolean: "  + (retVal != null ? retVal.getClass().getName() : "null") + " [" + retVal + "] on the field " + this.name + " of form " + this.modelForm.getName());
            }

        } catch (CompilationFailedException e) {
            String errMsg = "Error evaluating BeanShell ignore-when condition [" + ignoreWhen + "] on the field " + this.name + " of form " + this.modelForm.getName() + ": " + e.toString();
            Debug.logError(e, errMsg, module);
            throw new IllegalArgumentException(errMsg);
        }

        return shouldIgnore;

    }

    /**
     * Models the &lt;submit&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class SubmitField extends FieldInfo {
        private final FlexibleStringExpander backgroundSubmitRefreshTargetExdr;
        private final String buttonType;
        private final FlexibleStringExpander confirmationMsgExdr;
        private final FlexibleStringExpander imageLocation;
        private final boolean requestConfirmation;

        public SubmitField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.backgroundSubmitRefreshTargetExdr = FlexibleStringExpander.getInstance(element
                    .getAttribute("background-submit-refresh-target"));
            this.buttonType = element.getAttribute("button-type");
            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message"));
            this.imageLocation = FlexibleStringExpander.getInstance(element.getAttribute("image-location"));
            this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation"));
        }

        public SubmitField(int fieldInfo, ModelFormField modelFormField) {
            super(fieldInfo, FieldInfo.SUBMIT, modelFormField);
            this.backgroundSubmitRefreshTargetExdr = FlexibleStringExpander.getInstance("");
            this.buttonType = "";
            this.confirmationMsgExdr = FlexibleStringExpander.getInstance("");
            this.imageLocation = FlexibleStringExpander.getInstance("");
            this.requestConfirmation = false;
        }

        public SubmitField(ModelFormField modelFormField) {
            this(FieldInfo.SOURCE_EXPLICIT, modelFormField);
        }

        private SubmitField(SubmitField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.buttonType = original.buttonType;
            this.imageLocation = original.imageLocation;
            this.backgroundSubmitRefreshTargetExdr = original.backgroundSubmitRefreshTargetExdr;
            this.requestConfirmation = original.requestConfirmation;
            this.confirmationMsgExdr = original.confirmationMsgExdr;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new SubmitField(this, modelFormField);
        }

        public String getBackgroundSubmitRefreshTarget(Map<String, Object> context) {
            return this.backgroundSubmitRefreshTargetExdr.expandString(context);
        }

        public FlexibleStringExpander getBackgroundSubmitRefreshTargetExdr() {
            return backgroundSubmitRefreshTargetExdr;
        }

        public String getButtonType() {
            return buttonType;
        }

        public String getConfirmation(Map<String, Object> context) {
            String message = getConfirmationMsg(context);
            if (UtilValidate.isNotEmpty(message))
                return message;
            else if (getRequestConfirmation()) {
                String defaultMessage = UtilProperties.getPropertyValue("general", "default.confirmation.message",
                        "${uiLabelMap.CommonConfirm}");
                return FlexibleStringExpander.expandString(defaultMessage, context);
            }
            return "";
        }

        public String getConfirmationMsg(Map<String, Object> context) {
            return this.confirmationMsgExdr.expandString(context);
        }

        public FlexibleStringExpander getConfirmationMsgExdr() {
            return confirmationMsgExdr;
        }

        public FlexibleStringExpander getImageLocation() {
            return imageLocation;
        }

        public String getImageLocation(Map<String, Object> context) {
            return this.imageLocation.expandString(context);
        }

        public boolean getRequestConfirmation() {
            return this.requestConfirmation;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderSubmitField(writer, context, this);
        }
    }

    /**
     * Models the &lt;textarea&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class TextareaField extends FieldInfo {
        private final int cols;
        private final FlexibleStringExpander defaultValue;
        private final boolean readOnly;
        private final int rows;
        private final FlexibleStringExpander visualEditorButtons;
        private final boolean visualEditorEnable;
        private final Integer maxlength;

        public TextareaField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            int cols = 60;
            String colsStr = element.getAttribute("cols");
            if (!colsStr.isEmpty()) {
                try {
                    cols = Integer.parseInt(colsStr);
                } catch (NumberFormatException e) {
                    Debug.logError("Could not parse the size value of the text element: [" + colsStr
                            + "], setting to default of " + cols, module);
                }
            }
            this.cols = cols;
            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
            this.readOnly = "true".equals(element.getAttribute("read-only"));
            int rows = 2;
            String rowsStr = element.getAttribute("rows");
            if (!rowsStr.isEmpty()) {
                try {
                    rows = Integer.parseInt(rowsStr);
                } catch (NumberFormatException e) {
                    Debug.logError("Could not parse the size value of the text element: [" + rowsStr
                            + "], setting to default of " + rows, module);
                }
            }
            this.rows = rows;
            Integer maxlength = null;
            String maxlengthStr = element.getAttribute("maxlength");
            if (!maxlengthStr.isEmpty()) {
                try {
                    maxlength = Integer.valueOf(maxlengthStr);
                } catch (NumberFormatException e) {
                    Debug.logError("Could not parse the max-length value of the text element: [" + maxlengthStr
                            + "], setting to null; default of no maxlength will be used", module);
                }
            }
            this.maxlength = maxlength;
            this.visualEditorButtons = FlexibleStringExpander.getInstance(element.getAttribute("visual-editor-buttons"));
            this.visualEditorEnable = "true".equals(element.getAttribute("visual-editor-enable"));
        }

        public TextareaField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.TEXTAREA, modelFormField);
            this.cols = 60;
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.readOnly = false;
            this.rows = 2;
            this.maxlength = null;
            this.visualEditorButtons = FlexibleStringExpander.getInstance("");
            this.visualEditorEnable = false;
        }

        public TextareaField(ModelFormField modelFormField) {
            this(FieldInfo.SOURCE_EXPLICIT, modelFormField);
        }

        private TextareaField(TextareaField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.defaultValue = original.defaultValue;
            this.visualEditorEnable = original.visualEditorEnable;
            this.visualEditorButtons = original.visualEditorButtons;
            this.readOnly = original.readOnly;
            this.cols = original.cols;
            this.rows = original.rows;
            this.maxlength = original.maxlength;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new TextareaField(this, modelFormField);
        }

        public int getCols() {
            return cols;
        }

        public FlexibleStringExpander getDefaultValue() {
            return defaultValue;
        }

        public String getDefaultValue(Map<String, Object> context) {
            if (this.defaultValue != null) {
                return this.defaultValue.expandString(context);
            } else {
                return "";
            }
        }

        public int getRows() { return rows; }

        public Integer getMaxlength() {
            return maxlength;
        }

        public FlexibleStringExpander getVisualEditorButtons() {
            return visualEditorButtons;
        }

        public String getVisualEditorButtons(Map<String, Object> context) {
            return this.visualEditorButtons.expandString(context);
        }

        public boolean getVisualEditorEnable() {
            return this.visualEditorEnable;
        }

        public boolean isReadOnly() {
            return readOnly;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderTextareaField(writer, context, this);
        }
    }

    /**
     * Models the &lt;text&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class TextField extends FieldInfo {
        private final boolean clientAutocompleteField;
        private final FlexibleStringExpander defaultValue;
        private final boolean disabled;
        private final String mask;
        private final Integer maxlength;
        private final FlexibleStringExpander placeholder;
        private final boolean readonly;
        private final int size;
        private final SubHyperlink subHyperlink;

        public TextField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            this.clientAutocompleteField = !"false".equals(element.getAttribute("client-autocomplete-field"));
            this.defaultValue = FlexibleStringExpander.getInstance(element.getAttribute("default-value"));
            this.disabled = "true".equals(element.getAttribute("disabled"));
            this.mask = element.getAttribute("mask");
            Integer maxlength = null;
            String maxlengthStr = element.getAttribute("maxlength");
            if (!maxlengthStr.isEmpty()) {
                try {
                    maxlength = Integer.valueOf(maxlengthStr);
                } catch (NumberFormatException e) {
                    Debug.logError("Could not parse the maxlength value of the text element: [" + maxlengthStr
                            + "], setting to null; default of no maxlength will be used", module);
                }
            }
            this.maxlength = maxlength;
            this.placeholder = FlexibleStringExpander.getInstance(element.getAttribute("placeholder"));
            this.readonly = "true".equals(element.getAttribute("read-only"));
            int size = 25;
            String sizeStr = element.getAttribute("size");
            if (!sizeStr.isEmpty()) {
                try {
                    size = Integer.parseInt(sizeStr);
                } catch (NumberFormatException e) {
                    Debug.logError("Could not parse the size value of the text element: [" + sizeStr
                            + "], setting to the default of " + size, module);
                }
            }
            this.size = size;
            Element subHyperlinkElement = UtilXml.firstChildElement(element, "sub-hyperlink");
            if (subHyperlinkElement != null) {
                this.subHyperlink = new SubHyperlink(subHyperlinkElement, this.getModelFormField());
            } else {
                this.subHyperlink = null;
            }
        }

        protected TextField(int fieldSource, int size, Integer maxlength, ModelFormField modelFormField, int fieldType) {
            super(fieldSource, fieldType == -1 ? FieldInfo.TEXT : fieldType, modelFormField);
            this.clientAutocompleteField = true;
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.disabled = false;
            this.mask = "";
            this.maxlength = maxlength;
            this.placeholder = FlexibleStringExpander.getInstance("");
            this.readonly = false;
            this.size = size;   
            this.subHyperlink = null;
        }
        
        protected TextField(int fieldSource, int size, Integer maxlength, ModelFormField modelFormField) {
            super(fieldSource, FieldInfo.TEXT, modelFormField);
            this.clientAutocompleteField = true;
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.disabled = false;
            this.mask = "";
            this.maxlength = maxlength;
            this.placeholder = FlexibleStringExpander.getInstance("");
            this.readonly = false;
            this.size = size;
            this.subHyperlink = null;
        }

        private TextField(int fieldSource, int fieldType, ModelFormField modelFormField) {
            super(fieldSource, fieldType, modelFormField);
            this.clientAutocompleteField = true;
            this.defaultValue = FlexibleStringExpander.getInstance("");
            this.disabled = false;
            this.mask = "";
            this.maxlength = null;
            this.placeholder = FlexibleStringExpander.getInstance("");
            this.readonly = false;
            this.size = 25;
            this.subHyperlink = null;
        }

        public TextField(int fieldSource, ModelFormField modelFormField) {
            this(fieldSource, FieldInfo.TEXT, modelFormField);
        }

        public TextField(ModelFormField modelFormField) {
            this(FieldInfo.SOURCE_EXPLICIT, FieldInfo.TEXT, modelFormField);
        }

        protected TextField(TextField original, ModelFormField modelFormField) {
            super(original.getFieldSource(), original.getFieldType(), modelFormField);
            this.clientAutocompleteField = original.clientAutocompleteField;
            this.defaultValue = original.defaultValue;
            this.mask = original.mask;
            this.placeholder = original.placeholder;
            this.size = original.size;
            this.maxlength = original.maxlength;
            this.disabled = original.disabled;
            this.readonly = original.readonly;
            if (original.subHyperlink != null) {
                this.subHyperlink = new SubHyperlink(original.subHyperlink, modelFormField);
            } else {
                this.subHyperlink = null;
            }
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new TextField(this, modelFormField);
        }

        public boolean getClientAutocompleteField() {
            return this.clientAutocompleteField;
        }

        public FlexibleStringExpander getDefaultValue() {
            return defaultValue;
        }

        public String getDefaultValue(Map<String, Object> context) {
            if (this.defaultValue != null) {
                return this.defaultValue.expandString(context);
            } else {
                return "";
            }
        }

        public boolean getDisabled() {
            return this.disabled;
        }

        public String getMask() {
            return this.mask;
        }

        public Integer getMaxlength() {
            return maxlength;
        }

        public FlexibleStringExpander getPlaceholder() {
            return placeholder;
        }

        public String getPlaceholder(Map<String, Object> context) {
            return this.placeholder.expandString(context);
        }

        public boolean getReadonly() {
            return this.readonly;
        }

        public int getSize() {
            return size;
        }

        public SubHyperlink getSubHyperlink() {
            return this.subHyperlink;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderTextField(writer, context, this);
        }
    }

    /**
     * Models the &lt;text-find&gt; element.
     * 
     * @see <code>widget-form.xsd</code>
     */
    public static class TextFindField extends TextField {
        private final String defaultOption;
        private final boolean hideIgnoreCase;
        private final boolean hideOptions;
        private final boolean ignoreCase;

        public TextFindField(Element element, ModelFormField modelFormField) {
            super(element, modelFormField);
            if (element.hasAttribute("default-option")) {
                this.defaultOption = element.getAttribute("default-option");
            } else {
                this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains");
            }
            this.hideIgnoreCase = "true".equals(element.getAttribute("hide-options"))
                    || "ignore-case".equals(element.getAttribute("hide-options")) ? true : false;
            this.hideOptions = "true".equals(element.getAttribute("hide-options"))
                    || "options".equals(element.getAttribute("hide-options")) ? true : false;
            this.ignoreCase = "true".equals(element.getAttribute("ignore-case"));
        }

        public TextFindField(int fieldSource, int size, Integer maxlength, ModelFormField modelFormField) {
            super(fieldSource, size, maxlength, modelFormField);
            this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains");
            this.hideIgnoreCase = false;
            this.hideOptions = false;
            this.ignoreCase = true;
        }

        public TextFindField(int fieldSource, ModelFormField modelFormField) {
            super(fieldSource, modelFormField);
            this.defaultOption = UtilProperties.getPropertyValue("widget", "widget.form.defaultTextFindOption", "contains");
            this.hideIgnoreCase = false;
            this.hideOptions = false;
            this.ignoreCase = true;
        }

        private TextFindField(TextFindField original, ModelFormField modelFormField) {
            super(original, modelFormField);
            this.ignoreCase = original.ignoreCase;
            this.hideIgnoreCase = original.hideIgnoreCase;
            this.defaultOption = original.defaultOption;
            this.hideOptions = original.hideOptions;
        }

        @Override
        public void accept(ModelFieldVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        @Override
        public FieldInfo copy(ModelFormField modelFormField) {
            return new TextFindField(this, modelFormField);
        }

        public String getDefaultOption() {
            return this.defaultOption;
        }

        public String getDefaultOption(Map<String, Object> context) {
            String defaultOption = getDefaultOption();

            Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"), String.class, Object.class);
            if (UtilValidate.isNotEmpty(parameters)) {
                String fieldName = this.getModelFormField().getName();
                if (parameters.containsKey(fieldName)) {
                    defaultOption = (String) parameters.get(fieldName.concat("_op"));
                }
            }
            return defaultOption;
        }

        public boolean getHideIgnoreCase() {
            return this.hideIgnoreCase;
        }

        public boolean getHideOptions() {
            return this.hideOptions;
        }

        public boolean getIgnoreCase() {
            return this.ignoreCase;
        }

        public boolean getIgnoreCase(Map<String, Object> context) {
            Boolean ignoreCase = getIgnoreCase();

            Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"), String.class, Object.class);
            if (UtilValidate.isNotEmpty(parameters)) {
                String fieldName = this.getModelFormField().getName();
                if (parameters.containsKey(fieldName)) {
                    ignoreCase = "Y".equals((String) parameters.get(fieldName.concat("_ic")));
                }
            }
            return ignoreCase;
        }

        @Override
        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
                throws IOException {
            formStringRenderer.renderTextFindField(writer, context, this);
        }
    }
}
