diff --git a/applications/content/src/org/ofbiz/content/cms/CmsEvents.java b/applications/content/src/org/ofbiz/content/cms/CmsEvents.java
index 6b21bee..6d403b7 100644
--- a/applications/content/src/org/ofbiz/content/cms/CmsEvents.java
+++ b/applications/content/src/org/ofbiz/content/cms/CmsEvents.java
@@ -47,9 +47,9 @@
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.webapp.control.RequestHandler;
 import org.ofbiz.webapp.website.WebSiteWorker;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.MacroFormRenderer;
-import org.ofbiz.widget.screen.ScreenRenderer;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.macro.MacroFormRenderer;
 
 import freemarker.template.TemplateException;
 
diff --git a/applications/content/src/org/ofbiz/content/content/ContentWorker.java b/applications/content/src/org/ofbiz/content/content/ContentWorker.java
index 3f7d96c..2b57db8 100644
--- a/applications/content/src/org/ofbiz/content/content/ContentWorker.java
+++ b/applications/content/src/org/ofbiz/content/content/ContentWorker.java
@@ -69,7 +69,7 @@
 /**
  * ContentWorker Class
  */
-public class ContentWorker implements org.ofbiz.widget.ContentWorkerInterface {
+public class ContentWorker implements org.ofbiz.widget.content.ContentWorkerInterface {
 
     public static final String module = ContentWorker.class.getName();
 
diff --git a/applications/content/src/org/ofbiz/content/data/DataResourceWorker.java b/applications/content/src/org/ofbiz/content/data/DataResourceWorker.java
index d4f7f4b..876414f 100644
--- a/applications/content/src/org/ofbiz/content/data/DataResourceWorker.java
+++ b/applications/content/src/org/ofbiz/content/data/DataResourceWorker.java
@@ -76,11 +76,11 @@
 import org.ofbiz.entity.util.EntityUtilProperties;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.widget.screen.MacroScreenRenderer;
-import org.ofbiz.widget.screen.ModelScreen;
-import org.ofbiz.widget.screen.ScreenFactory;
-import org.ofbiz.widget.screen.ScreenRenderer;
-import org.ofbiz.widget.screen.ScreenStringRenderer;
+import org.ofbiz.widget.model.ModelScreen;
+import org.ofbiz.widget.model.ScreenFactory;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.macro.MacroScreenRenderer;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
@@ -90,7 +90,7 @@
 /**
  * DataResourceWorker Class
  */
-public class DataResourceWorker  implements org.ofbiz.widget.DataResourceWorkerInterface {
+public class DataResourceWorker  implements org.ofbiz.widget.content.DataResourceWorkerInterface {
 
     public static final String module = DataResourceWorker.class.getName();
     public static final String err_resource = "ContentErrorUiLabels";
diff --git a/applications/content/src/org/ofbiz/content/output/OutputServices.java b/applications/content/src/org/ofbiz/content/output/OutputServices.java
index 1f9b1f8..f6755dd 100644
--- a/applications/content/src/org/ofbiz/content/output/OutputServices.java
+++ b/applications/content/src/org/ofbiz/content/output/OutputServices.java
@@ -63,9 +63,9 @@
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.webapp.view.ApacheFopWorker;
-import org.ofbiz.widget.fo.FoFormRenderer;
-import org.ofbiz.widget.fo.FoScreenRenderer;
-import org.ofbiz.widget.screen.ScreenRenderer;
+import org.ofbiz.widget.renderer.fo.FoFormRenderer;
+import org.ofbiz.widget.renderer.fo.FoScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
 
 
 /**
diff --git a/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyQuestions.groovy b/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyQuestions.groovy
index e5d1ad2..53fa09f 100644
--- a/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyQuestions.groovy
+++ b/applications/content/webapp/content/WEB-INF/actions/survey/EditSurveyQuestions.groovy
@@ -20,7 +20,7 @@
 import org.ofbiz.entity.*
 import org.ofbiz.entity.condition.*
 import org.ofbiz.base.util.*
-import org.ofbiz.widget.html.*
+import org.ofbiz.widget.renderer.html.*
 
 surveyQuestionId = parameters.surveyQuestionId;
 context.surveyQuestionId = surveyQuestionId;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunActualComponents.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunActualComponents.groovy
index 49e6897..8163a60 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunActualComponents.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunActualComponents.groovy
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import org.ofbiz.widget.html.HtmlFormWrapper;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunComponents.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunComponents.groovy
index 8bc5a50..db69b53 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunComponents.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunComponents.groovy
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import org.ofbiz.widget.html.HtmlFormWrapper;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy
index 74d0108..6c25da5 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy
@@ -18,7 +18,7 @@
  */
 
 import org.ofbiz.entity.util.EntityUtil;
-import org.ofbiz.widget.html.HtmlFormWrapper;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 taskCosts = [];
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunDeclaration.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunDeclaration.groovy
index 8367e94..f456717 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunDeclaration.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunDeclaration.groovy
@@ -22,7 +22,7 @@
 
 import org.ofbiz.entity.util.EntityUtil;
 import org.ofbiz.entity.GenericValue;
-import org.ofbiz.widget.html.HtmlFormWrapper;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.manufacturing.jobshopmgt.ProductionRun;
 
 import javolution.util.FastList;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunFixedAssets.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunFixedAssets.groovy
index c1d6714..eb99298 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunFixedAssets.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunFixedAssets.groovy
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import org.ofbiz.widget.html.HtmlFormWrapper;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 
 productionRunId = parameters.productionRunId ?: parameters.workEffortId;
 
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionDay.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionDay.groovy
index e076d6a..ce1dea6 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionDay.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionDay.groovy
@@ -21,7 +21,7 @@
 import java.util.*;
 import org.ofbiz.base.util.*;
 import org.ofbiz.entity.*;
-import org.ofbiz.widget.html.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 
 if (security.hasEntityPermission("MANUFACTURING", "_VIEW", session)) {
     context.hasPermission = Boolean.TRUE;
diff --git a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionWeek.groovy b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionWeek.groovy
index 7907a4f..8886d69 100644
--- a/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionWeek.groovy
+++ b/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/routing/EditCalendarExceptionWeek.groovy
@@ -18,7 +18,7 @@
  */
 
 
-import org.ofbiz.widget.html.HtmlFormWrapper;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.base.util.*;
 
 if (security.hasEntityPermission("MANUFACTURING", "_VIEW", session)) {
diff --git a/applications/manufacturing/webapp/manufacturing/jobshopmgt/ShowProductionRun.groovy b/applications/manufacturing/webapp/manufacturing/jobshopmgt/ShowProductionRun.groovy
index ae8c362..b11a78f 100644
--- a/applications/manufacturing/webapp/manufacturing/jobshopmgt/ShowProductionRun.groovy
+++ b/applications/manufacturing/webapp/manufacturing/jobshopmgt/ShowProductionRun.groovy
@@ -25,7 +25,7 @@
 import org.ofbiz.base.util.*;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.widget.html.HtmlFormWrapper;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.manufacturing.jobshopmgt.ProductionRun;
 
 delegator = request.getAttribute("delegator");
diff --git a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderDeliveryScheduleInfo.groovy b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderDeliveryScheduleInfo.groovy
index 9fbd1b9..073c609 100644
--- a/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderDeliveryScheduleInfo.groovy
+++ b/applications/order/webapp/ordermgr/WEB-INF/actions/order/OrderDeliveryScheduleInfo.groovy
@@ -19,7 +19,7 @@
 
 import org.ofbiz.base.util.*;
 import org.ofbiz.entity.*;
-import org.ofbiz.widget.html.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 
 orderId = request.getParameter("orderId");
 orderTypeId = null;
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContent.groovy b/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContent.groovy
index 5ce758f..7fae990 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContent.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContent.groovy
@@ -21,7 +21,7 @@
 import org.ofbiz.base.util.string.*
 import org.ofbiz.entity.*
 import org.ofbiz.entity.util.EntityUtilProperties;
-import org.ofbiz.widget.html.*
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 
 // make the image file formats
 imageFilenameFormat = "configitems/${configItemId}";
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContentContent.groovy b/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContentContent.groovy
index 0370d1e..65f1414 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContentContent.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigItemContentContent.groovy
@@ -20,7 +20,7 @@
 import org.ofbiz.entity.*;
 import org.ofbiz.entity.util.*;
 import org.ofbiz.base.util.*;
-import org.ofbiz.widget.html.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 
 contentId = request.getParameter("contentId") ?: null;
 
diff --git a/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigOptions.groovy b/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigOptions.groovy
index bd3a6e4..4db0b0e 100644
--- a/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigOptions.groovy
+++ b/applications/product/webapp/catalog/WEB-INF/actions/config/EditProductConfigOptions.groovy
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import org.ofbiz.widget.html.*
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper
 
 createConfigOptionWrapper = new HtmlFormWrapper("component://product/widget/catalog/ConfigForms.xml", "CreateConfigOption", request, response);
 createConfigOptionWrapper.putInContext("configItemId", configItemId);
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipment.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipment.groovy
index a6e5372..7afbd43 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipment.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipment.groovy
@@ -18,7 +18,7 @@
  */
 
 import org.ofbiz.entity.condition.*
-import org.ofbiz.widget.html.HtmlFormWrapper
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper
 
 shipmentId = parameters.shipmentId;
 shipment = from("Shipment").where("shipmentId", shipmentId).queryOne();
diff --git a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPlan.groovy b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPlan.groovy
index d5288c6..aa17335 100644
--- a/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPlan.groovy
+++ b/applications/product/webapp/facility/WEB-INF/actions/shipment/EditShipmentPlan.groovy
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import org.ofbiz.widget.html.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.entity.condition.EntityCondition;
 
 shipmentId = request.getParameter("shipmentId");
diff --git a/framework/common/src/org/ofbiz/common/email/EmailServices.java b/framework/common/src/org/ofbiz/common/email/EmailServices.java
index 475a8f1..477eb08 100644
--- a/framework/common/src/org/ofbiz/common/email/EmailServices.java
+++ b/framework/common/src/org/ofbiz/common/email/EmailServices.java
@@ -73,9 +73,9 @@
 import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.service.mail.MimeMessageWrapper;
 import org.ofbiz.webapp.view.ApacheFopWorker;
-import org.ofbiz.widget.fo.FoScreenRenderer;
-import org.ofbiz.widget.html.HtmlScreenRenderer;
-import org.ofbiz.widget.screen.ScreenRenderer;
+import org.ofbiz.widget.renderer.fo.FoScreenRenderer;
+import org.ofbiz.widget.renderer.html.HtmlScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
 import org.xml.sax.SAXException;
 
 import com.sun.mail.smtp.SMTPAddressFailedException;
diff --git a/framework/common/webcommon/WEB-INF/handlers-controller.xml b/framework/common/webcommon/WEB-INF/handlers-controller.xml
index 23802a7..eb083c3 100644
--- a/framework/common/webcommon/WEB-INF/handlers-controller.xml
+++ b/framework/common/webcommon/WEB-INF/handlers-controller.xml
@@ -35,11 +35,11 @@
     <handler name="script" type="request" class="org.ofbiz.webapp.event.ScriptEventHandler"/>
 
     <!-- view handlers -->
-    <handler name="screen" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/>
-    <handler name="screenxml" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/>
-    <handler name="screentext" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/>
-    <handler name="screencsv" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/>
-    <handler name="screenfop" type="view" class="org.ofbiz.widget.screen.ScreenFopViewHandler"/>
+    <handler name="screen" type="view" class="org.ofbiz.widget.renderer.macro.MacroScreenViewHandler"/>
+    <handler name="screenxml" type="view" class="org.ofbiz.widget.renderer.macro.MacroScreenViewHandler"/>
+    <handler name="screentext" type="view" class="org.ofbiz.widget.renderer.macro.MacroScreenViewHandler"/>
+    <handler name="screencsv" type="view" class="org.ofbiz.widget.renderer.macro.MacroScreenViewHandler"/>
+    <handler name="screenfop" type="view" class="org.ofbiz.widget.renderer.fo.ScreenFopViewHandler"/>
     <handler name="jsp" type="view" class="org.ofbiz.webapp.view.JspViewHandler"/>
     <handler name="http" type="view" class="org.ofbiz.webapp.view.HttpViewHandler"/>
 </site-conf>
diff --git a/framework/common/widget/PortalPageScreens.xml b/framework/common/widget/PortalPageScreens.xml
index 17a7a08..0c2c16c 100644
--- a/framework/common/widget/PortalPageScreens.xml
+++ b/framework/common/widget/PortalPageScreens.xml
@@ -94,7 +94,7 @@
                 <set field="layoutSettings.javaScripts[]" value="/images/myportal.js" global="true"/>
                 <set field="layoutSettings.styleSheets[+0]" value="/images/myportal.css" global="true"/>
                 <entity-one entity-name="PortalPage" value-field="portalPage"/>
-                <set field="portalPages" value="${groovy:org.ofbiz.widget.PortalPageWorker.getPortalPages(parameters.parentPortalPageId,context)}"/>
+                <set field="portalPages" value="${groovy:org.ofbiz.widget.portal.PortalPageWorker.getPortalPages(parameters.parentPortalPageId,context)}"/>
             </actions>
             <widgets>
                 <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
diff --git a/framework/resources/templates/web.xml b/framework/resources/templates/web.xml
index 2ea7747..3e672cb 100644
--- a/framework/resources/templates/web.xml
+++ b/framework/resources/templates/web.xml
@@ -26,7 +26,7 @@
     <context-param>
         <param-name>widgetVerbose</param-name>
         <param-value>false</param-value>
-        <description>Enable widget boundary comments. See org.ofbiz.widget.ModelWidget.widgetBoundaryCommentsEnabled().</description>
+        <description>Enable widget boundary comments. See org.ofbiz.widget.model.ModelWidget.widgetBoundaryCommentsEnabled().</description>
     </context-param>
     -->
     <context-param>
diff --git a/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java b/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java
index b82da97..c64cdae 100644
--- a/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java
+++ b/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java
@@ -42,12 +42,13 @@
 import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.cache.UtilCache;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.DelegatorFactory;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.config.model.DelegatorElement;
 import org.ofbiz.entity.config.model.EntityConfig;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.model.ModelReader;
-import org.ofbiz.entity.*;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
@@ -57,10 +58,10 @@
 import org.ofbiz.webapp.control.ConfigXMLReader;
 import org.ofbiz.webapp.control.ConfigXMLReader.ControllerConfig;
 import org.ofbiz.webapp.control.WebAppConfigurationException;
-import org.ofbiz.widget.form.FormFactory;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.screen.ModelScreen;
-import org.ofbiz.widget.screen.ScreenFactory;
+import org.ofbiz.widget.model.FormFactory;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelScreen;
+import org.ofbiz.widget.model.ScreenFactory;
 import org.xml.sax.SAXException;
 
 public class ArtifactInfoFactory {
diff --git a/framework/webtools/src/org/ofbiz/webtools/artifactinfo/FormWidgetArtifactInfo.java b/framework/webtools/src/org/ofbiz/webtools/artifactinfo/FormWidgetArtifactInfo.java
index 7828dd3..46f0f93 100644
--- a/framework/webtools/src/org/ofbiz/webtools/artifactinfo/FormWidgetArtifactInfo.java
+++ b/framework/webtools/src/org/ofbiz/webtools/artifactinfo/FormWidgetArtifactInfo.java
@@ -33,7 +33,7 @@
 import org.ofbiz.base.util.UtilURL;
 import org.ofbiz.widget.artifact.ArtifactInfoContext;
 import org.ofbiz.widget.artifact.ArtifactInfoGatherer;
-import org.ofbiz.widget.form.ModelForm;
+import org.ofbiz.widget.model.ModelForm;
 import org.xml.sax.SAXException;
 
 /**
diff --git a/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ScreenWidgetArtifactInfo.java b/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ScreenWidgetArtifactInfo.java
index f3ee202..2c2544f 100644
--- a/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ScreenWidgetArtifactInfo.java
+++ b/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ScreenWidgetArtifactInfo.java
@@ -35,7 +35,7 @@
 import org.ofbiz.base.util.UtilURL;
 import org.ofbiz.widget.artifact.ArtifactInfoContext;
 import org.ofbiz.widget.artifact.ArtifactInfoGatherer;
-import org.ofbiz.widget.screen.ModelScreen;
+import org.ofbiz.widget.model.ModelScreen;
 import org.xml.sax.SAXException;
 
 /**
diff --git a/framework/webtools/src/org/ofbiz/webtools/print/FoPrintServerEvents.java b/framework/webtools/src/org/ofbiz/webtools/print/FoPrintServerEvents.java
index cdc032e..53d6a26 100644
--- a/framework/webtools/src/org/ofbiz/webtools/print/FoPrintServerEvents.java
+++ b/framework/webtools/src/org/ofbiz/webtools/print/FoPrintServerEvents.java
@@ -36,8 +36,8 @@
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.widget.screen.ScreenRenderer;
-import org.ofbiz.widget.html.HtmlScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.html.HtmlScreenRenderer;
 
 /**
  * FoPrintServerEvents
diff --git a/framework/widget/config/freemarkerTransforms.properties b/framework/widget/config/freemarkerTransforms.properties
index 82b64b8..5b783e2 100644
--- a/framework/widget/config/freemarkerTransforms.properties
+++ b/framework/widget/config/freemarkerTransforms.properties
@@ -21,4 +21,4 @@
 
 # entries are in the form: key=transform name, property=transform class name
 
-menuWrap=org.ofbiz.widget.menu.MenuWrapTransform
+menuWrap=org.ofbiz.widget.renderer.MenuWrapTransform
diff --git a/framework/widget/src/org/ofbiz/widget/WidgetFactory.java b/framework/widget/src/org/ofbiz/widget/WidgetFactory.java
index 5b9f591..a6f1cc2 100644
--- a/framework/widget/src/org/ofbiz/widget/WidgetFactory.java
+++ b/framework/widget/src/org/ofbiz/widget/WidgetFactory.java
@@ -29,9 +29,9 @@
 import org.ofbiz.base.util.Assert;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.widget.screen.IterateSectionWidget;
-import org.ofbiz.widget.screen.ModelScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget;
+import org.ofbiz.widget.model.IterateSectionWidget;
+import org.ofbiz.widget.model.ModelScreen;
+import org.ofbiz.widget.model.ModelScreenWidget;
 import org.w3c.dom.Element;
 
 /**
diff --git a/framework/widget/src/org/ofbiz/widget/WidgetWorker.java b/framework/widget/src/org/ofbiz/widget/WidgetWorker.java
index 093288d..18a7be3 100644
--- a/framework/widget/src/org/ofbiz/widget/WidgetWorker.java
+++ b/framework/widget/src/org/ofbiz/widget/WidgetWorker.java
@@ -39,8 +39,8 @@
 import org.ofbiz.webapp.control.RequestHandler;
 import org.ofbiz.webapp.control.WebAppConfigurationException;
 import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.ModelFormField;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelFormField;
 
 public final class WidgetWorker {
 
diff --git a/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java b/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
index 4bfde5a..a8fb7ee 100644
--- a/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
+++ b/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
@@ -23,83 +23,83 @@
 import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.webapp.control.ConfigXMLReader;
-import org.ofbiz.widget.AbstractModelAction.EntityAnd;
-import org.ofbiz.widget.AbstractModelAction.EntityCondition;
-import org.ofbiz.widget.AbstractModelAction.EntityOne;
-import org.ofbiz.widget.AbstractModelAction.GetRelated;
-import org.ofbiz.widget.AbstractModelAction.GetRelatedOne;
-import org.ofbiz.widget.AbstractModelAction.PropertyMap;
-import org.ofbiz.widget.AbstractModelAction.PropertyToField;
-import org.ofbiz.widget.AbstractModelAction.Script;
-import org.ofbiz.widget.AbstractModelAction.Service;
-import org.ofbiz.widget.AbstractModelAction.SetField;
-import org.ofbiz.widget.ModelAction;
-import org.ofbiz.widget.ModelActionVisitor;
-import org.ofbiz.widget.ModelFieldVisitor;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.form.FieldInfo;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.ModelForm.AltTarget;
-import org.ofbiz.widget.form.ModelForm.AutoFieldsEntity;
-import org.ofbiz.widget.form.ModelForm.AutoFieldsService;
-import org.ofbiz.widget.form.ModelFormAction;
-import org.ofbiz.widget.form.ModelFormAction.CallParentActions;
-import org.ofbiz.widget.form.ModelFormField;
-import org.ofbiz.widget.form.ModelFormField.CheckField;
-import org.ofbiz.widget.form.ModelFormField.ContainerField;
-import org.ofbiz.widget.form.ModelFormField.DateFindField;
-import org.ofbiz.widget.form.ModelFormField.DateTimeField;
-import org.ofbiz.widget.form.ModelFormField.DisplayEntityField;
-import org.ofbiz.widget.form.ModelFormField.DisplayField;
-import org.ofbiz.widget.form.ModelFormField.DropDownField;
-import org.ofbiz.widget.form.ModelFormField.FieldInfoWithOptions;
-import org.ofbiz.widget.form.ModelFormField.FileField;
-import org.ofbiz.widget.form.ModelFormField.HiddenField;
-import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
-import org.ofbiz.widget.form.ModelFormField.IgnoredField;
-import org.ofbiz.widget.form.ModelFormField.ImageField;
-import org.ofbiz.widget.form.ModelFormField.LookupField;
-import org.ofbiz.widget.form.ModelFormField.PasswordField;
-import org.ofbiz.widget.form.ModelFormField.RadioField;
-import org.ofbiz.widget.form.ModelFormField.RangeFindField;
-import org.ofbiz.widget.form.ModelFormField.ResetField;
-import org.ofbiz.widget.form.ModelFormField.SubmitField;
-import org.ofbiz.widget.form.ModelFormField.TextField;
-import org.ofbiz.widget.form.ModelFormField.TextFindField;
-import org.ofbiz.widget.form.ModelFormField.TextareaField;
-import org.ofbiz.widget.menu.ModelMenu;
-import org.ofbiz.widget.menu.ModelMenuAction;
-import org.ofbiz.widget.menu.ModelMenuItem;
-import org.ofbiz.widget.screen.HtmlWidget;
-import org.ofbiz.widget.screen.HtmlWidget.HtmlTemplate;
-import org.ofbiz.widget.screen.HtmlWidget.HtmlTemplateDecorator;
-import org.ofbiz.widget.screen.HtmlWidget.HtmlTemplateDecoratorSection;
-import org.ofbiz.widget.screen.IterateSectionWidget;
-import org.ofbiz.widget.screen.ModelScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget;
-import org.ofbiz.widget.screen.ModelScreenWidget.Column;
-import org.ofbiz.widget.screen.ModelScreenWidget.ColumnContainer;
-import org.ofbiz.widget.screen.ModelScreenWidget.Container;
-import org.ofbiz.widget.screen.ModelScreenWidget.Content;
-import org.ofbiz.widget.screen.ModelScreenWidget.DecoratorScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget.DecoratorSection;
-import org.ofbiz.widget.screen.ModelScreenWidget.DecoratorSectionInclude;
-import org.ofbiz.widget.screen.ModelScreenWidget.Form;
-import org.ofbiz.widget.screen.ModelScreenWidget.HorizontalSeparator;
-import org.ofbiz.widget.screen.ModelScreenWidget.ScreenImage;
-import org.ofbiz.widget.screen.ModelScreenWidget.IncludeScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget.Label;
-import org.ofbiz.widget.screen.ModelScreenWidget.ScreenLink;
-import org.ofbiz.widget.screen.ModelScreenWidget.Menu;
-import org.ofbiz.widget.screen.ModelScreenWidget.PlatformSpecific;
-import org.ofbiz.widget.screen.ModelScreenWidget.PortalPage;
-import org.ofbiz.widget.screen.ModelScreenWidget.Screenlet;
-import org.ofbiz.widget.screen.ModelScreenWidget.Section;
-import org.ofbiz.widget.screen.ModelScreenWidget.Tree;
-import org.ofbiz.widget.tree.ModelTree;
-import org.ofbiz.widget.tree.ModelTree.ModelNode;
-import org.ofbiz.widget.tree.ModelTree.ModelNode.ModelSubNode;
-import org.ofbiz.widget.tree.ModelTreeAction;
+import org.ofbiz.widget.model.AbstractModelAction.EntityAnd;
+import org.ofbiz.widget.model.AbstractModelAction.EntityCondition;
+import org.ofbiz.widget.model.AbstractModelAction.EntityOne;
+import org.ofbiz.widget.model.AbstractModelAction.GetRelated;
+import org.ofbiz.widget.model.AbstractModelAction.GetRelatedOne;
+import org.ofbiz.widget.model.AbstractModelAction.PropertyMap;
+import org.ofbiz.widget.model.AbstractModelAction.PropertyToField;
+import org.ofbiz.widget.model.AbstractModelAction.Script;
+import org.ofbiz.widget.model.AbstractModelAction.Service;
+import org.ofbiz.widget.model.AbstractModelAction.SetField;
+import org.ofbiz.widget.model.FieldInfo;
+import org.ofbiz.widget.model.HtmlWidget;
+import org.ofbiz.widget.model.HtmlWidget.HtmlTemplate;
+import org.ofbiz.widget.model.HtmlWidget.HtmlTemplateDecorator;
+import org.ofbiz.widget.model.HtmlWidget.HtmlTemplateDecoratorSection;
+import org.ofbiz.widget.model.IterateSectionWidget;
+import org.ofbiz.widget.model.ModelAction;
+import org.ofbiz.widget.model.ModelActionVisitor;
+import org.ofbiz.widget.model.ModelFieldVisitor;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelForm.AltTarget;
+import org.ofbiz.widget.model.ModelForm.AutoFieldsEntity;
+import org.ofbiz.widget.model.ModelForm.AutoFieldsService;
+import org.ofbiz.widget.model.ModelFormAction;
+import org.ofbiz.widget.model.ModelFormAction.CallParentActions;
+import org.ofbiz.widget.model.ModelFormField;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayEntityField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
+import org.ofbiz.widget.model.ModelMenu;
+import org.ofbiz.widget.model.ModelMenuAction;
+import org.ofbiz.widget.model.ModelMenuItem;
+import org.ofbiz.widget.model.ModelScreen;
+import org.ofbiz.widget.model.ModelScreenWidget;
+import org.ofbiz.widget.model.ModelScreenWidget.Column;
+import org.ofbiz.widget.model.ModelScreenWidget.ColumnContainer;
+import org.ofbiz.widget.model.ModelScreenWidget.Container;
+import org.ofbiz.widget.model.ModelScreenWidget.Content;
+import org.ofbiz.widget.model.ModelScreenWidget.DecoratorScreen;
+import org.ofbiz.widget.model.ModelScreenWidget.DecoratorSection;
+import org.ofbiz.widget.model.ModelScreenWidget.DecoratorSectionInclude;
+import org.ofbiz.widget.model.ModelScreenWidget.Form;
+import org.ofbiz.widget.model.ModelScreenWidget.HorizontalSeparator;
+import org.ofbiz.widget.model.ModelScreenWidget.IncludeScreen;
+import org.ofbiz.widget.model.ModelScreenWidget.Label;
+import org.ofbiz.widget.model.ModelScreenWidget.Menu;
+import org.ofbiz.widget.model.ModelScreenWidget.PlatformSpecific;
+import org.ofbiz.widget.model.ModelScreenWidget.PortalPage;
+import org.ofbiz.widget.model.ModelScreenWidget.ScreenImage;
+import org.ofbiz.widget.model.ModelScreenWidget.ScreenLink;
+import org.ofbiz.widget.model.ModelScreenWidget.Screenlet;
+import org.ofbiz.widget.model.ModelScreenWidget.Section;
+import org.ofbiz.widget.model.ModelScreenWidget.Tree;
+import org.ofbiz.widget.model.ModelTree;
+import org.ofbiz.widget.model.ModelTree.ModelNode;
+import org.ofbiz.widget.model.ModelTree.ModelNode.ModelSubNode;
+import org.ofbiz.widget.model.ModelTreeAction;
+import org.ofbiz.widget.model.ModelWidgetVisitor;
 
 /**
  * An object that gathers artifact information from screen widgets.
diff --git a/framework/widget/src/org/ofbiz/widget/ContentWorkerInterface.java b/framework/widget/src/org/ofbiz/widget/content/ContentWorkerInterface.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/ContentWorkerInterface.java
rename to framework/widget/src/org/ofbiz/widget/content/ContentWorkerInterface.java
index cceb618..b83f6db 100644
--- a/framework/widget/src/org/ofbiz/widget/ContentWorkerInterface.java
+++ b/framework/widget/src/org/ofbiz/widget/content/ContentWorkerInterface.java
@@ -1,48 +1,48 @@
-/*******************************************************************************
- * 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.ofbiz.widget;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.service.LocalDispatcher;
-
-/**
- * ContentWorkerInterface
- */
-public interface ContentWorkerInterface {
-
-    // helper methods
-    public GenericValue getCurrentContentExt(Delegator delegator, List<Map<String, ? extends Object>> trail, GenericValue userLogin, Map<String, Object> ctx, Boolean nullThruDatesOnly, String contentAssocPredicateId)  throws GeneralException;
-    public GenericValue getWebSitePublishPointExt(Delegator delegator, String contentId, boolean ignoreCache) throws GenericEntityException;
-    public String getMimeTypeIdExt(Delegator delegator, GenericValue view, Map<String, Object> ctx);
-
-    // new rendering methods
-    public void renderContentAsTextExt(LocalDispatcher dispatcher, Delegator delegator, String contentId, Appendable out, Map<String, Object> templateContext, Locale locale, String mimeTypeId, boolean cache) throws GeneralException, IOException;
-    public String renderContentAsTextExt(LocalDispatcher dispatcher, Delegator delegator, String contentId, Map<String, Object> templateContext, Locale locale, String mimeTypeId, boolean cache) throws GeneralException, IOException;
-
-    public void renderSubContentAsTextExt(LocalDispatcher dispatcher, Delegator delegator, String contentId, Appendable out, String mapKey, Map<String, Object> templateContext, Locale locale, String mimeTypeId, boolean cache) throws GeneralException, IOException;
-    public String renderSubContentAsTextExt(LocalDispatcher dispatcher, Delegator delegator, String contentId, String mapKey, Map<String, Object> templateContext, Locale locale, String mimeTypeId, boolean cache) throws GeneralException, IOException;
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.content;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.service.LocalDispatcher;
+
+/**
+ * ContentWorkerInterface
+ */
+public interface ContentWorkerInterface {
+
+    // helper methods
+    public GenericValue getCurrentContentExt(Delegator delegator, List<Map<String, ? extends Object>> trail, GenericValue userLogin, Map<String, Object> ctx, Boolean nullThruDatesOnly, String contentAssocPredicateId)  throws GeneralException;
+    public GenericValue getWebSitePublishPointExt(Delegator delegator, String contentId, boolean ignoreCache) throws GenericEntityException;
+    public String getMimeTypeIdExt(Delegator delegator, GenericValue view, Map<String, Object> ctx);
+
+    // new rendering methods
+    public void renderContentAsTextExt(LocalDispatcher dispatcher, Delegator delegator, String contentId, Appendable out, Map<String, Object> templateContext, Locale locale, String mimeTypeId, boolean cache) throws GeneralException, IOException;
+    public String renderContentAsTextExt(LocalDispatcher dispatcher, Delegator delegator, String contentId, Map<String, Object> templateContext, Locale locale, String mimeTypeId, boolean cache) throws GeneralException, IOException;
+
+    public void renderSubContentAsTextExt(LocalDispatcher dispatcher, Delegator delegator, String contentId, Appendable out, String mapKey, Map<String, Object> templateContext, Locale locale, String mimeTypeId, boolean cache) throws GeneralException, IOException;
+    public String renderSubContentAsTextExt(LocalDispatcher dispatcher, Delegator delegator, String contentId, String mapKey, Map<String, Object> templateContext, Locale locale, String mimeTypeId, boolean cache) throws GeneralException, IOException;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/DataResourceWorkerInterface.java b/framework/widget/src/org/ofbiz/widget/content/DataResourceWorkerInterface.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/DataResourceWorkerInterface.java
rename to framework/widget/src/org/ofbiz/widget/content/DataResourceWorkerInterface.java
index 155ace3..e0c505e 100644
--- a/framework/widget/src/org/ofbiz/widget/DataResourceWorkerInterface.java
+++ b/framework/widget/src/org/ofbiz/widget/content/DataResourceWorkerInterface.java
@@ -1,37 +1,37 @@
-/*******************************************************************************
- * 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.ofbiz.widget;
-
-import java.io.IOException;
-import java.util.Locale;
-import java.util.Map;
-
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.entity.Delegator;
-
-/**
- * ContentWorkerInterface
- */
-public interface DataResourceWorkerInterface {
-    public String renderDataResourceAsTextExt(Delegator delegator, String dataResourceId, Map<String, Object> templateContext,
-            Locale locale, String targetMimeTypeId, boolean cache) throws GeneralException, IOException;
-
-    public void renderDataResourceAsTextExt(Delegator delegator, String dataResourceId, Appendable out, Map<String, Object> templateContext,
-            Locale locale, String targetMimeTypeId, boolean cache) throws GeneralException, IOException;
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.content;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Map;
+
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.entity.Delegator;
+
+/**
+ * ContentWorkerInterface
+ */
+public interface DataResourceWorkerInterface {
+    public String renderDataResourceAsTextExt(Delegator delegator, String dataResourceId, Map<String, Object> templateContext,
+            Locale locale, String targetMimeTypeId, boolean cache) throws GeneralException, IOException;
+
+    public void renderDataResourceAsTextExt(Delegator delegator, String dataResourceId, Appendable out, Map<String, Object> templateContext,
+            Locale locale, String targetMimeTypeId, boolean cache) throws GeneralException, IOException;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/WidgetContentWorker.java b/framework/widget/src/org/ofbiz/widget/content/WidgetContentWorker.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/WidgetContentWorker.java
rename to framework/widget/src/org/ofbiz/widget/content/WidgetContentWorker.java
index c094d19..edea2cf 100644
--- a/framework/widget/src/org/ofbiz/widget/WidgetContentWorker.java
+++ b/framework/widget/src/org/ofbiz/widget/content/WidgetContentWorker.java
@@ -1,42 +1,42 @@
-/*******************************************************************************
- * 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.ofbiz.widget;
-
-import org.ofbiz.base.util.Debug;
-
-/**
- * WidgetContentWorker Class
- */
-public class WidgetContentWorker {
-    public static final String module = WidgetContentWorker.class.getName();
-    public static ContentWorkerInterface contentWorker = null;
-    static {
-        try {
-            ClassLoader loader = Thread.currentThread().getContextClassLoader();
-            // note: loadClass is necessary for these since this class doesn't know anything about them at compile time
-            contentWorker = (ContentWorkerInterface) loader.loadClass("org.ofbiz.content.content.ContentWorker").newInstance();
-        } catch (ClassNotFoundException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        } catch (IllegalAccessException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        } catch (InstantiationException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.content;
+
+import org.ofbiz.base.util.Debug;
+
+/**
+ * WidgetContentWorker Class
+ */
+public class WidgetContentWorker {
+    public static final String module = WidgetContentWorker.class.getName();
+    public static ContentWorkerInterface contentWorker = null;
+    static {
+        try {
+            ClassLoader loader = Thread.currentThread().getContextClassLoader();
+            // note: loadClass is necessary for these since this class doesn't know anything about them at compile time
+            contentWorker = (ContentWorkerInterface) loader.loadClass("org.ofbiz.content.content.ContentWorker").newInstance();
+        } catch (ClassNotFoundException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        } catch (IllegalAccessException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        } catch (InstantiationException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/WidgetDataResourceWorker.java b/framework/widget/src/org/ofbiz/widget/content/WidgetDataResourceWorker.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/WidgetDataResourceWorker.java
rename to framework/widget/src/org/ofbiz/widget/content/WidgetDataResourceWorker.java
index d19f427..afe2418 100644
--- a/framework/widget/src/org/ofbiz/widget/WidgetDataResourceWorker.java
+++ b/framework/widget/src/org/ofbiz/widget/content/WidgetDataResourceWorker.java
@@ -1,42 +1,42 @@
-/*******************************************************************************
- * 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.ofbiz.widget;
-
-import org.ofbiz.base.util.Debug;
-
-/**
- * WidgetContentWorker Class
- */
-public class WidgetDataResourceWorker {
-    public static final String module = WidgetDataResourceWorker.class.getName();
-    public static DataResourceWorkerInterface dataresourceWorker = null;
-    static {
-        try {
-            ClassLoader loader = Thread.currentThread().getContextClassLoader();
-            // note: loadClass is necessary for these since this class doesn't know anything about them at compile time
-            dataresourceWorker = (DataResourceWorkerInterface) loader.loadClass("org.ofbiz.content.data.DataResourceWorker").newInstance();
-        } catch (ClassNotFoundException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        } catch (IllegalAccessException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        } catch (InstantiationException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.content;
+
+import org.ofbiz.base.util.Debug;
+
+/**
+ * WidgetContentWorker Class
+ */
+public class WidgetDataResourceWorker {
+    public static final String module = WidgetDataResourceWorker.class.getName();
+    public static DataResourceWorkerInterface dataresourceWorker = null;
+    static {
+        try {
+            ClassLoader loader = Thread.currentThread().getContextClassLoader();
+            // note: loadClass is necessary for these since this class doesn't know anything about them at compile time
+            dataresourceWorker = (DataResourceWorkerInterface) loader.loadClass("org.ofbiz.content.data.DataResourceWorker").newInstance();
+        } catch (ClassNotFoundException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        } catch (IllegalAccessException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        } catch (InstantiationException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/AbstractModelAction.java b/framework/widget/src/org/ofbiz/widget/model/AbstractModelAction.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/AbstractModelAction.java
rename to framework/widget/src/org/ofbiz/widget/model/AbstractModelAction.java
index 0aacb3e..7ec655b 100644
--- a/framework/widget/src/org/ofbiz/widget/AbstractModelAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/AbstractModelAction.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
 import java.io.Serializable;
 import java.text.MessageFormat;
@@ -58,7 +58,7 @@
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.ModelService;
-import org.ofbiz.widget.xml.XmlWidgetActionVisitor;
+import org.ofbiz.widget.WidgetWorker;
 import org.w3c.dom.Element;
 
 /**
diff --git a/framework/widget/src/org/ofbiz/widget/AbstractModelCondition.java b/framework/widget/src/org/ofbiz/widget/model/AbstractModelCondition.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/AbstractModelCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/AbstractModelCondition.java
index 7cb74b3..d752f0b 100644
--- a/framework/widget/src/org/ofbiz/widget/AbstractModelCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/AbstractModelCondition.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
 import java.io.Serializable;
 import java.lang.reflect.Method;
@@ -50,7 +50,6 @@
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ModelService;
 import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.widget.xml.*;
 import org.w3c.dom.Element;
 
 /**
diff --git a/framework/widget/src/org/ofbiz/widget/CommonWidgetModels.java b/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/CommonWidgetModels.java
rename to framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java
index dfd9f87..b538397 100644
--- a/framework/widget/src/org/ofbiz/widget/CommonWidgetModels.java
+++ b/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
 import java.math.BigDecimal;
 import java.text.DateFormat;
diff --git a/framework/widget/src/org/ofbiz/widget/form/FieldInfo.java b/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/form/FieldInfo.java
rename to framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
index dcb8ea3..7bc47b3 100644
--- a/framework/widget/src/org/ofbiz/widget/form/FieldInfo.java
+++ b/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.form;
+package org.ofbiz.widget.model;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -24,8 +24,7 @@
 import java.util.Map;
 
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.widget.ModelFieldVisitor;
-import org.ofbiz.widget.xml.XmlWidgetFieldVisitor;
+import org.ofbiz.widget.renderer.FormStringRenderer;
 import org.w3c.dom.Element;
 
 /**
diff --git a/framework/widget/src/org/ofbiz/widget/form/FormFactory.java b/framework/widget/src/org/ofbiz/widget/model/FormFactory.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/form/FormFactory.java
rename to framework/widget/src/org/ofbiz/widget/model/FormFactory.java
index 0729275..a9ba4ad 100644
--- a/framework/widget/src/org/ofbiz/widget/form/FormFactory.java
+++ b/framework/widget/src/org/ofbiz/widget/model/FormFactory.java
@@ -1,131 +1,131 @@
-/*******************************************************************************
- * 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.ofbiz.widget.form;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.location.FlexibleLocation;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.cache.UtilCache;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.model.ModelReader;
-import org.ofbiz.service.DispatchContext;
-import org.ofbiz.service.LocalDispatcher;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-
-/**
- * Widget Library - Form factory class
- */
-public class FormFactory {
-
-    public static final String module = FormFactory.class.getName();
-    private static final UtilCache<String, ModelForm> formLocationCache = UtilCache.createUtilCache("widget.form.locationResource", 0, 0, false);
-    private static final UtilCache<String, ModelForm> formWebappCache = UtilCache.createUtilCache("widget.form.webappResource", 0, 0, false);
-
-    public static Map<String, ModelForm> getFormsFromLocation(String resourceName, ModelReader entityModelReader, DispatchContext dispatchContext)
-            throws IOException, SAXException, ParserConfigurationException {
-        URL formFileUrl = FlexibleLocation.resolveLocation(resourceName);
-        Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true);
-        return readFormDocument(formFileDoc, entityModelReader, dispatchContext, resourceName);
-    }
-
-    public static ModelForm getFormFromLocation(String resourceName, String formName, ModelReader entityModelReader, DispatchContext dispatchContext)
-            throws IOException, SAXException, ParserConfigurationException {
-        StringBuilder sb = new StringBuilder(dispatchContext.getDelegator().getDelegatorName());
-        sb.append(":").append(resourceName).append("#").append(formName);
-        String cacheKey = sb.toString();
-        ModelForm modelForm = formLocationCache.get(cacheKey);
-        if (modelForm == null) {
-            URL formFileUrl = FlexibleLocation.resolveLocation(resourceName);
-            Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true);
-            if (formFileDoc == null) {
-                throw new IllegalArgumentException("Could not find resource [" + resourceName + "]");
-            }
-            modelForm = createModelForm(formFileDoc, entityModelReader, dispatchContext, resourceName, formName);
-            modelForm = formLocationCache.putIfAbsentAndGet(cacheKey, modelForm);
-        }
-        if (modelForm == null) {
-            throw new IllegalArgumentException("Could not find form with name [" + formName + "] in class resource [" + resourceName + "]");
-        }
-        return modelForm;
-    }
-
-    public static ModelForm getFormFromWebappContext(String resourceName, String formName, HttpServletRequest request)
-            throws IOException, SAXException, ParserConfigurationException {
-        String webappName = UtilHttp.getApplicationName(request);
-        String cacheKey = webappName + "::" + resourceName + "::" + formName;
-        ModelForm modelForm = formWebappCache.get(cacheKey);
-        if (modelForm == null) {
-            ServletContext servletContext = (ServletContext) request.getAttribute("servletContext");
-            Delegator delegator = (Delegator) request.getAttribute("delegator");
-            LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
-            URL formFileUrl = servletContext.getResource(resourceName);
-            Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true);
-            Element formElement = UtilXml.firstChildElement(formFileDoc.getDocumentElement(), "form", "name", formName);
-            modelForm = new ModelForm(formElement, resourceName, delegator.getModelReader(), dispatcher.getDispatchContext());
-            modelForm = formWebappCache.putIfAbsentAndGet(cacheKey, modelForm);
-        }
-        if (modelForm == null) {
-            throw new IllegalArgumentException("Could not find form with name [" + formName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]");
-        }
-        return modelForm;
-    }
-
-    public static Map<String, ModelForm> readFormDocument(Document formFileDoc, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation) {
-        Map<String, ModelForm> modelFormMap = new HashMap<String, ModelForm>();
-        if (formFileDoc != null) {
-            // read document and construct ModelForm for each form element
-            Element rootElement = formFileDoc.getDocumentElement();
-            List<? extends Element> formElements = UtilXml.childElementList(rootElement, "form");
-            for (Element formElement : formElements) {
-                String formName = formElement.getAttribute("name");
-                String cacheKey = formLocation + "#" + formName;
-                ModelForm modelForm = formLocationCache.get(cacheKey);
-                if (modelForm == null) {
-                    modelForm = createModelForm(formElement, entityModelReader, dispatchContext, formLocation, formName);
-                    modelForm = formLocationCache.putIfAbsentAndGet(cacheKey, modelForm);
-                }
-                modelFormMap.put(formName, modelForm);
-            }
-        }
-        return modelFormMap;
-    }
-
-    public static ModelForm createModelForm(Document formFileDoc, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation, String formName) {
-        Element formElement = UtilXml.firstChildElement(formFileDoc.getDocumentElement(), "form", "name", formName);
-        return createModelForm(formElement, entityModelReader, dispatchContext, formLocation, formName);
-    }
-
-    public static ModelForm createModelForm(Element formElement, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation, String formName) {
-        ModelForm modelForm = new ModelForm(formElement, formLocation, entityModelReader, dispatchContext);
-        return modelForm;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.location.FlexibleLocation;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.cache.UtilCache;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.model.ModelReader;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.LocalDispatcher;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Widget Library - Form factory class
+ */
+public class FormFactory {
+
+    public static final String module = FormFactory.class.getName();
+    private static final UtilCache<String, ModelForm> formLocationCache = UtilCache.createUtilCache("widget.form.locationResource", 0, 0, false);
+    private static final UtilCache<String, ModelForm> formWebappCache = UtilCache.createUtilCache("widget.form.webappResource", 0, 0, false);
+
+    public static Map<String, ModelForm> getFormsFromLocation(String resourceName, ModelReader entityModelReader, DispatchContext dispatchContext)
+            throws IOException, SAXException, ParserConfigurationException {
+        URL formFileUrl = FlexibleLocation.resolveLocation(resourceName);
+        Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true);
+        return readFormDocument(formFileDoc, entityModelReader, dispatchContext, resourceName);
+    }
+
+    public static ModelForm getFormFromLocation(String resourceName, String formName, ModelReader entityModelReader, DispatchContext dispatchContext)
+            throws IOException, SAXException, ParserConfigurationException {
+        StringBuilder sb = new StringBuilder(dispatchContext.getDelegator().getDelegatorName());
+        sb.append(":").append(resourceName).append("#").append(formName);
+        String cacheKey = sb.toString();
+        ModelForm modelForm = formLocationCache.get(cacheKey);
+        if (modelForm == null) {
+            URL formFileUrl = FlexibleLocation.resolveLocation(resourceName);
+            Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true);
+            if (formFileDoc == null) {
+                throw new IllegalArgumentException("Could not find resource [" + resourceName + "]");
+            }
+            modelForm = createModelForm(formFileDoc, entityModelReader, dispatchContext, resourceName, formName);
+            modelForm = formLocationCache.putIfAbsentAndGet(cacheKey, modelForm);
+        }
+        if (modelForm == null) {
+            throw new IllegalArgumentException("Could not find form with name [" + formName + "] in class resource [" + resourceName + "]");
+        }
+        return modelForm;
+    }
+
+    public static ModelForm getFormFromWebappContext(String resourceName, String formName, HttpServletRequest request)
+            throws IOException, SAXException, ParserConfigurationException {
+        String webappName = UtilHttp.getApplicationName(request);
+        String cacheKey = webappName + "::" + resourceName + "::" + formName;
+        ModelForm modelForm = formWebappCache.get(cacheKey);
+        if (modelForm == null) {
+            ServletContext servletContext = (ServletContext) request.getAttribute("servletContext");
+            Delegator delegator = (Delegator) request.getAttribute("delegator");
+            LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
+            URL formFileUrl = servletContext.getResource(resourceName);
+            Document formFileDoc = UtilXml.readXmlDocument(formFileUrl, true, true);
+            Element formElement = UtilXml.firstChildElement(formFileDoc.getDocumentElement(), "form", "name", formName);
+            modelForm = new ModelForm(formElement, resourceName, delegator.getModelReader(), dispatcher.getDispatchContext());
+            modelForm = formWebappCache.putIfAbsentAndGet(cacheKey, modelForm);
+        }
+        if (modelForm == null) {
+            throw new IllegalArgumentException("Could not find form with name [" + formName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]");
+        }
+        return modelForm;
+    }
+
+    public static Map<String, ModelForm> readFormDocument(Document formFileDoc, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation) {
+        Map<String, ModelForm> modelFormMap = new HashMap<String, ModelForm>();
+        if (formFileDoc != null) {
+            // read document and construct ModelForm for each form element
+            Element rootElement = formFileDoc.getDocumentElement();
+            List<? extends Element> formElements = UtilXml.childElementList(rootElement, "form");
+            for (Element formElement : formElements) {
+                String formName = formElement.getAttribute("name");
+                String cacheKey = formLocation + "#" + formName;
+                ModelForm modelForm = formLocationCache.get(cacheKey);
+                if (modelForm == null) {
+                    modelForm = createModelForm(formElement, entityModelReader, dispatchContext, formLocation, formName);
+                    modelForm = formLocationCache.putIfAbsentAndGet(cacheKey, modelForm);
+                }
+                modelFormMap.put(formName, modelForm);
+            }
+        }
+        return modelFormMap;
+    }
+
+    public static ModelForm createModelForm(Document formFileDoc, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation, String formName) {
+        Element formElement = UtilXml.firstChildElement(formFileDoc.getDocumentElement(), "form", "name", formName);
+        return createModelForm(formElement, entityModelReader, dispatchContext, formLocation, formName);
+    }
+
+    public static ModelForm createModelForm(Element formElement, ModelReader entityModelReader, DispatchContext dispatchContext, String formLocation, String formName) {
+        ModelForm modelForm = new ModelForm(formElement, formLocation, entityModelReader, dispatchContext);
+        return modelForm;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java b/framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java
rename to framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java
index c74cb2b..66bb671 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java
@@ -1,312 +1,311 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.cache.UtilCache;
-import org.ofbiz.base.util.collections.MapStack;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.base.util.template.FreeMarkerWorker;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.html.HtmlWidgetRenderer;
-import org.w3c.dom.Element;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.beans.CollectionModel;
-import freemarker.ext.beans.StringModel;
-import freemarker.template.Configuration;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.Version;
-
-/**
- * Widget Library - Screen model HTML class.
- */
-@SuppressWarnings("serial")
-public class HtmlWidget extends ModelScreenWidget {
-    public static final String module = HtmlWidget.class.getName();
-
-    private static final UtilCache<String, Template> specialTemplateCache = UtilCache.createUtilCache("widget.screen.template.ftl.general", 0, 0, false);
-    protected static Configuration specialConfig = FreeMarkerWorker.makeConfiguration(new ExtendedWrapper(FreeMarkerWorker.version));
-
-    // not sure if this is the best way to get FTL to use my fancy MapModel derivative, but should work at least...
-    public static class ExtendedWrapper extends BeansWrapper {
-        public ExtendedWrapper(Version version) {
-            super(version);
-        }
-
-        @Override
-        public TemplateModel wrap(Object object) throws TemplateModelException {
-            // This StringHtmlWrapperForFtl option seems to be the best option
-            // and handles most things without causing too many problems
-            if (object instanceof String) {
-                return new StringHtmlWrapperForFtl((String) object, this);
-            } else if (object instanceof Collection && !(object instanceof Map)) {
-                // An additional wrapper to ensure ${aCollection} is properly encoded for html
-                return new CollectionHtmlWrapperForFtl((Collection<?>) object, this);
-            }
-            return super.wrap(object);
-        }
-    }
-
-    public static class StringHtmlWrapperForFtl extends StringModel {
-        public StringHtmlWrapperForFtl(String str, BeansWrapper wrapper) {
-            super(str, wrapper);
-        }
-        @Override
-        public String getAsString() {
-            return UtilCodec.getEncoder("html").encode(super.getAsString());
-        }
-    }
-
-    public static class CollectionHtmlWrapperForFtl extends CollectionModel {
-
-        public CollectionHtmlWrapperForFtl(Collection<?> collection, BeansWrapper wrapper) {
-            super(collection, wrapper);
-        }
-
-        @Override
-        public String getAsString() {
-            return UtilCodec.getEncoder("html").encode(super.getAsString());
-        }
-
-    }
-
-    // End Static, begin class section
-
-    private final List<ModelScreenWidget> subWidgets;
-
-    public HtmlWidget(ModelScreen modelScreen, Element htmlElement) {
-        super(modelScreen, htmlElement);
-        List<? extends Element> childElementList = UtilXml.childElementList(htmlElement);
-        if (childElementList.isEmpty()) {
-            this.subWidgets = Collections.emptyList();
-        } else {
-            List<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(childElementList.size());
-            for (Element childElement : childElementList) {
-                if ("html-template".equals(childElement.getNodeName())) {
-                    subWidgets.add(new HtmlTemplate(modelScreen, childElement));
-                } else if ("html-template-decorator".equals(childElement.getNodeName())) {
-                    subWidgets.add(new HtmlTemplateDecorator(modelScreen, childElement));
-                } else {
-                    throw new IllegalArgumentException("Tag not supported under the platform-specific -> html tag with name: "
-                            + childElement.getNodeName());
-                }
-            }
-            this.subWidgets = Collections.unmodifiableList(subWidgets);
-        }
-    }
-
-    public List<ModelScreenWidget> getSubWidgets() {
-        return subWidgets;
-    }
-
-    @Override
-    public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-        for (ModelScreenWidget subWidget : subWidgets) {
-            subWidget.renderWidgetString(writer, context, screenStringRenderer);
-        }
-    }
-
-    public static void renderHtmlTemplate(Appendable writer, FlexibleStringExpander locationExdr, Map<String, Object> context) {
-        String location = locationExdr.expandString(context);
-        //Debug.logInfo("Rendering template at location [" + location + "] with context: \n" + context, module);
-
-        if (UtilValidate.isEmpty(location)) {
-            throw new IllegalArgumentException("Template location is empty");
-        }
-
-        if (location.endsWith(".ftl")) {
-            try {
-                Map<String, ? extends Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
-                boolean insertWidgetBoundaryComments = ModelWidget.widgetBoundaryCommentsEnabled(parameters);
-                if (insertWidgetBoundaryComments) {
-                    writer.append(HtmlWidgetRenderer.formatBoundaryComment("Begin", "Template", location));
-                }
-
-                //FreeMarkerWorker.renderTemplateAtLocation(location, context, writer);
-                Template template = null;
-                if (location.endsWith(".fo.ftl")) { // FOP can't render correctly escaped characters
-                    template = FreeMarkerWorker.getTemplate(location);
-                } else {
-                    template = FreeMarkerWorker.getTemplate(location, specialTemplateCache, specialConfig);
-                }
-                FreeMarkerWorker.renderTemplate(template, context, writer);
-
-                if (insertWidgetBoundaryComments) {
-                    writer.append(HtmlWidgetRenderer.formatBoundaryComment("End", "Template", location));
-                }
-            } catch (IllegalArgumentException e) {
-                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                writeError(writer, errMsg);
-            } catch (MalformedURLException e) {
-                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                writeError(writer, errMsg);
-            } catch (TemplateException e) {
-                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                writeError(writer, errMsg);
-            } catch (IOException e) {
-                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                writeError(writer, errMsg);
-            }
-        } else {
-            throw new IllegalArgumentException("Rendering not yet supported for the template at location: " + location);
-        }
-    }
-
-    // TODO: We can make this more fancy, but for now this is very functional
-    public static void writeError(Appendable writer, String message) {
-        try {
-            writer.append(message);
-        } catch (IOException e) {
-        }
-    }
-
-    public static class HtmlTemplate extends ModelScreenWidget {
-        protected FlexibleStringExpander locationExdr;
-
-        public HtmlTemplate(ModelScreen modelScreen, Element htmlTemplateElement) {
-            super(modelScreen, htmlTemplateElement);
-            this.locationExdr = FlexibleStringExpander.getInstance(htmlTemplateElement.getAttribute("location"));
-        }
-
-        public String getLocation(Map<String, Object> context) {
-            return locationExdr.expandString(context);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            renderHtmlTemplate(writer, this.locationExdr, context);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getLocationExdr() {
-            return locationExdr;
-        }
-    }
-
-    public static class HtmlTemplateDecorator extends ModelScreenWidget {
-        protected FlexibleStringExpander locationExdr;
-        protected Map<String, ModelScreenWidget> sectionMap = new HashMap<String, ModelScreenWidget>();
-
-        public HtmlTemplateDecorator(ModelScreen modelScreen, Element htmlTemplateDecoratorElement) {
-            super(modelScreen, htmlTemplateDecoratorElement);
-            this.locationExdr = FlexibleStringExpander.getInstance(htmlTemplateDecoratorElement.getAttribute("location"));
-
-            List<? extends Element> htmlTemplateDecoratorSectionElementList = UtilXml.childElementList(htmlTemplateDecoratorElement, "html-template-decorator-section");
-            for (Element htmlTemplateDecoratorSectionElement: htmlTemplateDecoratorSectionElementList) {
-                String name = htmlTemplateDecoratorSectionElement.getAttribute("name");
-                this.sectionMap.put(name, new HtmlTemplateDecoratorSection(modelScreen, htmlTemplateDecoratorSectionElement));
-            }
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            // isolate the scope
-            MapStack<String> contextMs;
-            if (!(context instanceof MapStack<?>)) {
-                contextMs = MapStack.create(context);
-                context = contextMs;
-            } else {
-                contextMs = UtilGenerics.cast(context);
-            }
-
-            // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down
-            MapStack<String> standAloneStack = contextMs.standAloneChildStack();
-            standAloneStack.put("screens", new ScreenRenderer(writer, standAloneStack, screenStringRenderer));
-            SectionsRenderer sections = new SectionsRenderer(this.sectionMap, standAloneStack, writer, screenStringRenderer);
-
-            // put the sectionMap in the context, make sure it is in the sub-scope, ie after calling push on the MapStack
-            contextMs.push();
-            context.put("sections", sections);
-
-            renderHtmlTemplate(writer, this.locationExdr, context);
-            contextMs.pop();
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getLocationExdr() {
-            return locationExdr;
-        }
-
-        public Map<String, ModelScreenWidget> getSectionMap() {
-            return sectionMap;
-        }
-    }
-
-    public static class HtmlTemplateDecoratorSection extends ModelScreenWidget {
-        protected List<ModelScreenWidget> subWidgets;
-
-        public HtmlTemplateDecoratorSection(ModelScreen modelScreen, Element htmlTemplateDecoratorSectionElement) {
-            super(modelScreen, htmlTemplateDecoratorSectionElement);
-            List<? extends Element> subElementList = UtilXml.childElementList(htmlTemplateDecoratorSectionElement);
-            this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            // render sub-widgets
-            renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public List<ModelScreenWidget> getSubWidgets() {
-            return subWidgets;
-        }
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.cache.UtilCache;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.base.util.template.FreeMarkerWorker;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.html.HtmlWidgetRenderer;
+import org.w3c.dom.Element;
+
+import freemarker.ext.beans.BeansWrapper;
+import freemarker.ext.beans.CollectionModel;
+import freemarker.ext.beans.StringModel;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModel;
+import freemarker.template.TemplateModelException;
+import freemarker.template.Version;
+
+/**
+ * Widget Library - Screen model HTML class.
+ */
+@SuppressWarnings("serial")
+public class HtmlWidget extends ModelScreenWidget {
+    public static final String module = HtmlWidget.class.getName();
+
+    private static final UtilCache<String, Template> specialTemplateCache = UtilCache.createUtilCache("widget.screen.template.ftl.general", 0, 0, false);
+    protected static Configuration specialConfig = FreeMarkerWorker.makeConfiguration(new ExtendedWrapper(FreeMarkerWorker.version));
+
+    // not sure if this is the best way to get FTL to use my fancy MapModel derivative, but should work at least...
+    public static class ExtendedWrapper extends BeansWrapper {
+        public ExtendedWrapper(Version version) {
+            super(version);
+        }
+
+        @Override
+        public TemplateModel wrap(Object object) throws TemplateModelException {
+            // This StringHtmlWrapperForFtl option seems to be the best option
+            // and handles most things without causing too many problems
+            if (object instanceof String) {
+                return new StringHtmlWrapperForFtl((String) object, this);
+            } else if (object instanceof Collection && !(object instanceof Map)) {
+                // An additional wrapper to ensure ${aCollection} is properly encoded for html
+                return new CollectionHtmlWrapperForFtl((Collection<?>) object, this);
+            }
+            return super.wrap(object);
+        }
+    }
+
+    public static class StringHtmlWrapperForFtl extends StringModel {
+        public StringHtmlWrapperForFtl(String str, BeansWrapper wrapper) {
+            super(str, wrapper);
+        }
+        @Override
+        public String getAsString() {
+            return UtilCodec.getEncoder("html").encode(super.getAsString());
+        }
+    }
+
+    public static class CollectionHtmlWrapperForFtl extends CollectionModel {
+
+        public CollectionHtmlWrapperForFtl(Collection<?> collection, BeansWrapper wrapper) {
+            super(collection, wrapper);
+        }
+
+        @Override
+        public String getAsString() {
+            return UtilCodec.getEncoder("html").encode(super.getAsString());
+        }
+
+    }
+
+    // End Static, begin class section
+
+    private final List<ModelScreenWidget> subWidgets;
+
+    public HtmlWidget(ModelScreen modelScreen, Element htmlElement) {
+        super(modelScreen, htmlElement);
+        List<? extends Element> childElementList = UtilXml.childElementList(htmlElement);
+        if (childElementList.isEmpty()) {
+            this.subWidgets = Collections.emptyList();
+        } else {
+            List<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(childElementList.size());
+            for (Element childElement : childElementList) {
+                if ("html-template".equals(childElement.getNodeName())) {
+                    subWidgets.add(new HtmlTemplate(modelScreen, childElement));
+                } else if ("html-template-decorator".equals(childElement.getNodeName())) {
+                    subWidgets.add(new HtmlTemplateDecorator(modelScreen, childElement));
+                } else {
+                    throw new IllegalArgumentException("Tag not supported under the platform-specific -> html tag with name: "
+                            + childElement.getNodeName());
+                }
+            }
+            this.subWidgets = Collections.unmodifiableList(subWidgets);
+        }
+    }
+
+    public List<ModelScreenWidget> getSubWidgets() {
+        return subWidgets;
+    }
+
+    @Override
+    public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+        for (ModelScreenWidget subWidget : subWidgets) {
+            subWidget.renderWidgetString(writer, context, screenStringRenderer);
+        }
+    }
+
+    public static void renderHtmlTemplate(Appendable writer, FlexibleStringExpander locationExdr, Map<String, Object> context) {
+        String location = locationExdr.expandString(context);
+        //Debug.logInfo("Rendering template at location [" + location + "] with context: \n" + context, module);
+
+        if (UtilValidate.isEmpty(location)) {
+            throw new IllegalArgumentException("Template location is empty");
+        }
+
+        if (location.endsWith(".ftl")) {
+            try {
+                Map<String, ? extends Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
+                boolean insertWidgetBoundaryComments = ModelWidget.widgetBoundaryCommentsEnabled(parameters);
+                if (insertWidgetBoundaryComments) {
+                    writer.append(HtmlWidgetRenderer.formatBoundaryComment("Begin", "Template", location));
+                }
+
+                //FreeMarkerWorker.renderTemplateAtLocation(location, context, writer);
+                Template template = null;
+                if (location.endsWith(".fo.ftl")) { // FOP can't render correctly escaped characters
+                    template = FreeMarkerWorker.getTemplate(location);
+                } else {
+                    template = FreeMarkerWorker.getTemplate(location, specialTemplateCache, specialConfig);
+                }
+                FreeMarkerWorker.renderTemplate(template, context, writer);
+
+                if (insertWidgetBoundaryComments) {
+                    writer.append(HtmlWidgetRenderer.formatBoundaryComment("End", "Template", location));
+                }
+            } catch (IllegalArgumentException e) {
+                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                writeError(writer, errMsg);
+            } catch (MalformedURLException e) {
+                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                writeError(writer, errMsg);
+            } catch (TemplateException e) {
+                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                writeError(writer, errMsg);
+            } catch (IOException e) {
+                String errMsg = "Error rendering included template at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                writeError(writer, errMsg);
+            }
+        } else {
+            throw new IllegalArgumentException("Rendering not yet supported for the template at location: " + location);
+        }
+    }
+
+    // TODO: We can make this more fancy, but for now this is very functional
+    public static void writeError(Appendable writer, String message) {
+        try {
+            writer.append(message);
+        } catch (IOException e) {
+        }
+    }
+
+    public static class HtmlTemplate extends ModelScreenWidget {
+        protected FlexibleStringExpander locationExdr;
+
+        public HtmlTemplate(ModelScreen modelScreen, Element htmlTemplateElement) {
+            super(modelScreen, htmlTemplateElement);
+            this.locationExdr = FlexibleStringExpander.getInstance(htmlTemplateElement.getAttribute("location"));
+        }
+
+        public String getLocation(Map<String, Object> context) {
+            return locationExdr.expandString(context);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            renderHtmlTemplate(writer, this.locationExdr, context);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getLocationExdr() {
+            return locationExdr;
+        }
+    }
+
+    public static class HtmlTemplateDecorator extends ModelScreenWidget {
+        protected FlexibleStringExpander locationExdr;
+        protected Map<String, ModelScreenWidget> sectionMap = new HashMap<String, ModelScreenWidget>();
+
+        public HtmlTemplateDecorator(ModelScreen modelScreen, Element htmlTemplateDecoratorElement) {
+            super(modelScreen, htmlTemplateDecoratorElement);
+            this.locationExdr = FlexibleStringExpander.getInstance(htmlTemplateDecoratorElement.getAttribute("location"));
+
+            List<? extends Element> htmlTemplateDecoratorSectionElementList = UtilXml.childElementList(htmlTemplateDecoratorElement, "html-template-decorator-section");
+            for (Element htmlTemplateDecoratorSectionElement: htmlTemplateDecoratorSectionElementList) {
+                String name = htmlTemplateDecoratorSectionElement.getAttribute("name");
+                this.sectionMap.put(name, new HtmlTemplateDecoratorSection(modelScreen, htmlTemplateDecoratorSectionElement));
+            }
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            // isolate the scope
+            MapStack<String> contextMs;
+            if (!(context instanceof MapStack<?>)) {
+                contextMs = MapStack.create(context);
+                context = contextMs;
+            } else {
+                contextMs = UtilGenerics.cast(context);
+            }
+
+            // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down
+            MapStack<String> standAloneStack = contextMs.standAloneChildStack();
+            standAloneStack.put("screens", new ScreenRenderer(writer, standAloneStack, screenStringRenderer));
+            SectionsRenderer sections = new SectionsRenderer(this.sectionMap, standAloneStack, writer, screenStringRenderer);
+
+            // put the sectionMap in the context, make sure it is in the sub-scope, ie after calling push on the MapStack
+            contextMs.push();
+            context.put("sections", sections);
+
+            renderHtmlTemplate(writer, this.locationExdr, context);
+            contextMs.pop();
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getLocationExdr() {
+            return locationExdr;
+        }
+
+        public Map<String, ModelScreenWidget> getSectionMap() {
+            return sectionMap;
+        }
+    }
+
+    public static class HtmlTemplateDecoratorSection extends ModelScreenWidget {
+        protected List<ModelScreenWidget> subWidgets;
+
+        public HtmlTemplateDecoratorSection(ModelScreen modelScreen, Element htmlTemplateDecoratorSectionElement) {
+            super(modelScreen, htmlTemplateDecoratorSectionElement);
+            List<? extends Element> subElementList = UtilXml.childElementList(htmlTemplateDecoratorSectionElement);
+            this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            // render sub-widgets
+            renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public List<ModelScreenWidget> getSubWidgets() {
+            return subWidgets;
+        }
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/IterateSectionWidget.java b/framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/screen/IterateSectionWidget.java
rename to framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java
index 3ae2fce..670ca9b 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/IterateSectionWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java
@@ -1,387 +1,387 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.collections.MapStack;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.WidgetWorker;
-import org.w3c.dom.Element;
-
-
-/**
- * Widget Library - Screen model HTML class
- */
-@SuppressWarnings("serial")
-public class IterateSectionWidget extends ModelScreenWidget {
-
-    public static final String module = IterateSectionWidget.class.getName();
-    public static int DEFAULT_PAGE_SIZE = 5;
-    public static int MAX_PAGE_SIZE = 10000;
-
-    private final List<ModelScreenWidget.Section> sectionList;
-    private final FlexibleMapAccessor<Object> listNameExdr;
-    private final FlexibleStringExpander entryNameExdr;
-    private final FlexibleStringExpander keyNameExdr;
-    private final FlexibleStringExpander paginateTarget;
-    private final FlexibleStringExpander paginate;
-    private final int viewSize;
-
-    public IterateSectionWidget(ModelScreen modelScreen, Element iterateSectionElement) {
-        super(modelScreen, iterateSectionElement);
-        String listName = iterateSectionElement.getAttribute("list");
-        if (listName.isEmpty()) {
-            listName = iterateSectionElement.getAttribute("list-name");
-        }
-        this.listNameExdr = FlexibleMapAccessor.getInstance(listName);
-        String entryName = iterateSectionElement.getAttribute("entry");
-        if (entryName.isEmpty()) {
-            entryName = iterateSectionElement.getAttribute("entry-name");
-        }
-        this.entryNameExdr = FlexibleStringExpander.getInstance(entryName);
-        String keyName = iterateSectionElement.getAttribute("key");
-        if (keyName.isEmpty()) {
-            keyName = iterateSectionElement.getAttribute("key-name");
-        }
-        this.keyNameExdr = FlexibleStringExpander.getInstance(keyName);
-        this.paginateTarget = FlexibleStringExpander.getInstance(iterateSectionElement.getAttribute("paginate-target"));
-        this.paginate = FlexibleStringExpander.getInstance(iterateSectionElement.getAttribute("paginate"));
-        int viewSize = DEFAULT_PAGE_SIZE;
-        String viewSizeStr = iterateSectionElement.getAttribute("view-size");
-        if (!viewSizeStr.isEmpty()) {
-            viewSize = Integer.parseInt(viewSizeStr);
-        }
-        this.viewSize = viewSize;
-        List<? extends Element> childElementList = UtilXml.childElementList(iterateSectionElement);
-        if (childElementList.isEmpty()) {
-            this.sectionList = Collections.emptyList();
-        } else {
-            List<ModelScreenWidget.Section> sectionList = new ArrayList<ModelScreenWidget.Section>(childElementList.size());
-            for (Element sectionElement: childElementList) {
-                ModelScreenWidget.Section section = new ModelScreenWidget.Section(modelScreen, sectionElement, false);
-                sectionList.add(section);
-            }
-            this.sectionList = Collections.unmodifiableList(sectionList);
-        }
-    }
-
-    public List<ModelScreenWidget.Section> getSectionList() {
-        return sectionList;
-    }
-
-    @Override
-    public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-        int viewIndex = 0;
-        int viewSize = this.viewSize;
-        int lowIndex = -1;
-        int highIndex = -1;
-        int listSize = 0;
-        int actualPageSize = 0;
-
-        boolean isEntrySet = false;
-        // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down
-        MapStack<String> contextMs = MapStack.create(context);
-
-        String entryName = this.entryNameExdr.expandString(context);
-        String keyName = this.keyNameExdr.expandString(context);
-        Object obj = listNameExdr.get(context);
-        if (obj == null) {
-            Debug.logError("No object found for listName:" + listNameExdr.toString(), module);
-            return;
-        }
-        List<?> theList = null;
-        if (obj instanceof Map<?, ?>) {
-            Set<Map.Entry<String, Object>> entrySet = UtilGenerics.<Map<String, Object>>cast(obj).entrySet();
-            Object [] a = entrySet.toArray();
-            theList = Arrays.asList(a);
-            isEntrySet = true;
-        } else if (obj instanceof List<?>) {
-            theList = (List<?>)obj;
-        } else {
-            Debug.logError("Object not list or map type", module);
-            return;
-        }
-        listSize = theList.size();
-        WidgetWorker.incrementPaginatorNumber(context);
-        int startPageNumber = WidgetWorker.getPaginatorNumber(context);
-
-        if (getPaginate(context)) {
-            try {
-                Map<String, String> params = UtilGenerics.cast(context.get("parameters"));
-                String viewIndexString = params.get("VIEW_INDEX" + "_" + WidgetWorker.getPaginatorNumber(context));
-                String viewSizeString = params.get("VIEW_SIZE" + "_" + WidgetWorker.getPaginatorNumber(context));
-                viewIndex = Integer.parseInt(viewIndexString);
-                viewSize = Integer.parseInt(viewSizeString);
-            } catch (Exception e) {
-                try {
-                    viewIndex = ((Integer) context.get("viewIndex")).intValue();
-                } catch (Exception e2) {
-                    viewIndex = 0;
-                }
-            }
-            context.put("viewIndex", Integer.valueOf(viewIndex));
-            lowIndex = viewIndex * viewSize;
-            highIndex = (viewIndex + 1) * viewSize;
-        } else {
-            viewIndex = 0;
-            viewSize = MAX_PAGE_SIZE;
-            lowIndex = 0;
-            highIndex = MAX_PAGE_SIZE;
-        }
-        Iterator<?> iter = theList.iterator();
-        int itemIndex = -1;
-        int iterateIndex = 0;
-        while (iter.hasNext()) {
-            itemIndex++;
-            if (itemIndex >= highIndex) {
-                break;
-            }
-            Object item = iter.next();
-            if (itemIndex < lowIndex) {
-                continue;
-            }
-            if (isEntrySet) {
-                Map.Entry<String, ?> entry = UtilGenerics.cast(item);
-                contextMs.put(entryName, entry.getValue());
-                contextMs.put(keyName, entry.getKey());
-            } else {
-                contextMs.put(entryName, item);
-            }
-            contextMs.put("itemIndex", Integer.valueOf(itemIndex));
-
-            if (iterateIndex < listSize) {
-                contextMs.put("iterateId",String.valueOf(entryName+iterateIndex));
-                iterateIndex++;
-            }
-            for (ModelScreenWidget.Section section: this.sectionList) {
-                section.renderWidgetString(writer, contextMs, screenStringRenderer);
-            }
-        }
-
-        if ((itemIndex + 1) < highIndex) {
-            highIndex = itemIndex + 1;
-        }
-        actualPageSize = highIndex - lowIndex;
-        if (getPaginate(context)) {
-            try {
-                Integer lastPageNumber = null;
-                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
-                if (globalCtx != null) {
-                    lastPageNumber = (Integer)globalCtx.get("PAGINATOR_NUMBER");
-                    globalCtx.put("PAGINATOR_NUMBER", Integer.valueOf(startPageNumber));
-                }
-                renderNextPrev(writer, context, listSize, actualPageSize);
-                if (globalCtx != null) {
-                    globalCtx.put("PAGINATOR_NUMBER", lastPageNumber);
-                }
-            } catch (IOException e) {
-                Debug.logError(e, module);
-                throw new RuntimeException(e.getMessage());
-            }
-        }
-
-    }
-    /*
-     * @return
-     */
-    public String getPaginateTarget(Map<String, Object> context) {
-        return this.paginateTarget.expandString(context);
-    }
-
-    public boolean getPaginate(Map<String, Object> context) {
-        if (!this.paginate.isEmpty() && UtilValidate.isNotEmpty(this.paginate.expandString(context))) {
-            return Boolean.valueOf(this.paginate.expandString(context)).booleanValue();
-        } else {
-            return true;
-        }
-    }
-
-    public int getViewSize() {
-        return viewSize;
-    }
-
-    public void renderNextPrev(Appendable writer, Map<String, Object> context, int listSize, int actualPageSize) throws IOException {
-        String targetService = this.getPaginateTarget(context);
-        if (targetService == null) {
-            targetService = "${targetService}";
-        }
-
-        Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters"));
-        Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap"));
-        if (UtilValidate.isNotEmpty(queryStringMap)) {
-            inputFields.putAll(queryStringMap);
-        }
-
-        String queryString = UtilHttp.urlEncodeArgs(inputFields);
-        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
-        queryString = UtilHttp.stripViewParamsFromQueryString(queryString, "" + paginatorNumber);
-
-
-
-
-        if (UtilValidate.isEmpty(targetService)) {
-            Debug.logWarning("TargetService is empty.", module);
-            return;
-        }
-
-        int viewIndex = -1;
-        try {
-            viewIndex = ((Integer) context.get("viewIndex")).intValue();
-        } catch (Exception e) {
-            viewIndex = 0;
-        }
-
-        int viewSize = -1;
-        try {
-            viewSize = ((Integer) context.get("viewSize")).intValue();
-        } catch (Exception e) {
-            viewSize = this.getViewSize();
-        }
-
-
-        /*
-        int highIndex = -1;
-        try {
-            highIndex = modelForm.getHighIndex();
-        } catch (Exception e) {
-            highIndex = 0;
-        }
-
-        int lowIndex = -1;
-        try {
-            lowIndex = modelForm.getLowIndex();
-        } catch (Exception e) {
-            lowIndex = 0;
-        }
-         */
-
-        int lowIndex = viewIndex * viewSize;
-        int highIndex = (viewIndex + 1) * viewSize;
-        // if this is all there seems to be (if listSize < 0, then size is unknown)
-        if (actualPageSize >= listSize && listSize > 0) {
-            return;
-        }
-
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-
-        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-
-        writer.append("<table border=\"0\" width=\"100%\" cellpadding=\"2\">\n");
-        writer.append("  <tr>\n");
-        writer.append("    <td align=\"right\">\n");
-        writer.append("      <b>\n");
-        if (viewIndex > 0) {
-            writer.append(" <a href=\"");
-            StringBuilder linkText = new StringBuilder(targetService);
-            if (linkText.indexOf("?") < 0)  linkText.append("?");
-            else linkText.append("&amp;");
-            //if (queryString != null && !queryString.equals("null")) linkText += queryString + "&";
-            if (UtilValidate.isNotEmpty(queryString)) {
-                linkText.append(queryString).append("&amp;");
-            }
-            linkText.append("VIEW_SIZE_"+ paginatorNumber + "=").append(viewSize).append("&amp;VIEW_INDEX_" + paginatorNumber + "=").append(viewIndex - 1).append("\"");
-
-            // make the link
-            writer.append(rh.makeLink(request, response, linkText.toString(), false, false, false));
-            String previous = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", (Locale) context.get("locale"));
-            writer.append(" class=\"buttontext\">[").append(previous).append("]</a>\n");
-
-        }
-        if (listSize > 0) {
-            Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize));
-            String commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale"));
-            writer.append(" <span class=\"tabletext\">").append(commonDisplaying).append("</span> \n");
-        }
-        if (highIndex < listSize) {
-            writer.append(" <a href=\"");
-            StringBuilder linkText = new StringBuilder(targetService);
-            if (linkText.indexOf("?") < 0)  linkText.append("?");
-            else linkText.append("&amp;");
-            if (UtilValidate.isNotEmpty(queryString)) {
-                linkText.append(queryString).append("&amp;");
-            }
-            linkText.append("VIEW_SIZE_" + paginatorNumber + "=").append(viewSize).append("&amp;VIEW_INDEX_" + paginatorNumber + "=").append(viewIndex + 1).append("\"");
-
-            // make the link
-            writer.append(rh.makeLink(request, response, linkText.toString(), false, false, false));
-            String next = UtilProperties.getMessage("CommonUiLabels", "CommonNext", (Locale) context.get("locale"));
-            writer.append(" class=\"buttontext\">[").append(next).append("]</a>\n");
-
-        }
-        writer.append("      </b>\n");
-        writer.append("    </td>\n");
-        writer.append("  </tr>\n");
-        writer.append("</table>\n");
-
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
-    }
-
-    public FlexibleMapAccessor<Object> getListNameExdr() {
-        return listNameExdr;
-    }
-
-    public FlexibleStringExpander getEntryNameExdr() {
-        return entryNameExdr;
-    }
-
-    public FlexibleStringExpander getKeyNameExdr() {
-        return keyNameExdr;
-    }
-
-    public FlexibleStringExpander getPaginateTarget() {
-        return paginateTarget;
-    }
-
-    public FlexibleStringExpander getPaginate() {
-        return paginate;
-    }
-
-}
-
-
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.webapp.control.RequestHandler;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.w3c.dom.Element;
+
+
+/**
+ * Widget Library - Screen model HTML class
+ */
+@SuppressWarnings("serial")
+public class IterateSectionWidget extends ModelScreenWidget {
+
+    public static final String module = IterateSectionWidget.class.getName();
+    public static int DEFAULT_PAGE_SIZE = 5;
+    public static int MAX_PAGE_SIZE = 10000;
+
+    private final List<ModelScreenWidget.Section> sectionList;
+    private final FlexibleMapAccessor<Object> listNameExdr;
+    private final FlexibleStringExpander entryNameExdr;
+    private final FlexibleStringExpander keyNameExdr;
+    private final FlexibleStringExpander paginateTarget;
+    private final FlexibleStringExpander paginate;
+    private final int viewSize;
+
+    public IterateSectionWidget(ModelScreen modelScreen, Element iterateSectionElement) {
+        super(modelScreen, iterateSectionElement);
+        String listName = iterateSectionElement.getAttribute("list");
+        if (listName.isEmpty()) {
+            listName = iterateSectionElement.getAttribute("list-name");
+        }
+        this.listNameExdr = FlexibleMapAccessor.getInstance(listName);
+        String entryName = iterateSectionElement.getAttribute("entry");
+        if (entryName.isEmpty()) {
+            entryName = iterateSectionElement.getAttribute("entry-name");
+        }
+        this.entryNameExdr = FlexibleStringExpander.getInstance(entryName);
+        String keyName = iterateSectionElement.getAttribute("key");
+        if (keyName.isEmpty()) {
+            keyName = iterateSectionElement.getAttribute("key-name");
+        }
+        this.keyNameExdr = FlexibleStringExpander.getInstance(keyName);
+        this.paginateTarget = FlexibleStringExpander.getInstance(iterateSectionElement.getAttribute("paginate-target"));
+        this.paginate = FlexibleStringExpander.getInstance(iterateSectionElement.getAttribute("paginate"));
+        int viewSize = DEFAULT_PAGE_SIZE;
+        String viewSizeStr = iterateSectionElement.getAttribute("view-size");
+        if (!viewSizeStr.isEmpty()) {
+            viewSize = Integer.parseInt(viewSizeStr);
+        }
+        this.viewSize = viewSize;
+        List<? extends Element> childElementList = UtilXml.childElementList(iterateSectionElement);
+        if (childElementList.isEmpty()) {
+            this.sectionList = Collections.emptyList();
+        } else {
+            List<ModelScreenWidget.Section> sectionList = new ArrayList<ModelScreenWidget.Section>(childElementList.size());
+            for (Element sectionElement: childElementList) {
+                ModelScreenWidget.Section section = new ModelScreenWidget.Section(modelScreen, sectionElement, false);
+                sectionList.add(section);
+            }
+            this.sectionList = Collections.unmodifiableList(sectionList);
+        }
+    }
+
+    public List<ModelScreenWidget.Section> getSectionList() {
+        return sectionList;
+    }
+
+    @Override
+    public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+        int viewIndex = 0;
+        int viewSize = this.viewSize;
+        int lowIndex = -1;
+        int highIndex = -1;
+        int listSize = 0;
+        int actualPageSize = 0;
+
+        boolean isEntrySet = false;
+        // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down
+        MapStack<String> contextMs = MapStack.create(context);
+
+        String entryName = this.entryNameExdr.expandString(context);
+        String keyName = this.keyNameExdr.expandString(context);
+        Object obj = listNameExdr.get(context);
+        if (obj == null) {
+            Debug.logError("No object found for listName:" + listNameExdr.toString(), module);
+            return;
+        }
+        List<?> theList = null;
+        if (obj instanceof Map<?, ?>) {
+            Set<Map.Entry<String, Object>> entrySet = UtilGenerics.<Map<String, Object>>cast(obj).entrySet();
+            Object [] a = entrySet.toArray();
+            theList = Arrays.asList(a);
+            isEntrySet = true;
+        } else if (obj instanceof List<?>) {
+            theList = (List<?>)obj;
+        } else {
+            Debug.logError("Object not list or map type", module);
+            return;
+        }
+        listSize = theList.size();
+        WidgetWorker.incrementPaginatorNumber(context);
+        int startPageNumber = WidgetWorker.getPaginatorNumber(context);
+
+        if (getPaginate(context)) {
+            try {
+                Map<String, String> params = UtilGenerics.cast(context.get("parameters"));
+                String viewIndexString = params.get("VIEW_INDEX" + "_" + WidgetWorker.getPaginatorNumber(context));
+                String viewSizeString = params.get("VIEW_SIZE" + "_" + WidgetWorker.getPaginatorNumber(context));
+                viewIndex = Integer.parseInt(viewIndexString);
+                viewSize = Integer.parseInt(viewSizeString);
+            } catch (Exception e) {
+                try {
+                    viewIndex = ((Integer) context.get("viewIndex")).intValue();
+                } catch (Exception e2) {
+                    viewIndex = 0;
+                }
+            }
+            context.put("viewIndex", Integer.valueOf(viewIndex));
+            lowIndex = viewIndex * viewSize;
+            highIndex = (viewIndex + 1) * viewSize;
+        } else {
+            viewIndex = 0;
+            viewSize = MAX_PAGE_SIZE;
+            lowIndex = 0;
+            highIndex = MAX_PAGE_SIZE;
+        }
+        Iterator<?> iter = theList.iterator();
+        int itemIndex = -1;
+        int iterateIndex = 0;
+        while (iter.hasNext()) {
+            itemIndex++;
+            if (itemIndex >= highIndex) {
+                break;
+            }
+            Object item = iter.next();
+            if (itemIndex < lowIndex) {
+                continue;
+            }
+            if (isEntrySet) {
+                Map.Entry<String, ?> entry = UtilGenerics.cast(item);
+                contextMs.put(entryName, entry.getValue());
+                contextMs.put(keyName, entry.getKey());
+            } else {
+                contextMs.put(entryName, item);
+            }
+            contextMs.put("itemIndex", Integer.valueOf(itemIndex));
+
+            if (iterateIndex < listSize) {
+                contextMs.put("iterateId",String.valueOf(entryName+iterateIndex));
+                iterateIndex++;
+            }
+            for (ModelScreenWidget.Section section: this.sectionList) {
+                section.renderWidgetString(writer, contextMs, screenStringRenderer);
+            }
+        }
+
+        if ((itemIndex + 1) < highIndex) {
+            highIndex = itemIndex + 1;
+        }
+        actualPageSize = highIndex - lowIndex;
+        if (getPaginate(context)) {
+            try {
+                Integer lastPageNumber = null;
+                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
+                if (globalCtx != null) {
+                    lastPageNumber = (Integer)globalCtx.get("PAGINATOR_NUMBER");
+                    globalCtx.put("PAGINATOR_NUMBER", Integer.valueOf(startPageNumber));
+                }
+                renderNextPrev(writer, context, listSize, actualPageSize);
+                if (globalCtx != null) {
+                    globalCtx.put("PAGINATOR_NUMBER", lastPageNumber);
+                }
+            } catch (IOException e) {
+                Debug.logError(e, module);
+                throw new RuntimeException(e.getMessage());
+            }
+        }
+
+    }
+    /*
+     * @return
+     */
+    public String getPaginateTarget(Map<String, Object> context) {
+        return this.paginateTarget.expandString(context);
+    }
+
+    public boolean getPaginate(Map<String, Object> context) {
+        if (!this.paginate.isEmpty() && UtilValidate.isNotEmpty(this.paginate.expandString(context))) {
+            return Boolean.valueOf(this.paginate.expandString(context)).booleanValue();
+        } else {
+            return true;
+        }
+    }
+
+    public int getViewSize() {
+        return viewSize;
+    }
+
+    public void renderNextPrev(Appendable writer, Map<String, Object> context, int listSize, int actualPageSize) throws IOException {
+        String targetService = this.getPaginateTarget(context);
+        if (targetService == null) {
+            targetService = "${targetService}";
+        }
+
+        Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters"));
+        Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap"));
+        if (UtilValidate.isNotEmpty(queryStringMap)) {
+            inputFields.putAll(queryStringMap);
+        }
+
+        String queryString = UtilHttp.urlEncodeArgs(inputFields);
+        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
+        queryString = UtilHttp.stripViewParamsFromQueryString(queryString, "" + paginatorNumber);
+
+
+
+
+        if (UtilValidate.isEmpty(targetService)) {
+            Debug.logWarning("TargetService is empty.", module);
+            return;
+        }
+
+        int viewIndex = -1;
+        try {
+            viewIndex = ((Integer) context.get("viewIndex")).intValue();
+        } catch (Exception e) {
+            viewIndex = 0;
+        }
+
+        int viewSize = -1;
+        try {
+            viewSize = ((Integer) context.get("viewSize")).intValue();
+        } catch (Exception e) {
+            viewSize = this.getViewSize();
+        }
+
+
+        /*
+        int highIndex = -1;
+        try {
+            highIndex = modelForm.getHighIndex();
+        } catch (Exception e) {
+            highIndex = 0;
+        }
+
+        int lowIndex = -1;
+        try {
+            lowIndex = modelForm.getLowIndex();
+        } catch (Exception e) {
+            lowIndex = 0;
+        }
+         */
+
+        int lowIndex = viewIndex * viewSize;
+        int highIndex = (viewIndex + 1) * viewSize;
+        // if this is all there seems to be (if listSize < 0, then size is unknown)
+        if (actualPageSize >= listSize && listSize > 0) {
+            return;
+        }
+
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+
+        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+
+        writer.append("<table border=\"0\" width=\"100%\" cellpadding=\"2\">\n");
+        writer.append("  <tr>\n");
+        writer.append("    <td align=\"right\">\n");
+        writer.append("      <b>\n");
+        if (viewIndex > 0) {
+            writer.append(" <a href=\"");
+            StringBuilder linkText = new StringBuilder(targetService);
+            if (linkText.indexOf("?") < 0)  linkText.append("?");
+            else linkText.append("&amp;");
+            //if (queryString != null && !queryString.equals("null")) linkText += queryString + "&";
+            if (UtilValidate.isNotEmpty(queryString)) {
+                linkText.append(queryString).append("&amp;");
+            }
+            linkText.append("VIEW_SIZE_"+ paginatorNumber + "=").append(viewSize).append("&amp;VIEW_INDEX_" + paginatorNumber + "=").append(viewIndex - 1).append("\"");
+
+            // make the link
+            writer.append(rh.makeLink(request, response, linkText.toString(), false, false, false));
+            String previous = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", (Locale) context.get("locale"));
+            writer.append(" class=\"buttontext\">[").append(previous).append("]</a>\n");
+
+        }
+        if (listSize > 0) {
+            Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize));
+            String commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale"));
+            writer.append(" <span class=\"tabletext\">").append(commonDisplaying).append("</span> \n");
+        }
+        if (highIndex < listSize) {
+            writer.append(" <a href=\"");
+            StringBuilder linkText = new StringBuilder(targetService);
+            if (linkText.indexOf("?") < 0)  linkText.append("?");
+            else linkText.append("&amp;");
+            if (UtilValidate.isNotEmpty(queryString)) {
+                linkText.append(queryString).append("&amp;");
+            }
+            linkText.append("VIEW_SIZE_" + paginatorNumber + "=").append(viewSize).append("&amp;VIEW_INDEX_" + paginatorNumber + "=").append(viewIndex + 1).append("\"");
+
+            // make the link
+            writer.append(rh.makeLink(request, response, linkText.toString(), false, false, false));
+            String next = UtilProperties.getMessage("CommonUiLabels", "CommonNext", (Locale) context.get("locale"));
+            writer.append(" class=\"buttontext\">[").append(next).append("]</a>\n");
+
+        }
+        writer.append("      </b>\n");
+        writer.append("    </td>\n");
+        writer.append("  </tr>\n");
+        writer.append("</table>\n");
+
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+
+    public FlexibleMapAccessor<Object> getListNameExdr() {
+        return listNameExdr;
+    }
+
+    public FlexibleStringExpander getEntryNameExdr() {
+        return entryNameExdr;
+    }
+
+    public FlexibleStringExpander getKeyNameExdr() {
+        return keyNameExdr;
+    }
+
+    public FlexibleStringExpander getPaginateTarget() {
+        return paginateTarget;
+    }
+
+    public FlexibleStringExpander getPaginate() {
+        return paginate;
+    }
+
+}
+
+
diff --git a/framework/widget/src/org/ofbiz/widget/menu/MenuFactory.java b/framework/widget/src/org/ofbiz/widget/model/MenuFactory.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/menu/MenuFactory.java
rename to framework/widget/src/org/ofbiz/widget/model/MenuFactory.java
index 472d688..c30ac37 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/MenuFactory.java
+++ b/framework/widget/src/org/ofbiz/widget/model/MenuFactory.java
@@ -1,118 +1,118 @@
-/*******************************************************************************
- * 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.ofbiz.widget.menu;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.location.FlexibleLocation;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.cache.UtilCache;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-
-/**
- * Widget Library - Menu factory class
- */
-public class MenuFactory {
-
-    public static final String module = MenuFactory.class.getName();
-
-    public static final UtilCache<String, Map<String, ModelMenu>> menuWebappCache = UtilCache.createUtilCache("widget.menu.webappResource", 0, 0, false);
-    public static final UtilCache<String, Map<String, ModelMenu>> menuLocationCache = UtilCache.createUtilCache("widget.menu.locationResource", 0, 0, false);
-
-    public static ModelMenu getMenuFromWebappContext(String resourceName, String menuName, HttpServletRequest request)
-            throws IOException, SAXException, ParserConfigurationException {
-        String webappName = UtilHttp.getApplicationName(request);
-        String cacheKey = webappName + "::" + resourceName;
-
-        Map<String, ModelMenu> modelMenuMap = menuWebappCache.get(cacheKey);
-        if (modelMenuMap == null) {
-            synchronized (MenuFactory.class) {
-                modelMenuMap = menuWebappCache.get(cacheKey);
-                if (modelMenuMap == null) {
-                    ServletContext servletContext = (ServletContext) request.getAttribute("servletContext");
-
-                    URL menuFileUrl = servletContext.getResource(resourceName);
-                    Document menuFileDoc = UtilXml.readXmlDocument(menuFileUrl, true, true);
-                    modelMenuMap = readMenuDocument(menuFileDoc, cacheKey);
-                    menuWebappCache.put(cacheKey, modelMenuMap);
-                }
-            }
-        }
-
-        if (UtilValidate.isEmpty(modelMenuMap)) {
-            throw new IllegalArgumentException("Could not find menu file in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]");
-        }
-
-        ModelMenu modelMenu = modelMenuMap.get(menuName);
-        if (modelMenu == null) {
-            throw new IllegalArgumentException("Could not find menu with name [" + menuName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]");
-        }
-        return modelMenu;
-    }
-
-    public static Map<String, ModelMenu> readMenuDocument(Document menuFileDoc, String menuLocation) {
-        Map<String, ModelMenu> modelMenuMap = new HashMap<String, ModelMenu>();
-        if (menuFileDoc != null) {
-            // read document and construct ModelMenu for each menu element
-            Element rootElement = menuFileDoc.getDocumentElement();
-            for (Element menuElement: UtilXml.childElementList(rootElement, "menu")){
-                ModelMenu modelMenu = new ModelMenu(menuElement, menuLocation);
-                modelMenuMap.put(modelMenu.getName(), modelMenu);
-            }
-         }
-        return modelMenuMap;
-    }
-
-    public static ModelMenu getMenuFromLocation(String resourceName, String menuName) throws IOException, SAXException, ParserConfigurationException {
-        Map<String, ModelMenu> modelMenuMap = menuLocationCache.get(resourceName);
-        if (modelMenuMap == null) {
-            synchronized (MenuFactory.class) {
-                modelMenuMap = menuLocationCache.get(resourceName);
-                if (modelMenuMap == null) {
-                    URL menuFileUrl = FlexibleLocation.resolveLocation(resourceName);
-                    Document menuFileDoc = UtilXml.readXmlDocument(menuFileUrl, true, true);
-                    modelMenuMap = readMenuDocument(menuFileDoc, resourceName);
-                    menuLocationCache.put(resourceName, modelMenuMap);
-                }
-            }
-        }
-
-        if (UtilValidate.isEmpty(modelMenuMap)) {
-            throw new IllegalArgumentException("Could not find menu file in location [" + resourceName + "]");
-        }
-
-        ModelMenu modelMenu = modelMenuMap.get(menuName);
-        if (modelMenu == null) {
-            throw new IllegalArgumentException("Could not find menu with name [" + menuName + "] in location [" + resourceName + "]");
-        }
-        return modelMenu;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.location.FlexibleLocation;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.cache.UtilCache;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Widget Library - Menu factory class
+ */
+public class MenuFactory {
+
+    public static final String module = MenuFactory.class.getName();
+
+    public static final UtilCache<String, Map<String, ModelMenu>> menuWebappCache = UtilCache.createUtilCache("widget.menu.webappResource", 0, 0, false);
+    public static final UtilCache<String, Map<String, ModelMenu>> menuLocationCache = UtilCache.createUtilCache("widget.menu.locationResource", 0, 0, false);
+
+    public static ModelMenu getMenuFromWebappContext(String resourceName, String menuName, HttpServletRequest request)
+            throws IOException, SAXException, ParserConfigurationException {
+        String webappName = UtilHttp.getApplicationName(request);
+        String cacheKey = webappName + "::" + resourceName;
+
+        Map<String, ModelMenu> modelMenuMap = menuWebappCache.get(cacheKey);
+        if (modelMenuMap == null) {
+            synchronized (MenuFactory.class) {
+                modelMenuMap = menuWebappCache.get(cacheKey);
+                if (modelMenuMap == null) {
+                    ServletContext servletContext = (ServletContext) request.getAttribute("servletContext");
+
+                    URL menuFileUrl = servletContext.getResource(resourceName);
+                    Document menuFileDoc = UtilXml.readXmlDocument(menuFileUrl, true, true);
+                    modelMenuMap = readMenuDocument(menuFileDoc, cacheKey);
+                    menuWebappCache.put(cacheKey, modelMenuMap);
+                }
+            }
+        }
+
+        if (UtilValidate.isEmpty(modelMenuMap)) {
+            throw new IllegalArgumentException("Could not find menu file in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]");
+        }
+
+        ModelMenu modelMenu = modelMenuMap.get(menuName);
+        if (modelMenu == null) {
+            throw new IllegalArgumentException("Could not find menu with name [" + menuName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]");
+        }
+        return modelMenu;
+    }
+
+    public static Map<String, ModelMenu> readMenuDocument(Document menuFileDoc, String menuLocation) {
+        Map<String, ModelMenu> modelMenuMap = new HashMap<String, ModelMenu>();
+        if (menuFileDoc != null) {
+            // read document and construct ModelMenu for each menu element
+            Element rootElement = menuFileDoc.getDocumentElement();
+            for (Element menuElement: UtilXml.childElementList(rootElement, "menu")){
+                ModelMenu modelMenu = new ModelMenu(menuElement, menuLocation);
+                modelMenuMap.put(modelMenu.getName(), modelMenu);
+            }
+         }
+        return modelMenuMap;
+    }
+
+    public static ModelMenu getMenuFromLocation(String resourceName, String menuName) throws IOException, SAXException, ParserConfigurationException {
+        Map<String, ModelMenu> modelMenuMap = menuLocationCache.get(resourceName);
+        if (modelMenuMap == null) {
+            synchronized (MenuFactory.class) {
+                modelMenuMap = menuLocationCache.get(resourceName);
+                if (modelMenuMap == null) {
+                    URL menuFileUrl = FlexibleLocation.resolveLocation(resourceName);
+                    Document menuFileDoc = UtilXml.readXmlDocument(menuFileUrl, true, true);
+                    modelMenuMap = readMenuDocument(menuFileDoc, resourceName);
+                    menuLocationCache.put(resourceName, modelMenuMap);
+                }
+            }
+        }
+
+        if (UtilValidate.isEmpty(modelMenuMap)) {
+            throw new IllegalArgumentException("Could not find menu file in location [" + resourceName + "]");
+        }
+
+        ModelMenu modelMenu = modelMenuMap.get(menuName);
+        if (modelMenu == null) {
+            throw new IllegalArgumentException("Could not find menu with name [" + menuName + "] in location [" + resourceName + "]");
+        }
+        return modelMenu;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/ModelAction.java b/framework/widget/src/org/ofbiz/widget/model/ModelAction.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/ModelAction.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelAction.java
index 19977a2..6503686 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelAction.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
 import java.util.Map;
 
diff --git a/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java b/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java
similarity index 93%
rename from framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java
index 28c039c..84085a5 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java
@@ -16,11 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
-
-import org.ofbiz.widget.form.ModelFormAction;
-import org.ofbiz.widget.menu.ModelMenuAction;
-import org.ofbiz.widget.tree.ModelTreeAction;
+package org.ofbiz.widget.model;
 
 /**
  *  A <code>ModelAction</code> visitor.
diff --git a/framework/widget/src/org/ofbiz/widget/ModelCondition.java b/framework/widget/src/org/ofbiz/widget/model/ModelCondition.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/ModelCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelCondition.java
index b829fdb..b7f6ff9 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelCondition.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
 import java.util.Map;
 
diff --git a/framework/widget/src/org/ofbiz/widget/ModelConditionFactory.java b/framework/widget/src/org/ofbiz/widget/model/ModelConditionFactory.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/ModelConditionFactory.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelConditionFactory.java
index 0857f52..e47799d 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelConditionFactory.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelConditionFactory.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
 import org.w3c.dom.Element;
 
diff --git a/framework/widget/src/org/ofbiz/widget/ModelConditionVisitor.java b/framework/widget/src/org/ofbiz/widget/model/ModelConditionVisitor.java
similarity index 68%
rename from framework/widget/src/org/ofbiz/widget/ModelConditionVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelConditionVisitor.java
index 7bc9684..a60dd39 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelConditionVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelConditionVisitor.java
@@ -16,23 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
-import org.ofbiz.widget.AbstractModelCondition.And;
-import org.ofbiz.widget.AbstractModelCondition.IfCompare;
-import org.ofbiz.widget.AbstractModelCondition.IfCompareField;
-import org.ofbiz.widget.AbstractModelCondition.IfEmpty;
-import org.ofbiz.widget.AbstractModelCondition.IfEntityPermission;
-import org.ofbiz.widget.AbstractModelCondition.IfHasPermission;
-import org.ofbiz.widget.AbstractModelCondition.IfRegexp;
-import org.ofbiz.widget.AbstractModelCondition.IfServicePermission;
-import org.ofbiz.widget.AbstractModelCondition.IfValidateMethod;
-import org.ofbiz.widget.AbstractModelCondition.Not;
-import org.ofbiz.widget.AbstractModelCondition.Or;
-import org.ofbiz.widget.AbstractModelCondition.Xor;
-import org.ofbiz.widget.menu.ModelMenuCondition;
-import org.ofbiz.widget.screen.ModelScreenCondition.IfEmptySection;
-import org.ofbiz.widget.tree.ModelTreeCondition;
+import org.ofbiz.widget.model.AbstractModelCondition.And;
+import org.ofbiz.widget.model.AbstractModelCondition.IfCompare;
+import org.ofbiz.widget.model.AbstractModelCondition.IfCompareField;
+import org.ofbiz.widget.model.AbstractModelCondition.IfEmpty;
+import org.ofbiz.widget.model.AbstractModelCondition.IfEntityPermission;
+import org.ofbiz.widget.model.AbstractModelCondition.IfHasPermission;
+import org.ofbiz.widget.model.AbstractModelCondition.IfRegexp;
+import org.ofbiz.widget.model.AbstractModelCondition.IfServicePermission;
+import org.ofbiz.widget.model.AbstractModelCondition.IfValidateMethod;
+import org.ofbiz.widget.model.AbstractModelCondition.Not;
+import org.ofbiz.widget.model.AbstractModelCondition.Or;
+import org.ofbiz.widget.model.AbstractModelCondition.Xor;
+import org.ofbiz.widget.model.ModelScreenCondition.IfEmptySection;
 
 /**
  *  A <code>ModelCondition</code> visitor.
diff --git a/framework/widget/src/org/ofbiz/widget/ModelFieldVisitor.java b/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
similarity index 65%
rename from framework/widget/src/org/ofbiz/widget/ModelFieldVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
index bf06bf7..753971b 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelFieldVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
@@ -16,29 +16,29 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
-import org.ofbiz.widget.form.ModelFormField.CheckField;
-import org.ofbiz.widget.form.ModelFormField.ContainerField;
-import org.ofbiz.widget.form.ModelFormField.DateFindField;
-import org.ofbiz.widget.form.ModelFormField.DateTimeField;
-import org.ofbiz.widget.form.ModelFormField.DisplayEntityField;
-import org.ofbiz.widget.form.ModelFormField.DisplayField;
-import org.ofbiz.widget.form.ModelFormField.DropDownField;
-import org.ofbiz.widget.form.ModelFormField.FileField;
-import org.ofbiz.widget.form.ModelFormField.HiddenField;
-import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
-import org.ofbiz.widget.form.ModelFormField.IgnoredField;
-import org.ofbiz.widget.form.ModelFormField.ImageField;
-import org.ofbiz.widget.form.ModelFormField.LookupField;
-import org.ofbiz.widget.form.ModelFormField.PasswordField;
-import org.ofbiz.widget.form.ModelFormField.RadioField;
-import org.ofbiz.widget.form.ModelFormField.RangeFindField;
-import org.ofbiz.widget.form.ModelFormField.ResetField;
-import org.ofbiz.widget.form.ModelFormField.SubmitField;
-import org.ofbiz.widget.form.ModelFormField.TextField;
-import org.ofbiz.widget.form.ModelFormField.TextFindField;
-import org.ofbiz.widget.form.ModelFormField.TextareaField;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayEntityField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
 
 /**
  *  A <code>ModelFormField</code> visitor.
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelForm.java b/framework/widget/src/org/ofbiz/widget/model/ModelForm.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/form/ModelForm.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelForm.java
index 41f981d..73b87bb 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelForm.java
@@ -1,1858 +1,1854 @@
-/*******************************************************************************
- * 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.ofbiz.widget.form;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.ofbiz.base.util.BshUtil;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.model.ModelEntity;
-import org.ofbiz.entity.model.ModelField;
-import org.ofbiz.entity.model.ModelReader;
-import org.ofbiz.service.DispatchContext;
-import org.ofbiz.service.GenericServiceException;
-import org.ofbiz.service.ModelParam;
-import org.ofbiz.service.ModelService;
-import org.ofbiz.widget.AbstractModelAction;
-import org.ofbiz.widget.CommonWidgetModels;
-import org.ofbiz.widget.ModelAction;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.WidgetWorker;
-import org.w3c.dom.Element;
-
-import bsh.EvalError;
-import bsh.Interpreter;
-
-/**
- * Models the &lt;form&gt; element.
- * 
- * @see <code>widget-form.xsd</code>
- */
-@SuppressWarnings("serial")
-public class ModelForm extends ModelWidget {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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!
-     * 
-     * BE VERY CAREFUL when implementing "extends" - parent form collections
-     * must be added to child collections, not replace them. In other words,
-     * do not assign parent collection fields to child collection fields.
-     * 
-     */
-
-    public static final String module = ModelForm.class.getName();
-    public static final String DEFAULT_FORM_RESULT_LIST_NAME = "defaultFormResultList";
-    /** Pagination settings and defaults. */
-    public static int DEFAULT_PAGE_SIZE = 10;
-    public static int MAX_PAGE_SIZE = 10000;
-    public static String DEFAULT_PAG_INDEX_FIELD = "viewIndex";
-    public static String DEFAULT_PAG_SIZE_FIELD = "viewSize";
-    public static String DEFAULT_PAG_STYLE = "nav-pager";
-    public static String DEFAULT_PAG_FIRST_STYLE = "nav-first";
-    public static String DEFAULT_PAG_PREV_STYLE = "nav-previous";
-    public static String DEFAULT_PAG_NEXT_STYLE = "nav-next";
-    public static String DEFAULT_PAG_LAST_STYLE = "nav-last";
-    /** Sort field default styles. */
-    public static String DEFAULT_SORT_FIELD_STYLE = "sort-order";
-    public static String DEFAULT_SORT_FIELD_ASC_STYLE = "sort-order-asc";
-    public static String DEFAULT_SORT_FIELD_DESC_STYLE = "sort-order-desc";
-    private final List<ModelAction> actions;
-    private final List<AltRowStyle> altRowStyles;
-    private final List<AltTarget> altTargets;
-    private final List<AutoFieldsEntity> autoFieldsEntities;
-    private final List<AutoFieldsService> autoFieldsServices;
-    private final boolean clientAutocompleteFields;
-    private final String containerId;
-    private final String containerStyle;
-    private final String defaultEntityName;
-    /** This field group will be the "catch-all" group for fields that are not
-     *  included in an explicit field-group.
-     */
-    private final FieldGroup defaultFieldGroup;
-    private final FlexibleMapAccessor<Map<String, ? extends Object>> defaultMapName;
-    private final String defaultRequiredFieldStyle;
-    private final String defaultServiceName;
-    private final String defaultSortFieldAscStyle;
-    private final String defaultSortFieldDescStyle;
-    private final String defaultSortFieldStyle;
-    private final String defaultTableStyle;
-    private final String defaultTitleAreaStyle;
-    private final String defaultTitleStyle;
-    private final String defaultTooltipStyle;
-    private final int defaultViewSize;
-    private final String defaultWidgetAreaStyle;
-    private final String defaultWidgetStyle;
-    private final String evenRowStyle;
-    /** This is a list of FieldGroups in the order they were created.
-     * Can also include Banner objects.
-     */
-    private final List<FieldGroupBase> fieldGroupList;
-    /** This Map is keyed with the field name and has a FieldGroup for the value.
-     * Can also include Banner objects.
-     */
-    private final Map<String, FieldGroupBase> fieldGroupMap;
-    /** This List will contain one copy of each field for each field name in the order
-     * they were encountered in the service, entity, or form definition; field definitions
-     * with constraints will also be in this list but may appear multiple times for the same
-     * field name.
-     *
-     * When rendering the form the order in this list should be following and it should not be
-     * necessary to use the Map. The Map is used when loading the form definition to keep the
-     * list clean and implement the override features for field definitions.
-     */
-    private final List<ModelFormField> fieldList;
-    private final String focusFieldName;
-    private final String formLocation;
-    private final String formTitleAreaStyle;
-    private final String formWidgetAreaStyle;
-    private final boolean groupColumns;
-    private final String headerRowStyle;
-    private final boolean hideHeader;
-    private final String itemIndexSeparator;
-    private final List<String> lastOrderFields;
-    private final String listEntryName;
-    private final String listName;
-    private final List<ModelFormField> multiSubmitFields;
-    private final String oddRowStyle;
-    /** On Paginate areas to be updated. */
-    private final List<UpdateArea> onPaginateUpdateAreas;
-    /** On Sort Column areas to be updated. */
-    private final List<UpdateArea> onSortColumnUpdateAreas;
-    /** On Submit areas to be updated. */
-    private final List<UpdateArea> onSubmitUpdateAreas;
-    private final FlexibleStringExpander overrideListSize;
-    private final FlexibleStringExpander paginate;
-    private final FlexibleStringExpander paginateFirstLabel;
-    private final FlexibleStringExpander paginateIndexField;
-    private final FlexibleStringExpander paginateLastLabel;
-    private final FlexibleStringExpander paginateNextLabel;
-    private final FlexibleStringExpander paginatePreviousLabel;
-    private final FlexibleStringExpander paginateSizeField;
-    private final String paginateStyle;
-    private final FlexibleStringExpander paginateTarget;
-    private final String paginateTargetAnchor;
-    private final FlexibleStringExpander paginateViewSizeLabel;
-    private final ModelForm parentModelForm;
-    private final List<ModelAction> rowActions;
-    private final FlexibleStringExpander rowCountExdr;
-    private final boolean separateColumns;
-    private final boolean skipEnd;
-    private final boolean skipStart;
-    private final String sortFieldParameterName;
-    private final List<SortField> sortOrderFields;
-    private final FlexibleStringExpander target;
-    private final String targetType;
-    private final FlexibleStringExpander targetWindowExdr;
-    private final String title;
-    private final String tooltip;
-    private final String type;
-    private final boolean useRowSubmit;
-    /** Keeps track of conditional fields to help ensure that only one is rendered
-     */
-    private final Set<String> useWhenFields;
-
-    /** XML Constructor */
-    public ModelForm(Element formElement, String formLocation, ModelReader entityModelReader, DispatchContext dispatchContext) {
-        super(formElement);
-        this.formLocation = formLocation;
-        parentModelForm = getParentForm(formElement, entityModelReader, dispatchContext);
-        int defaultViewSizeInt = DEFAULT_PAGE_SIZE;
-        String viewSize = formElement.getAttribute("view-size");
-        if (viewSize.isEmpty()) {
-            if (parentModelForm != null) {
-                defaultViewSizeInt = parentModelForm.defaultViewSize;
-            } else {
-                defaultViewSizeInt = UtilProperties.getPropertyAsInteger("widget.properties", "widget.form.defaultViewSize",
-                        defaultViewSizeInt);
-            }
-        } else {
-            try {
-                defaultViewSizeInt = Integer.valueOf(viewSize);
-            } catch (NumberFormatException e) {
-            }
-        }
-        this.defaultViewSize = defaultViewSizeInt;
-        String type = formElement.getAttribute("type");
-        if (type.isEmpty() && parentModelForm != null) {
-            type = parentModelForm.type;
-        }
-        this.type = type;
-        FlexibleStringExpander target = FlexibleStringExpander.getInstance(formElement.getAttribute("target"));
-        if (target.isEmpty() && parentModelForm != null) {
-            target = parentModelForm.target;
-        }
-        this.target = target;
-        String containerId = formElement.getAttribute("id");
-        if (containerId.isEmpty() && parentModelForm != null) {
-            containerId = parentModelForm.containerId;
-        }
-        this.containerId = containerId;
-        String containerStyle = formElement.getAttribute("style");
-        if (containerStyle.isEmpty() && parentModelForm != null) {
-            containerStyle = parentModelForm.containerStyle;
-        }
-        this.containerStyle = containerStyle;
-        String title = formElement.getAttribute("title");
-        if (title.isEmpty() && parentModelForm != null) {
-            title = parentModelForm.title;
-        }
-        this.title = title;
-        String tooltip = formElement.getAttribute("tooltip");
-        if (tooltip.isEmpty() && parentModelForm != null) {
-            tooltip = parentModelForm.tooltip;
-        }
-        this.tooltip = tooltip;
-        String listName = formElement.getAttribute("list-name");
-        if (listName.isEmpty()) {
-            if (parentModelForm != null) {
-                listName = parentModelForm.listName;
-            } else {
-                listName = DEFAULT_FORM_RESULT_LIST_NAME;
-            }
-        }
-        this.listName = listName;
-        String listEntryName = formElement.getAttribute("list-entry-name");
-        if (listEntryName.isEmpty() && parentModelForm != null) {
-            listEntryName = parentModelForm.listEntryName;
-        }
-        this.listEntryName = listEntryName;
-        String defaultEntityName = formElement.getAttribute("default-entity-name");
-        if (defaultEntityName.isEmpty() && parentModelForm != null) {
-            defaultEntityName = parentModelForm.defaultEntityName;
-        }
-        this.defaultEntityName = defaultEntityName;
-        String defaultServiceName = formElement.getAttribute("default-service-name");
-        if (defaultServiceName.isEmpty() && parentModelForm != null) {
-            defaultServiceName = parentModelForm.defaultServiceName;
-        }
-        this.defaultServiceName = defaultServiceName;
-        String formTitleAreaStyle = formElement.getAttribute("form-title-area-style");
-        if (formTitleAreaStyle.isEmpty() && parentModelForm != null) {
-            formTitleAreaStyle = parentModelForm.formTitleAreaStyle;
-        }
-        this.formTitleAreaStyle = formTitleAreaStyle;
-        String formWidgetAreaStyle = formElement.getAttribute("form-widget-area-style");
-        if (formWidgetAreaStyle.isEmpty() && parentModelForm != null) {
-            formWidgetAreaStyle = parentModelForm.formWidgetAreaStyle;
-        }
-        this.formWidgetAreaStyle = formWidgetAreaStyle;
-        String defaultTitleAreaStyle = formElement.getAttribute("default-title-area-style");
-        if (defaultTitleAreaStyle.isEmpty() && parentModelForm != null) {
-            defaultTitleAreaStyle = parentModelForm.defaultTitleAreaStyle;
-        }
-        this.defaultTitleAreaStyle = defaultTitleAreaStyle;
-        String defaultWidgetAreaStyle = formElement.getAttribute("default-widget-area-style");
-        if (defaultWidgetAreaStyle.isEmpty() && parentModelForm != null) {
-            defaultWidgetAreaStyle = parentModelForm.defaultWidgetAreaStyle;
-        }
-        this.defaultWidgetAreaStyle = defaultWidgetAreaStyle;
-        String oddRowStyle = formElement.getAttribute("odd-row-style");
-        if (oddRowStyle.isEmpty() && parentModelForm != null) {
-            oddRowStyle = parentModelForm.oddRowStyle;
-        }
-        this.oddRowStyle = oddRowStyle;
-        String evenRowStyle = formElement.getAttribute("even-row-style");
-        if (evenRowStyle.isEmpty() && parentModelForm != null) {
-            evenRowStyle = parentModelForm.evenRowStyle;
-        }
-        this.evenRowStyle = evenRowStyle;
-        String defaultTableStyle = formElement.getAttribute("default-table-style");
-        if (defaultTableStyle.isEmpty() && parentModelForm != null) {
-            defaultTableStyle = parentModelForm.defaultTableStyle;
-        }
-        this.defaultTableStyle = defaultTableStyle;
-        String headerRowStyle = formElement.getAttribute("header-row-style");
-        if (headerRowStyle.isEmpty() && parentModelForm != null) {
-            headerRowStyle = parentModelForm.headerRowStyle;
-        }
-        this.headerRowStyle = headerRowStyle;
-        String defaultTitleStyle = formElement.getAttribute("default-title-style");
-        if (defaultTitleStyle.isEmpty() && parentModelForm != null) {
-            defaultTitleStyle = parentModelForm.defaultTitleStyle;
-        }
-        this.defaultTitleStyle = defaultTitleStyle;
-        String defaultWidgetStyle = formElement.getAttribute("default-widget-style");
-        if (defaultWidgetStyle.isEmpty() && parentModelForm != null) {
-            defaultWidgetStyle = parentModelForm.defaultWidgetStyle;
-        }
-        this.defaultWidgetStyle = defaultWidgetStyle;
-        String defaultTooltipStyle = formElement.getAttribute("default-tooltip-style");
-        if (defaultTooltipStyle.isEmpty() && parentModelForm != null) {
-            defaultTooltipStyle = parentModelForm.defaultTooltipStyle;
-        }
-        this.defaultTooltipStyle = defaultTooltipStyle;
-        String itemIndexSeparator = formElement.getAttribute("item-index-separator");
-        if (itemIndexSeparator.isEmpty() && parentModelForm != null) {
-            itemIndexSeparator = parentModelForm.itemIndexSeparator;
-        }
-        this.itemIndexSeparator = itemIndexSeparator;
-        String separateColumns = formElement.getAttribute("separate-columns");
-        if (separateColumns.isEmpty() && parentModelForm != null) {
-            this.separateColumns = parentModelForm.separateColumns;
-        } else {
-            this.separateColumns = "true".equals(separateColumns);
-        }
-        String groupColumns = formElement.getAttribute("group-columns");
-        if (groupColumns.isEmpty() && parentModelForm != null) {
-            this.groupColumns = parentModelForm.groupColumns;
-        } else {
-            this.groupColumns = !"false".equals(groupColumns);
-        }
-        String targetType = formElement.getAttribute("target-type");
-        if (targetType.isEmpty() && parentModelForm != null) {
-            targetType = parentModelForm.targetType;
-        }
-        this.targetType = targetType;
-        FlexibleMapAccessor<Map<String, ? extends Object>> defaultMapName = FlexibleMapAccessor.getInstance(formElement
-                .getAttribute("default-map-name"));
-        if (defaultMapName.isEmpty() && parentModelForm != null) {
-            defaultMapName = parentModelForm.defaultMapName;
-        }
-        this.defaultMapName = defaultMapName;
-        FlexibleStringExpander targetWindowExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("target-window"));
-        if (targetWindowExdr.isEmpty() && parentModelForm != null) {
-            targetWindowExdr = parentModelForm.targetWindowExdr;
-        }
-        this.targetWindowExdr = targetWindowExdr;
-        String hideHeader = formElement.getAttribute("hide-header");
-        if (hideHeader.isEmpty() && parentModelForm != null) {
-            this.hideHeader = parentModelForm.hideHeader;
-        } else {
-            this.hideHeader = "true".equals(hideHeader);
-        }
-        String clientAutocompleteFields = formElement.getAttribute("client-autocomplete-fields");
-        if (clientAutocompleteFields.isEmpty() && parentModelForm != null) {
-            this.clientAutocompleteFields = parentModelForm.clientAutocompleteFields;
-        } else {
-            this.clientAutocompleteFields = !"false".equals(formElement.getAttribute("client-autocomplete-fields"));
-        }
-        FlexibleStringExpander paginateTarget = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate-target"));
-        if (paginateTarget.isEmpty() && parentModelForm != null) {
-            paginateTarget = parentModelForm.paginateTarget;
-        }
-        this.paginateTarget = paginateTarget;
-        ArrayList<AltTarget> altTargets = new ArrayList<AltTarget>();
-        if (parentModelForm != null) {
-            altTargets.addAll(parentModelForm.altTargets);
-        }
-        for (Element altTargetElement : UtilXml.childElementList(formElement, "alt-target")) {
-            altTargets.add(new AltTarget(altTargetElement));
-        }
-        altTargets.trimToSize();
-        this.altTargets = Collections.unmodifiableList(altTargets);
-        ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
-        if (parentModelForm != null) {
-            actions.addAll(parentModelForm.actions);
-        }
-        Element actionsElement = UtilXml.firstChildElement(formElement, "actions");
-        if (actionsElement != null) {
-            actions.addAll(ModelFormAction.readSubActions(this, actionsElement));
-        }
-        actions.trimToSize();
-        this.actions = Collections.unmodifiableList(actions);
-        ArrayList<ModelAction> rowActions = new ArrayList<ModelAction>();
-        if (parentModelForm != null) {
-            rowActions.addAll(parentModelForm.rowActions);
-        }
-        Element rowActionsElement = UtilXml.firstChildElement(formElement, "row-actions");
-        if (rowActionsElement != null) {
-            rowActions.addAll(ModelFormAction.readSubActions(this, rowActionsElement));
-        }
-        rowActions.trimToSize();
-        this.rowActions = Collections.unmodifiableList(rowActions);
-        ArrayList<UpdateArea> onPaginateUpdateAreas = new ArrayList<UpdateArea>();
-        ArrayList<UpdateArea> onSubmitUpdateAreas = new ArrayList<UpdateArea>();
-        ArrayList<UpdateArea> onSortColumnUpdateAreas = new ArrayList<UpdateArea>();
-        if (parentModelForm != null) {
-            onPaginateUpdateAreas.addAll(parentModelForm.onPaginateUpdateAreas);
-            onSubmitUpdateAreas.addAll(parentModelForm.onSubmitUpdateAreas);
-            onSortColumnUpdateAreas.addAll(parentModelForm.onSortColumnUpdateAreas);
-        }
-        for (Element updateAreaElement : UtilXml.childElementList(formElement, "on-event-update-area")) {
-            UpdateArea updateArea = new UpdateArea(updateAreaElement, defaultServiceName, defaultEntityName);
-            if ("paginate".equals(updateArea.getEventType())) {
-                int index = onPaginateUpdateAreas.indexOf(updateArea);
-                if (index != -1) {
-                    if (!updateArea.areaTarget.isEmpty()) {
-                        onPaginateUpdateAreas.set(index, updateArea);
-                    } else {
-                        // blank target indicates a removing override
-                        onPaginateUpdateAreas.remove(index);
-                    }
-                } else {
-                    onPaginateUpdateAreas.add(updateArea);
-                }
-            } else if ("submit".equals(updateArea.getEventType())) {
-                int index = onSubmitUpdateAreas.indexOf(updateArea);
-                if (index != -1) {
-                    onSubmitUpdateAreas.set(index, updateArea);
-                } else {
-                    onSubmitUpdateAreas.add(updateArea);
-                }
-            } else if ("sort-column".equals(updateArea.getEventType())) {
-                int index = onSortColumnUpdateAreas.indexOf(updateArea);
-                if (index != -1) {
-                    if (!updateArea.areaTarget.isEmpty()) {
-                        onSortColumnUpdateAreas.set(index, updateArea);
-                    } else {
-                        // blank target indicates a removing override
-                        onSortColumnUpdateAreas.remove(index);
-                    }
-                } else {
-                    onSortColumnUpdateAreas.add(updateArea);
-                }
-            }
-        }
-        onPaginateUpdateAreas.trimToSize();
-        this.onPaginateUpdateAreas = Collections.unmodifiableList(onPaginateUpdateAreas);
-        onSubmitUpdateAreas.trimToSize();
-        this.onSubmitUpdateAreas = Collections.unmodifiableList(onSubmitUpdateAreas);
-        onSortColumnUpdateAreas.trimToSize();
-        this.onSortColumnUpdateAreas = Collections.unmodifiableList(onSortColumnUpdateAreas);
-        ArrayList<AltRowStyle> altRowStyles = new ArrayList<AltRowStyle>();
-        if (parentModelForm != null) {
-            altRowStyles.addAll(parentModelForm.altRowStyles);
-        }
-        for (Element altRowStyleElement : UtilXml.childElementList(formElement, "alt-row-style")) {
-            AltRowStyle altRowStyle = new AltRowStyle(altRowStyleElement);
-            altRowStyles.add(altRowStyle);
-        }
-        altRowStyles.trimToSize();
-        this.altRowStyles = Collections.unmodifiableList(altRowStyles);
-        Set<String> useWhenFields = new HashSet<String>();
-        if (parentModelForm != null) {
-            useWhenFields.addAll(parentModelForm.useWhenFields);
-        }
-        ArrayList<ModelFormFieldBuilder> fieldBuilderList = new ArrayList<ModelFormFieldBuilder>();
-        Map<String, ModelFormFieldBuilder> fieldBuilderMap = new HashMap<String, ModelFormFieldBuilder>();
-        if (parentModelForm != null) {
-            // Create this fieldList/Map from clones of parentModelForm's
-            for (ModelFormField parentChildField : parentModelForm.fieldList) {
-                ModelFormFieldBuilder builder = new ModelFormFieldBuilder(parentChildField);
-                builder.setModelForm(this);
-                fieldBuilderList.add(builder);
-                fieldBuilderMap.put(builder.getName(), builder);
-            }
-        }
-        Map<String, FieldGroupBase> fieldGroupMap = new HashMap<String, FieldGroupBase>();
-        if (parentModelForm != null) {
-            fieldGroupMap.putAll(parentModelForm.fieldGroupMap);
-        }
-        ArrayList<FieldGroupBase> fieldGroupList = new ArrayList<FieldGroupBase>();
-        if (parentModelForm != null) {
-            fieldGroupList.addAll(parentModelForm.fieldGroupList);
-        }
-        ArrayList<String> lastOrderFields = new ArrayList<String>();
-        if (parentModelForm != null) {
-            lastOrderFields.addAll(parentModelForm.lastOrderFields);
-        }
-        String sortFieldParameterName = formElement.getAttribute("sort-field-parameter-name");
-        if (sortFieldParameterName.isEmpty() && parentModelForm != null) {
-            this.sortFieldParameterName = parentModelForm.targetType;
-        } else {
-            this.sortFieldParameterName = "sortField";
-        }
-        String defaultRequiredFieldStyle = formElement.getAttribute("default-required-field-style");
-        if (defaultRequiredFieldStyle.isEmpty() && parentModelForm != null) {
-            defaultRequiredFieldStyle = parentModelForm.defaultRequiredFieldStyle;
-        }
-        this.defaultRequiredFieldStyle = defaultRequiredFieldStyle;
-        String defaultSortFieldStyle = formElement.getAttribute("default-sort-field-style");
-        if (defaultSortFieldStyle.isEmpty() && parentModelForm != null) {
-            this.defaultSortFieldStyle = parentModelForm.defaultSortFieldStyle;
-        } else {
-            this.defaultSortFieldStyle = DEFAULT_SORT_FIELD_STYLE;
-        }
-        String defaultSortFieldAscStyle = formElement.getAttribute("default-sort-field-asc-style");
-        if (defaultSortFieldAscStyle.isEmpty() && parentModelForm != null) {
-            this.defaultSortFieldAscStyle = parentModelForm.defaultSortFieldAscStyle;
-        } else {
-            this.defaultSortFieldAscStyle = DEFAULT_SORT_FIELD_ASC_STYLE;
-        }
-        String defaultSortFieldDescStyle = formElement.getAttribute("default-sort-field-desc-style");
-        if (defaultSortFieldDescStyle.isEmpty() && parentModelForm != null) {
-            this.defaultSortFieldDescStyle = parentModelForm.defaultSortFieldDescStyle;
-        } else {
-            this.defaultSortFieldDescStyle = DEFAULT_SORT_FIELD_DESC_STYLE;
-        }
-        String paginateTargetAnchor = formElement.getAttribute("paginate-target-anchor");
-        if (paginateTargetAnchor.isEmpty() && parentModelForm != null) {
-            paginateTargetAnchor = parentModelForm.paginateTargetAnchor;
-        }
-        this.paginateTargetAnchor = paginateTargetAnchor;
-        FlexibleStringExpander paginateIndexField = FlexibleStringExpander.getInstance(formElement
-                .getAttribute("paginate-index-field"));
-        if (paginateIndexField.isEmpty() && parentModelForm != null) {
-            paginateIndexField = parentModelForm.paginateIndexField;
-        }
-        this.paginateIndexField = paginateIndexField;
-        FlexibleStringExpander paginateSizeField = FlexibleStringExpander.getInstance(formElement
-                .getAttribute("paginate-size-field"));
-        if (paginateSizeField.isEmpty() && parentModelForm != null) {
-            paginateSizeField = parentModelForm.paginateSizeField;
-        }
-        this.paginateSizeField = paginateSizeField;
-        FlexibleStringExpander overrideListSize = FlexibleStringExpander.getInstance(formElement
-                .getAttribute("override-list-size"));
-        if (overrideListSize.isEmpty() && parentModelForm != null) {
-            overrideListSize = parentModelForm.overrideListSize;
-        }
-        this.overrideListSize = overrideListSize;
-        FlexibleStringExpander paginateFirstLabel = FlexibleStringExpander.getInstance(formElement
-                .getAttribute("paginate-first-label"));
-        if (paginateFirstLabel.isEmpty() && parentModelForm != null) {
-            paginateFirstLabel = parentModelForm.paginateFirstLabel;
-        }
-        this.paginateFirstLabel = paginateFirstLabel;
-        FlexibleStringExpander paginatePreviousLabel = FlexibleStringExpander.getInstance(formElement
-                .getAttribute("paginate-previous-label"));
-        if (paginatePreviousLabel.isEmpty() && parentModelForm != null) {
-            paginatePreviousLabel = parentModelForm.paginatePreviousLabel;
-        }
-        this.paginatePreviousLabel = paginatePreviousLabel;
-        FlexibleStringExpander paginateNextLabel = FlexibleStringExpander.getInstance(formElement
-                .getAttribute("paginate-next-label"));
-        if (paginateNextLabel.isEmpty() && parentModelForm != null) {
-            paginateNextLabel = parentModelForm.paginateNextLabel;
-        }
-        this.paginateNextLabel = paginateNextLabel;
-        FlexibleStringExpander paginateLastLabel = FlexibleStringExpander.getInstance(formElement
-                .getAttribute("paginate-last-label"));
-        if (paginateLastLabel.isEmpty() && parentModelForm != null) {
-            paginateLastLabel = parentModelForm.paginateLastLabel;
-        }
-        this.paginateLastLabel = paginateLastLabel;
-        FlexibleStringExpander paginateViewSizeLabel = FlexibleStringExpander.getInstance(formElement
-                .getAttribute("paginate-viewsize-label"));
-        if (paginateViewSizeLabel.isEmpty() && parentModelForm != null) {
-            paginateViewSizeLabel = parentModelForm.paginateViewSizeLabel;
-        }
-        this.paginateViewSizeLabel = paginateViewSizeLabel;
-        String paginateStyle = formElement.getAttribute("paginate-style");
-        if (paginateStyle.isEmpty() && parentModelForm != null) {
-            this.paginateStyle = parentModelForm.paginateStyle;
-        } else {
-            this.paginateStyle = DEFAULT_PAG_STYLE;
-        }
-        FlexibleStringExpander paginate = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate"));
-        if (paginate.isEmpty() && parentModelForm != null) {
-            paginate = parentModelForm.paginate;
-        }
-        this.paginate = paginate;
-        String skipStart = formElement.getAttribute("skip-start");
-        if (skipStart.isEmpty() && parentModelForm != null) {
-            this.skipStart = parentModelForm.skipStart;
-        } else {
-            this.skipStart = "true".equals(skipStart);
-        }
-        String skipEnd = formElement.getAttribute("skip-end");
-        if (skipEnd.isEmpty() && parentModelForm != null) {
-            this.skipEnd = parentModelForm.skipEnd;
-        } else {
-            this.skipEnd = "true".equals(skipEnd);
-        }
-        String useRowSubmit = formElement.getAttribute("use-row-submit");
-        if (useRowSubmit.isEmpty() && parentModelForm != null) {
-            this.useRowSubmit = parentModelForm.useRowSubmit;
-        } else {
-            this.useRowSubmit = "true".equals(useRowSubmit);
-        }
-        FlexibleStringExpander rowCountExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("row-count"));
-        if (rowCountExdr.isEmpty() && parentModelForm != null) {
-            rowCountExdr = parentModelForm.rowCountExdr;
-        }
-        this.rowCountExdr = paginate;
-        ArrayList<ModelFormFieldBuilder> multiSubmitBuilders = new ArrayList<ModelFormFieldBuilder>();
-        ArrayList<AutoFieldsService> autoFieldsServices = new ArrayList<AutoFieldsService>();
-        ArrayList<AutoFieldsEntity> autoFieldsEntities = new ArrayList<AutoFieldsEntity>();
-        ArrayList<SortField> sortOrderFields = new ArrayList<SortField>();
-        this.defaultFieldGroup = new FieldGroup(null, this, sortOrderFields, fieldGroupMap);
-        for (Element autoFieldsServiceElement : UtilXml.childElementList(formElement, "auto-fields-service")) {
-            AutoFieldsService autoFieldsService = new AutoFieldsService(autoFieldsServiceElement);
-            autoFieldsServices.add(autoFieldsService);
-            addAutoFieldsFromService(autoFieldsService, entityModelReader, dispatchContext, useWhenFields, fieldBuilderList, fieldBuilderMap);
-        }
-        for (Element autoFieldsEntityElement : UtilXml.childElementList(formElement, "auto-fields-entity")) {
-            AutoFieldsEntity autoFieldsEntity = new AutoFieldsEntity(autoFieldsEntityElement);
-            autoFieldsEntities.add(autoFieldsEntity);
-            addAutoFieldsFromEntity(autoFieldsEntity, entityModelReader, useWhenFields, fieldBuilderList, fieldBuilderMap);
-        }
-        String thisType = this.getType();
-        for (Element fieldElement : UtilXml.childElementList(formElement, "field")) {
-            ModelFormFieldBuilder builder = new ModelFormFieldBuilder(fieldElement, this, entityModelReader, dispatchContext);
-            FieldInfo fieldInfo = builder.getFieldInfo();
-            if (thisType.equals("multi") && fieldInfo instanceof ModelFormField.SubmitField) {
-                multiSubmitBuilders.add(builder);
-            } else {
-                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
-            }
-        }
-        // get the sort-order
-        Element sortOrderElement = UtilXml.firstChildElement(formElement, "sort-order");
-        if (sortOrderElement != null) {
-            FieldGroup lastFieldGroup = new FieldGroup(null, this, sortOrderFields, fieldGroupMap);
-            fieldGroupList.add(lastFieldGroup);
-            // read in sort-field
-            for (Element sortFieldElement : UtilXml.childElementList(sortOrderElement)) {
-                String tagName = sortFieldElement.getTagName();
-                if (tagName.equals("sort-field")) {
-                    String fieldName = sortFieldElement.getAttribute("name");
-                    String position = sortFieldElement.getAttribute("position");
-                    sortOrderFields.add(new SortField(fieldName, position));
-                    fieldGroupMap.put(fieldName, lastFieldGroup);
-                } else if (tagName.equals("last-field")) {
-                    String fieldName = sortFieldElement.getAttribute("name");
-                    fieldGroupMap.put(fieldName, lastFieldGroup);
-                    lastOrderFields.add(fieldName);
-                } else if (tagName.equals("banner")) {
-                    Banner thisBanner = new Banner(sortFieldElement);
-                    fieldGroupList.add(thisBanner);
-                    lastFieldGroup = new FieldGroup(null, this, sortOrderFields, fieldGroupMap);
-                    fieldGroupList.add(lastFieldGroup);
-                } else if (tagName.equals("field-group")) {
-                    FieldGroup thisFieldGroup = new FieldGroup(sortFieldElement, this, sortOrderFields, fieldGroupMap);
-                    fieldGroupList.add(thisFieldGroup);
-                    lastFieldGroup = new FieldGroup(null, this, sortOrderFields, fieldGroupMap);
-                    fieldGroupList.add(lastFieldGroup);
-                }
-            }
-        }
-        if (sortOrderFields.size() > 0) {
-            ArrayList<ModelFormFieldBuilder> sortedFields = new ArrayList<ModelFormFieldBuilder>();
-            for (SortField sortField : sortOrderFields) {
-                String fieldName = sortField.getFieldName();
-                if (UtilValidate.isEmpty(fieldName)) {
-                    continue;
-                }
-                // get all fields with the given name from the existing list and put them in the sorted list
-                Iterator<ModelFormFieldBuilder> fieldIter = fieldBuilderList.iterator();
-                while (fieldIter.hasNext()) {
-                    ModelFormFieldBuilder builder = fieldIter.next();
-                    if (fieldName.equals(builder.getName())) {
-                        // matched the name; remove from the original last and add to the sorted list
-                        if (UtilValidate.isNotEmpty(sortField.getPosition())) {
-                            builder.setPosition(sortField.getPosition());
-                        }
-                        fieldIter.remove();
-                        sortedFields.add(builder);
-                    }
-                }
-            }
-            // now add all of the rest of the fields from fieldList, ie those that were not explicitly listed in the sort order
-            sortedFields.addAll(fieldBuilderList);
-            // sortedFields all done, set fieldList
-            fieldBuilderList = sortedFields;
-        }
-        if (UtilValidate.isNotEmpty(lastOrderFields)) {
-            List<ModelFormFieldBuilder> lastedFields = new LinkedList<ModelFormFieldBuilder>();
-            for (String fieldName : lastOrderFields) {
-                if (UtilValidate.isEmpty(fieldName)) {
-                    continue;
-                }
-                // get all fields with the given name from the existing list and put them in the lasted list
-                Iterator<ModelFormFieldBuilder> fieldIter = fieldBuilderList.iterator();
-                while (fieldIter.hasNext()) {
-                    ModelFormFieldBuilder builder = fieldIter.next();
-                    if (fieldName.equals(builder.getName())) {
-                        // matched the name; remove from the original last and add to the lasted list
-                        fieldIter.remove();
-                        lastedFields.add(builder);
-                    }
-                }
-            }
-            //now put all lastedFields at the field list end
-            fieldBuilderList.addAll(lastedFields);
-        }
-        List<ModelFormField> fieldList = new ArrayList<ModelFormField>(fieldBuilderList.size());
-        for (ModelFormFieldBuilder builder : fieldBuilderList) {
-            fieldList.add(builder.build());
-        }
-        this.fieldList = Collections.unmodifiableList(fieldList);
-        List<ModelFormField> multiSubmitFields = new ArrayList<ModelFormField>(multiSubmitBuilders.size());
-        for (ModelFormFieldBuilder builder : multiSubmitBuilders) {
-            multiSubmitFields.add(builder.build());
-        }
-        this.multiSubmitFields = Collections.unmodifiableList(multiSubmitFields);
-        this.useWhenFields = Collections.unmodifiableSet(useWhenFields);
-        this.fieldGroupMap = Collections.unmodifiableMap(fieldGroupMap);
-        fieldGroupList.trimToSize();
-        this.fieldGroupList = Collections.unmodifiableList(fieldGroupList);
-        lastOrderFields.trimToSize();
-        this.lastOrderFields = Collections.unmodifiableList(lastOrderFields);
-        autoFieldsServices.trimToSize();
-        this.autoFieldsServices = Collections.unmodifiableList(autoFieldsServices);
-        autoFieldsEntities.trimToSize();
-        this.autoFieldsEntities = Collections.unmodifiableList(autoFieldsEntities);
-        sortOrderFields.trimToSize();
-        this.sortOrderFields = Collections.unmodifiableList(sortOrderFields);
-        String focusFieldName = formElement.getAttribute("focus-field-name");
-        if (focusFieldName.isEmpty() && parentModelForm != null) {
-            focusFieldName = parentModelForm.focusFieldName;
-        }
-        this.focusFieldName = focusFieldName;
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
-    }
-
-    private void addAutoFieldsFromEntity(AutoFieldsEntity autoFieldsEntity, ModelReader entityModelReader,
-            Set<String> useWhenFields, List<ModelFormFieldBuilder> fieldBuilderList, Map<String, ModelFormFieldBuilder> fieldBuilderMap) {
-        // read entity def and auto-create fields
-        ModelEntity modelEntity = null;
-        try {
-            modelEntity = entityModelReader.getModelEntity(autoFieldsEntity.entityName);
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-        }
-        if (modelEntity == null) {
-            throw new IllegalArgumentException("Error finding Entity with name " + autoFieldsEntity.entityName
-                    + " for auto-fields-entity in a form widget");
-        }
-        Iterator<ModelField> modelFieldIter = modelEntity.getFieldsIterator();
-        while (modelFieldIter.hasNext()) {
-            ModelField modelField = modelFieldIter.next();
-            if (modelField.getIsAutoCreatedInternal()) {
-                // don't ever auto-add these, should only be added if explicitly referenced
-                continue;
-            }
-            ModelFormFieldBuilder builder = new ModelFormFieldBuilder();
-            builder.setModelForm(this);
-            builder.setName(modelField.getName());
-            builder.setEntityName(modelEntity.getEntityName());
-            builder.setFieldName(modelField.getName());
-            builder.induceFieldInfoFromEntityField(modelEntity, modelField, autoFieldsEntity.defaultFieldType);
-            builder.setPosition(autoFieldsEntity.defaultPosition);
-            if (UtilValidate.isNotEmpty(autoFieldsEntity.mapName)) {
-                builder.setMapName(autoFieldsEntity.mapName);
-            }
-            addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
-        }
-    }
-
-    private void addAutoFieldsFromService(AutoFieldsService autoFieldsService, ModelReader entityModelReader,
-            DispatchContext dispatchContext, Set<String> useWhenFields, List<ModelFormFieldBuilder> fieldBuilderList,
-            Map<String, ModelFormFieldBuilder> fieldBuilderMap) {
-        // read service def and auto-create fields
-        ModelService modelService = null;
-        try {
-            modelService = dispatchContext.getModelService(autoFieldsService.serviceName);
-        } catch (GenericServiceException e) {
-            String errmsg = "Error finding Service with name " + autoFieldsService.serviceName
-                    + " for auto-fields-service in a form widget";
-            Debug.logError(e, errmsg, module);
-            throw new IllegalArgumentException(errmsg);
-        }
-        for (ModelParam modelParam : modelService.getInModelParamList()) {
-            if (modelParam.internal) {
-                // skip auto params that the service engine populates...
-                continue;
-            }
-            if (modelParam.formDisplay) {
-                if (UtilValidate.isNotEmpty(modelParam.entityName) && UtilValidate.isNotEmpty(modelParam.fieldName)) {
-                    ModelEntity modelEntity;
-                    try {
-                        modelEntity = entityModelReader.getModelEntity(modelParam.entityName);
-                        if (modelEntity != null) {
-                            ModelField modelField = modelEntity.getField(modelParam.fieldName);
-                            if (modelField != null) {
-                                // okay, populate using the entity field info...
-                                ModelFormFieldBuilder builder = new ModelFormFieldBuilder();
-                                builder.setModelForm(this);
-                                builder.setName(modelField.getName());
-                                builder.setEntityName(modelEntity.getEntityName());
-                                builder.setFieldName(modelField.getName());
-                                builder.induceFieldInfoFromEntityField(modelEntity, modelField, autoFieldsService.defaultFieldType);
-                                if (UtilValidate.isNotEmpty(autoFieldsService.mapName)) {
-                                    builder.setMapName(autoFieldsService.mapName);
-                                }
-                                builder.setRequiredField(!modelParam.optional);
-                                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
-                                // continue to skip creating based on service param
-                                continue;
-                            }
-                        }
-                    } catch (GenericEntityException e) {
-                        Debug.logError(e, module);
-                    }
-                }
-                ModelFormFieldBuilder builder = new ModelFormFieldBuilder();
-                builder.setModelForm(this);
-                builder.setName(modelParam.name);
-                builder.setServiceName(modelService.name);
-                builder.setAttributeName(modelParam.name);
-                builder.setTitle(modelParam.formLabel);
-                builder.setRequiredField(!modelParam.optional);
-                builder.induceFieldInfoFromServiceParam(modelService, modelParam, autoFieldsService.defaultFieldType);
-                builder.setPosition(autoFieldsService.defaultPosition);
-                if (UtilValidate.isNotEmpty(autoFieldsService.mapName)) {
-                    builder.setMapName(autoFieldsService.mapName);
-                }
-                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
-            }
-        }
-    }
-
-    private void addUpdateField(ModelFormFieldBuilder builder, Set<String> useWhenFields,
-            List<ModelFormFieldBuilder> fieldBuilderList, Map<String, ModelFormFieldBuilder> fieldBuilderMap) {
-        if (!builder.getUseWhen().isEmpty() || useWhenFields.contains(builder.getName())) {
-            useWhenFields.add(builder.getName());
-            // is a conditional field, add to the List but don't worry about the Map
-            //for adding to list, see if there is another field with that name in the list and if so, put it before that one
-            boolean inserted = false;
-            for (int i = 0; i < fieldBuilderList.size(); i++) {
-                ModelFormFieldBuilder curField = fieldBuilderList.get(i);
-                if (curField.getName() != null && curField.getName().equals(builder.getName())) {
-                    fieldBuilderList.add(i, builder);
-                    inserted = true;
-                    break;
-                }
-            }
-            if (!inserted) {
-                fieldBuilderList.add(builder);
-            }
-            return;
-        } else {
-            // not a conditional field, see if a named field exists in Map
-            ModelFormFieldBuilder existingField = fieldBuilderMap.get(builder.getName());
-            if (existingField != null) {
-                // does exist, update the field by doing a merge/override
-                existingField.mergeOverrideModelFormField(builder);
-            } else {
-                // does not exist, add to List and Map
-                fieldBuilderList.add(builder);
-                fieldBuilderMap.put(builder.getName(), builder);
-            }
-        }
-    }
-
-    public List<ModelAction> getActions() {
-        return actions;
-    }
-
-    public List<AltRowStyle> getAltRowStyles() {
-        return altRowStyles;
-    }
-
-    public List<AltTarget> getAltTargets() {
-        return altTargets;
-    }
-
-    public List<AutoFieldsEntity> getAutoFieldsEntities() {
-        return autoFieldsEntities;
-    }
-
-    public List<AutoFieldsService> getAutoFieldsServices() {
-        return autoFieldsServices;
-    }
-
-    public Interpreter getBshInterpreter(Map<String, Object> context) throws EvalError {
-        Interpreter bsh = (Interpreter) context.get("bshInterpreter");
-        if (bsh == null) {
-            bsh = BshUtil.makeInterpreter(context);
-            context.put("bshInterpreter", bsh);
-        }
-        return bsh;
-    }
-
-    @Override
-    public String getBoundaryCommentName() {
-        return formLocation + "#" + getName();
-    }
-
-    public boolean getClientAutocompleteFields() {
-        return this.clientAutocompleteFields;
-    }
-
-    public String getContainerId() {
-        // use the name if there is no id
-        if (UtilValidate.isNotEmpty(this.containerId)) {
-            return this.containerId;
-        } else {
-            return this.getName();
-        }
-    }
-
-    public String getContainerStyle() {
-        return this.containerStyle;
-    }
-
-    public String getDefaultEntityName() {
-        return this.defaultEntityName;
-    }
-
-    public FieldGroup getDefaultFieldGroup() {
-        return defaultFieldGroup;
-    }
-
-    public Map<String, ? extends Object> getDefaultMap(Map<String, ? extends Object> context) {
-        return this.defaultMapName.get(context);
-    }
-
-    public String getDefaultMapName() {
-        return this.defaultMapName.getOriginalName();
-    }
-
-    public String getDefaultRequiredFieldStyle() {
-        return this.defaultRequiredFieldStyle;
-    }
-
-    public String getDefaultServiceName() {
-        return this.defaultServiceName;
-    }
-
-    public String getDefaultSortFieldAscStyle() {
-        return this.defaultSortFieldAscStyle;
-    }
-
-    public String getDefaultSortFieldDescStyle() {
-        return this.defaultSortFieldDescStyle;
-    }
-
-    public String getDefaultSortFieldStyle() {
-        return this.defaultSortFieldStyle;
-    }
-
-    public String getDefaultTableStyle() {
-        return this.defaultTableStyle;
-    }
-
-    public String getDefaultTitleAreaStyle() {
-        return this.defaultTitleAreaStyle;
-    }
-
-    public String getDefaultTitleStyle() {
-        return this.defaultTitleStyle;
-    }
-
-    public String getDefaultTooltipStyle() {
-        return this.defaultTooltipStyle;
-    }
-
-    public int getDefaultViewSize() {
-        return defaultViewSize;
-    }
-
-    public String getDefaultWidgetAreaStyle() {
-        return this.defaultWidgetAreaStyle;
-    }
-
-    public String getDefaultWidgetStyle() {
-        return this.defaultWidgetStyle;
-    }
-
-    public String getEvenRowStyle() {
-        return this.evenRowStyle;
-    }
-
-    public List<FieldGroupBase> getFieldGroupList() {
-        return fieldGroupList;
-    }
-
-    public Map<String, FieldGroupBase> getFieldGroupMap() {
-        return fieldGroupMap;
-    }
-
-    public List<ModelFormField> getFieldList() {
-        return fieldList;
-    }
-
-    public String getFocusFieldName() {
-        return focusFieldName;
-    }
-
-    public String getFormLocation() {
-        return this.formLocation;
-    }
-
-    public String getFormTitleAreaStyle() {
-        return this.formTitleAreaStyle;
-    }
-
-    public String getFormWidgetAreaStyle() {
-        return this.formWidgetAreaStyle;
-    }
-
-    public String getHeaderRowStyle() {
-        return this.headerRowStyle;
-    }
-
-    public boolean getHideHeader() {
-        return this.hideHeader;
-    }
-
-    public String getItemIndexSeparator() {
-        if (UtilValidate.isNotEmpty(this.itemIndexSeparator)) {
-            return this.itemIndexSeparator;
-        } else {
-            return "_o_";
-        }
-    }
-
-    public List<String> getLastOrderFields() {
-        return lastOrderFields;
-    }
-
-    public String getListEntryName() {
-        return this.listEntryName;
-    }
-
-    public String getListName() {
-        return this.listName;
-    }
-
-    public String getMultiPaginateIndexField(Map<String, Object> context) {
-        String field = this.paginateIndexField.expandString(context);
-        if (UtilValidate.isEmpty(field)) {
-            field = DEFAULT_PAG_INDEX_FIELD;
-        }
-        //  append the paginator number
-        field = field + "_" + WidgetWorker.getPaginatorNumber(context);
-        return field;
-    }
-
-    public String getMultiPaginateSizeField(Map<String, Object> context) {
-        String field = this.paginateSizeField.expandString(context);
-        if (UtilValidate.isEmpty(field)) {
-            field = DEFAULT_PAG_SIZE_FIELD;
-        }
-        //  append the paginator number
-        field = field + "_" + WidgetWorker.getPaginatorNumber(context);
-        return field;
-    }
-
-    public List<ModelFormField> getMultiSubmitFields() {
-        return this.multiSubmitFields;
-    }
-
-    public String getOddRowStyle() {
-        return this.oddRowStyle;
-    }
-
-    public List<UpdateArea> getOnPaginateUpdateAreas() {
-        return this.onPaginateUpdateAreas;
-    }
-
-    public List<UpdateArea> getOnSortColumnUpdateAreas() {
-        return this.onSortColumnUpdateAreas;
-    }
-
-    /* Returns the list of ModelForm.UpdateArea objects.
-     */
-    public List<UpdateArea> getOnSubmitUpdateAreas() {
-        return this.onSubmitUpdateAreas;
-    }
-
-    public String getOverrideListSize() {
-        return overrideListSize.getOriginal();
-    }
-
-    public int getOverrideListSize(Map<String, Object> context) {
-        int listSize = 0;
-        if (!this.overrideListSize.isEmpty()) {
-            String size = this.overrideListSize.expandString(context);
-            try {
-                size = size.replaceAll("[^0-9.]", "");
-                listSize = Integer.parseInt(size);
-            } catch (NumberFormatException e) {
-                Debug.logError(e, "Error getting override list size from value " + size, module);
-            }
-        }
-        return listSize;
-    }
-
-    public String getPaginate() {
-        return paginate.getOriginal();
-    }
-
-    public boolean getPaginate(Map<String, Object> context) {
-        String paginate = this.paginate.expandString(context);
-        if (!paginate.isEmpty()) {
-            return Boolean.valueOf(paginate).booleanValue();
-        } else {
-            return true;
-        }
-    }
-
-    public String getPaginateFirstLabel() {
-        return paginateFirstLabel.getOriginal();
-    }
-
-    public String getPaginateFirstLabel(Map<String, Object> context) {
-        Locale locale = (Locale) context.get("locale");
-        String field = this.paginateFirstLabel.expandString(context);
-        if (UtilValidate.isEmpty(field)) {
-            field = UtilProperties.getMessage("CommonUiLabels", "CommonFirst", locale);
-        }
-        return field;
-    }
-
-    public String getPaginateFirstStyle() {
-        return DEFAULT_PAG_FIRST_STYLE;
-    }
-
-    public String getPaginateIndexField() {
-        return paginateIndexField.getOriginal();
-    }
-
-    public String getPaginateIndexField(Map<String, Object> context) {
-        String field = this.paginateIndexField.expandString(context);
-        if (field.isEmpty()) {
-            return DEFAULT_PAG_INDEX_FIELD;
-        }
-        return field;
-    }
-
-    public String getPaginateLastLabel() {
-        return paginateLastLabel.getOriginal();
-    }
-
-    public String getPaginateLastLabel(Map<String, Object> context) {
-        Locale locale = (Locale) context.get("locale");
-        String field = this.paginateLastLabel.expandString(context);
-        if (UtilValidate.isEmpty(field)) {
-            field = UtilProperties.getMessage("CommonUiLabels", "CommonLast", locale);
-        }
-        return field;
-    }
-
-    public String getPaginateLastStyle() {
-        return DEFAULT_PAG_LAST_STYLE;
-    }
-
-    public String getPaginateNextLabel() {
-        return paginateNextLabel.getOriginal();
-    }
-
-    public String getPaginateNextLabel(Map<String, Object> context) {
-        String field = this.paginateNextLabel.expandString(context);
-        if (field.isEmpty()) {
-            Locale locale = (Locale) context.get("locale");
-            return UtilProperties.getMessage("CommonUiLabels", "CommonNext", locale);
-        }
-        return field;
-    }
-
-    public String getPaginateNextStyle() {
-        return DEFAULT_PAG_NEXT_STYLE;
-    }
-
-    public String getPaginatePreviousLabel() {
-        return paginatePreviousLabel.getOriginal();
-    }
-
-    public String getPaginatePreviousLabel(Map<String, Object> context) {
-        String field = this.paginatePreviousLabel.expandString(context);
-        if (field.isEmpty()) {
-            Locale locale = (Locale) context.get("locale");
-            field = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", locale);
-        }
-        return field;
-    }
-
-    public String getPaginatePreviousStyle() {
-        return DEFAULT_PAG_PREV_STYLE;
-    }
-
-    public String getPaginateSizeField() {
-        return paginateSizeField.getOriginal();
-    }
-
-    public String getPaginateSizeField(Map<String, Object> context) {
-        String field = this.paginateSizeField.expandString(context);
-        if (field.isEmpty()) {
-            return DEFAULT_PAG_SIZE_FIELD;
-        }
-        return field;
-    }
-
-    public String getPaginateStyle() {
-        return this.paginateStyle;
-    }
-
-    public String getPaginateTarget() {
-        return paginateTarget.getOriginal();
-    }
-
-    public String getPaginateTarget(Map<String, Object> context) {
-        String targ = this.paginateTarget.expandString(context);
-        if (targ.isEmpty()) {
-            Map<String, ?> parameters = UtilGenerics.cast(context.get("parameters"));
-            if (parameters != null && parameters.containsKey("targetRequestUri")) {
-                targ = (String) parameters.get("targetRequestUri");
-            }
-        }
-        return targ;
-    }
-
-    public String getPaginateTargetAnchor() {
-        return this.paginateTargetAnchor;
-    }
-
-    public String getPaginateViewSizeLabel() {
-        return paginateViewSizeLabel.getOriginal();
-    }
-
-    public String getPaginateViewSizeLabel(Map<String, Object> context) {
-        String field = this.paginateViewSizeLabel.expandString(context);
-        if (field.isEmpty()) {
-            Locale locale = (Locale) context.get("locale");
-            return UtilProperties.getMessage("CommonUiLabels", "CommonItemsPerPage", locale);
-        }
-        return field;
-    }
-
-    private ModelForm getParentForm(Element formElement, ModelReader entityModelReader, DispatchContext dispatchContext) {
-        ModelForm parent = null;
-        String parentResource = formElement.getAttribute("extends-resource");
-        String parentForm = formElement.getAttribute("extends");
-        if (parentForm.length() > 0) {
-            // check if we have a resource name (part of the string before the ?)
-            if (parentResource.length() > 0) {
-                try {
-                    parent = FormFactory.getFormFromLocation(parentResource, parentForm, entityModelReader, dispatchContext);
-                } catch (Exception e) {
-                    Debug.logError(e, "Failed to load parent form definition '" + parentForm + "' at resource '" + parentResource
-                            + "'", module);
-                }
-            } else if (!parentForm.equals(formElement.getAttribute("name"))) {
-                // try to find a form definition in the same file
-                Element rootElement = formElement.getOwnerDocument().getDocumentElement();
-                List<? extends Element> formElements = UtilXml.childElementList(rootElement, "form");
-                //Uncomment below to add support for abstract forms
-                //formElements.addAll(UtilXml.childElementList(rootElement, "abstract-form"));
-                for (Element formElementEntry : formElements) {
-                    if (formElementEntry.getAttribute("name").equals(parentForm)) {
-                        parent = new ModelForm(formElementEntry, parentResource, entityModelReader, dispatchContext);
-                        break;
-                    }
-                }
-                if (parent == null) {
-                    Debug.logError("Failed to find parent form definition '" + parentForm + "' in same document.", module);
-                }
-            } else {
-                Debug.logError("Recursive form definition found for '" + formElement.getAttribute("name") + ".'", module);
-            }
-        }
-        return parent;
-    }
-
-    public String getParentFormLocation() {
-        return this.parentModelForm == null ? null : this.parentModelForm.getFormLocation();
-    }
-
-    public String getParentFormName() {
-        return this.parentModelForm == null ? null : this.parentModelForm.getName();
-    }
-
-    public ModelForm getParentModelForm() {
-        return parentModelForm;
-    }
-
-    public String getPassedRowCount(Map<String, Object> context) {
-        return rowCountExdr.expandString(context);
-    }
-
-    public List<ModelAction> getRowActions() {
-        return rowActions;
-    }
-
-    public String getRowCount() {
-        return rowCountExdr.getOriginal();
-    }
-
-    public boolean getSeparateColumns() {
-        return this.separateColumns;
-    }
-
-    public boolean getSkipEnd() {
-        return this.skipEnd;
-    }
-
-    public boolean getSkipStart() {
-        return this.skipStart;
-    }
-
-    public String getSortField(Map<String, Object> context) {
-        String value = null;
-        try {
-            value = (String) context.get(this.sortFieldParameterName);
-            if (value == null) {
-                Map<String, String> parameters = UtilGenerics.cast(context.get("parameters"));
-                if (parameters != null) {
-                    value = parameters.get(this.sortFieldParameterName);
-                }
-            }
-        } catch (Exception e) {
-            Debug.logWarning(e, "Error getting sortField: " + e.toString(), module);
-        }
-        return value;
-    }
-
-    public String getSortFieldParameterName() {
-        return this.sortFieldParameterName;
-    }
-
-    public List<SortField> getSortOrderFields() {
-        return sortOrderFields;
-    }
-
-    /**
-     * iterate through alt-row-styles list to see if should be used, then add style
-     * @return The style for item row
-     */
-    public String getStyleAltRowStyle(Map<String, Object> context) {
-        String styles = "";
-        try {
-            // use the same Interpreter (ie with the same context setup) for all evals
-            Interpreter bsh = this.getBshInterpreter(context);
-            for (AltRowStyle altRowStyle : this.altRowStyles) {
-                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(altRowStyle.useWhen));
-                // retVal should be a Boolean, if not something weird is up...
-                if (retVal instanceof Boolean) {
-                    Boolean boolVal = (Boolean) retVal;
-                    if (boolVal.booleanValue()) {
-                        styles += altRowStyle.style;
-                    }
-                } else {
-                    throw new IllegalArgumentException("Return value from style condition eval was not a Boolean: "
-                            + retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
-                }
-            }
-        } catch (EvalError e) {
-            String errmsg = "Error evaluating BeanShell style conditions on form " + getName();
-            Debug.logError(e, errmsg, module);
-            throw new IllegalArgumentException(errmsg);
-        }
-        return styles;
-    }
-
-    public String getTarget() {
-        return target.getOriginal();
-    }
-
-    /** iterate through altTargets list to see if any should be used, if not return original target
-     * @return The target for this Form
-     */
-    public String getTarget(Map<String, Object> context, String targetType) {
-        Map<String, Object> expanderContext = context;
-        UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-        if (simpleEncoder != null) {
-            expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
-        }
-        try {
-            // use the same Interpreter (ie with the same context setup) for all evals
-            Interpreter bsh = this.getBshInterpreter(context);
-            for (AltTarget altTarget : this.altTargets) {
-                String useWhen = FlexibleStringExpander.expandString(altTarget.useWhen, context);
-                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
-                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 target condition eval was not a Boolean: "
-                            + retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
-                }
-
-                if (condTrue && !targetType.equals("inter-app")) {
-                    return altTarget.targetExdr.expandString(expanderContext);
-                }
-            }
-        } catch (EvalError e) {
-            String errmsg = "Error evaluating BeanShell target conditions on form " + getName();
-            Debug.logError(e, errmsg, module);
-            throw new IllegalArgumentException(errmsg);
-        }
-        return target.expandString(expanderContext);
-    }
-
-    public String getTargetType() {
-        return this.targetType;
-    }
-
-    public String getTargetWindow() {
-        return targetWindowExdr.getOriginal();
-    }
-
-    public String getTargetWindow(Map<String, Object> context) {
-        return this.targetWindowExdr.expandString(context);
-    }
-
-    public String getTitle() {
-        return this.title;
-    }
-
-    public String getTooltip() {
-        return this.tooltip;
-    }
-
-    public String getType() {
-        return this.type;
-    }
-
-    public boolean getUseRowSubmit() {
-        return this.useRowSubmit;
-    }
-
-    public Set<String> getUseWhenFields() {
-        return useWhenFields;
-    }
-    public boolean getGroupColumns() {
-        return groupColumns;
-    }
-
-    public boolean isOverridenListSize() {
-        return !this.overrideListSize.isEmpty();
-    }
-
-    public void runFormActions(Map<String, Object> context) {
-        AbstractModelAction.runSubActions(this.actions, context);
-    }
-
-    public static class AltRowStyle {
-        public final String useWhen;
-        public final String style;
-
-        public AltRowStyle(Element altRowStyleElement) {
-            this.useWhen = altRowStyleElement.getAttribute("use-when");
-            this.style = altRowStyleElement.getAttribute("style");
-        }
-    }
-
-    public static class AltTarget {
-        public final String useWhen;
-        public final FlexibleStringExpander targetExdr;
-
-        public AltTarget(Element altTargetElement) {
-            this.useWhen = altTargetElement.getAttribute("use-when");
-            this.targetExdr = FlexibleStringExpander.getInstance(altTargetElement.getAttribute("target"));
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            return obj instanceof AltTarget && obj.hashCode() == this.hashCode();
-        }
-
-        @Override
-        public int hashCode() {
-            return useWhen.hashCode();
-        }
-    }
-
-    public static class AutoFieldsEntity {
-        public final String entityName;
-        public final String mapName;
-        public final String defaultFieldType;
-        public final int defaultPosition;
-
-        public AutoFieldsEntity(Element element) {
-            this.entityName = element.getAttribute("entity-name");
-            this.mapName = element.getAttribute("map-name");
-            this.defaultFieldType = element.getAttribute("default-field-type");
-            String positionStr = element.getAttribute("default-position");
-            int position = 1;
-            try {
-                if (UtilValidate.isNotEmpty(positionStr)) {
-                    position = Integer.valueOf(positionStr);
-                }
-            } catch (Exception e) {
-                Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr
-                        + "], using the default of the form renderer", module);
-            }
-            this.defaultPosition = position;
-        }
-    }
-
-    public static class AutoFieldsService {
-        public final String serviceName;
-        public final String mapName;
-        public final String defaultFieldType;
-        public final int defaultPosition;
-
-        public AutoFieldsService(Element element) {
-            this.serviceName = element.getAttribute("service-name");
-            this.mapName = element.getAttribute("map-name");
-            this.defaultFieldType = element.getAttribute("default-field-type");
-            String positionStr = element.getAttribute("default-position");
-            int position = 1;
-            try {
-                if (UtilValidate.isNotEmpty(positionStr)) {
-                    position = Integer.valueOf(positionStr);
-                }
-            } catch (Exception e) {
-                Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr
-                        + "], using the default of the form renderer", module);
-            }
-            this.defaultPosition = position;
-        }
-    }
-
-    public static class Banner implements FieldGroupBase {
-        public final FlexibleStringExpander style;
-        public final FlexibleStringExpander text;
-        public final FlexibleStringExpander textStyle;
-        public final FlexibleStringExpander leftText;
-        public final FlexibleStringExpander leftTextStyle;
-        public final FlexibleStringExpander rightText;
-        public final FlexibleStringExpander rightTextStyle;
-
-        public Banner(Element sortOrderElement) {
-            this.style = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("style"));
-            this.text = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("text"));
-            this.textStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("text-style"));
-            this.leftText = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("left-text"));
-            this.leftTextStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("left-text-style"));
-            this.rightText = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("right-text"));
-            this.rightTextStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("right-text-style"));
-        }
-
-        public String getLeftText(Map<String, Object> context) {
-            return this.leftText.expandString(context);
-        }
-
-        public String getLeftTextStyle(Map<String, Object> context) {
-            return this.leftTextStyle.expandString(context);
-        }
-
-        public String getRightText(Map<String, Object> context) {
-            return this.rightText.expandString(context);
-        }
-
-        public String getRightTextStyle(Map<String, Object> context) {
-            return this.rightTextStyle.expandString(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return this.style.expandString(context);
-        }
-
-        public String getText(Map<String, Object> context) {
-            return this.text.expandString(context);
-        }
-
-        public String getTextStyle(Map<String, Object> context) {
-            return this.textStyle.expandString(context);
-        }
-
-        public void renderString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderBanner(writer, context, this);
-        }
-    }
-
-    public static class FieldGroup implements FieldGroupBase {
-        private static AtomicInteger baseSeqNo = new AtomicInteger(0);
-        private static final String baseId = "_G";
-        private final String id;
-        private final String style;
-        private final String title;
-        private final boolean collapsible;
-        private final boolean initiallyCollapsed;
-        private final ModelForm modelForm;
-
-        public FieldGroup(Element sortOrderElement, ModelForm modelForm, List<SortField> sortOrderFields,
-                Map<String, FieldGroupBase> fieldGroupMap) {
-            this.modelForm = modelForm;
-            String id;
-            String style = "";
-            String title = "";
-            boolean collapsible = false;
-            boolean initiallyCollapsed = false;
-            if (sortOrderElement != null) {
-                id = sortOrderElement.getAttribute("id");
-                if (id.isEmpty()) {
-                    String lastGroupId = baseId + baseSeqNo.getAndIncrement() + "_";
-                    id = lastGroupId;
-                }
-                style = sortOrderElement.getAttribute("style");
-                title = sortOrderElement.getAttribute("title");
-                collapsible = "true".equals(sortOrderElement.getAttribute("collapsible"));
-                initiallyCollapsed = "true".equals(sortOrderElement.getAttribute("initially-collapsed"));
-                if (initiallyCollapsed) {
-                    collapsible = true;
-                }
-                for (Element sortFieldElement : UtilXml.childElementList(sortOrderElement, "sort-field")) {
-                    sortOrderFields.add(new SortField(sortFieldElement.getAttribute("name"), sortFieldElement
-                            .getAttribute("position")));
-                    fieldGroupMap.put(sortFieldElement.getAttribute("name"), this);
-                }
-            } else {
-                String lastGroupId = baseId + baseSeqNo.getAndIncrement() + "_";
-                id = lastGroupId;
-            }
-            this.id = id;
-            this.style = style;
-            this.title = title;
-            this.collapsible = collapsible;
-            this.initiallyCollapsed = initiallyCollapsed;
-        }
-
-        public Boolean collapsible() {
-            return this.collapsible;
-        }
-
-        public String getId() {
-            return this.id;
-        }
-
-        public String getStyle() {
-            return this.style;
-        }
-
-        public String getTitle() {
-            return this.title;
-        }
-
-        public Boolean initiallyCollapsed() {
-            return this.initiallyCollapsed;
-        }
-
-        public void renderEndString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderFormatSingleWrapperClose(writer, context, modelForm);
-            if (!modelForm.fieldGroupList.isEmpty()) {
-                if (shouldUse(context)) {
-                    formStringRenderer.renderFieldGroupClose(writer, context, this);
-                }
-            }
-        }
-
-        public void renderStartString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            if (!modelForm.fieldGroupList.isEmpty()) {
-                if (shouldUse(context)) {
-                    formStringRenderer.renderFieldGroupOpen(writer, context, this);
-                }
-            }
-            formStringRenderer.renderFormatSingleWrapperOpen(writer, context, modelForm);
-        }
-
-        public boolean shouldUse(Map<String, Object> context) {
-            for (String fieldName : modelForm.fieldGroupMap.keySet()) {
-                FieldGroupBase group = modelForm.fieldGroupMap.get(fieldName);
-                if (group instanceof FieldGroup) {
-                    FieldGroup fieldgroup = (FieldGroup) group;
-                    if (this.id.equals(fieldgroup.getId())) {
-                        for (ModelFormField modelField : modelForm.fieldList) {
-                            if (fieldName.equals(modelField.getName()) && modelField.shouldUse(context)) {
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-            return false;
-        }
-    }
-
-    public static interface FieldGroupBase {
-    }
-
-    public static class SortField {
-        private final String fieldName;
-        private final Integer position;
-
-        public SortField(String name) {
-            this(name, null);
-        }
-
-        public SortField(String name, String position) {
-            this.fieldName = name;
-            if (UtilValidate.isNotEmpty(position)) {
-                Integer posParam = null;
-                try {
-                    posParam = Integer.valueOf(position);
-                } catch (Exception e) {/* just ignore the exception*/
-                }
-                this.position = posParam;
-            } else {
-                this.position = null;
-            }
-        }
-
-        public String getFieldName() {
-            return this.fieldName;
-        }
-
-        public Integer getPosition() {
-            return this.position;
-        }
-    }
-
-    /** The UpdateArea class implements the <code>&lt;on-event-update-area&gt;</code>
-     * elements used in form widgets.
-     */
-    public static class UpdateArea {
-        private final String eventType;
-        private final String areaId;
-        private final String areaTarget;
-        private final String defaultServiceName;
-        private final String defaultEntityName;
-        private final CommonWidgetModels.AutoEntityParameters autoEntityParameters;
-        private final CommonWidgetModels.AutoServiceParameters autoServiceParameters;
-        private final List<CommonWidgetModels.Parameter> parameterList;
-
-        public UpdateArea(Element updateAreaElement) {
-            this(updateAreaElement, null, null);
-        }
-
-        /** XML constructor.
-         * @param updateAreaElement The <code>&lt;on-xxx-update-area&gt;</code>
-         * XML element.
-         */
-        public UpdateArea(Element updateAreaElement, String defaultServiceName, String defaultEntityName) {
-            this.eventType = updateAreaElement.getAttribute("event-type");
-            this.areaId = updateAreaElement.getAttribute("area-id");
-            this.areaTarget = updateAreaElement.getAttribute("area-target");
-            this.defaultServiceName = defaultServiceName;
-            this.defaultEntityName = defaultEntityName;
-            List<? extends Element> parameterElementList = UtilXml.childElementList(updateAreaElement, "parameter");
-            if (parameterElementList.isEmpty()) {
-                this.parameterList = Collections.emptyList();
-            } else {
-                List<CommonWidgetModels.Parameter> parameterList = new ArrayList<CommonWidgetModels.Parameter>(parameterElementList.size());
-                for (Element parameterElement : parameterElementList) {
-                    parameterList.add(new CommonWidgetModels.Parameter(parameterElement));
-                }
-                this.parameterList = Collections.unmodifiableList(parameterList);
-            }
-            Element autoServiceParamsElement = UtilXml.firstChildElement(updateAreaElement, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                this.autoServiceParameters = new CommonWidgetModels.AutoServiceParameters(autoServiceParamsElement);
-            } else {
-                this.autoServiceParameters = null;
-            }
-            Element autoEntityParamsElement = UtilXml.firstChildElement(updateAreaElement, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                this.autoEntityParameters = new CommonWidgetModels.AutoEntityParameters(autoEntityParamsElement);
-            } else {
-                this.autoEntityParameters = null;
-            }
-        }
-
-        /** String constructor.
-         * @param areaId The id of the widget element to be updated
-         * @param areaTarget The target URL called to update the area
-         */
-        public UpdateArea(String eventType, String areaId, String areaTarget) {
-            this.eventType = eventType;
-            this.areaId = areaId;
-            this.areaTarget = areaTarget;
-            this.defaultServiceName = null;
-            this.defaultEntityName = null;
-            this.parameterList = Collections.emptyList();
-            this.autoServiceParameters = null;
-            this.autoEntityParameters = null;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            return obj instanceof UpdateArea && obj.hashCode() == this.hashCode();
-        }
-
-        public String getAreaId() {
-            return areaId;
-        }
-
-        public String getAreaTarget(Map<String, ? extends Object> context) {
-            return FlexibleStringExpander.expandString(areaTarget, context);
-        }
-
-        public String getEventType() {
-            return eventType;
-        }
-
-        public Map<String, String> getParameterMap(Map<String, Object> context) {
-            Map<String, String> fullParameterMap = new HashMap<String, String>();
-            if (autoServiceParameters != null) {
-                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, defaultServiceName));
-            }
-            if (autoEntityParameters != null) {
-                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, defaultEntityName));
-            }
-            for (CommonWidgetModels.Parameter parameter : this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-            }
-
-            return fullParameterMap;
-        }
-
-        @Override
-        public int hashCode() {
-            return areaId.hashCode();
-        }
-
-        public String getAreaTarget() {
-            return areaTarget;
-        }
-
-        public String getDefaultServiceName() {
-            return defaultServiceName;
-        }
-
-        public String getDefaultEntityName() {
-            return defaultEntityName;
-        }
-
-        public CommonWidgetModels.AutoEntityParameters getAutoEntityParameters() {
-            return autoEntityParameters;
-        }
-
-        public CommonWidgetModels.AutoServiceParameters getAutoServiceParameters() {
-            return autoServiceParameters;
-        }
-
-        public List<CommonWidgetModels.Parameter> getParameterList() {
-            return parameterList;
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.ofbiz.base.util.BshUtil;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelField;
+import org.ofbiz.entity.model.ModelReader;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.ModelParam;
+import org.ofbiz.service.ModelService;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.w3c.dom.Element;
+
+import bsh.EvalError;
+import bsh.Interpreter;
+
+/**
+ * Models the &lt;form&gt; element.
+ * 
+ * @see <code>widget-form.xsd</code>
+ */
+@SuppressWarnings("serial")
+public class ModelForm extends ModelWidget {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     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!
+     * 
+     * BE VERY CAREFUL when implementing "extends" - parent form collections
+     * must be added to child collections, not replace them. In other words,
+     * do not assign parent collection fields to child collection fields.
+     * 
+     */
+
+    public static final String module = ModelForm.class.getName();
+    public static final String DEFAULT_FORM_RESULT_LIST_NAME = "defaultFormResultList";
+    /** Pagination settings and defaults. */
+    public static int DEFAULT_PAGE_SIZE = 10;
+    public static int MAX_PAGE_SIZE = 10000;
+    public static String DEFAULT_PAG_INDEX_FIELD = "viewIndex";
+    public static String DEFAULT_PAG_SIZE_FIELD = "viewSize";
+    public static String DEFAULT_PAG_STYLE = "nav-pager";
+    public static String DEFAULT_PAG_FIRST_STYLE = "nav-first";
+    public static String DEFAULT_PAG_PREV_STYLE = "nav-previous";
+    public static String DEFAULT_PAG_NEXT_STYLE = "nav-next";
+    public static String DEFAULT_PAG_LAST_STYLE = "nav-last";
+    /** Sort field default styles. */
+    public static String DEFAULT_SORT_FIELD_STYLE = "sort-order";
+    public static String DEFAULT_SORT_FIELD_ASC_STYLE = "sort-order-asc";
+    public static String DEFAULT_SORT_FIELD_DESC_STYLE = "sort-order-desc";
+    private final List<ModelAction> actions;
+    private final List<AltRowStyle> altRowStyles;
+    private final List<AltTarget> altTargets;
+    private final List<AutoFieldsEntity> autoFieldsEntities;
+    private final List<AutoFieldsService> autoFieldsServices;
+    private final boolean clientAutocompleteFields;
+    private final String containerId;
+    private final String containerStyle;
+    private final String defaultEntityName;
+    /** This field group will be the "catch-all" group for fields that are not
+     *  included in an explicit field-group.
+     */
+    private final FieldGroup defaultFieldGroup;
+    private final FlexibleMapAccessor<Map<String, ? extends Object>> defaultMapName;
+    private final String defaultRequiredFieldStyle;
+    private final String defaultServiceName;
+    private final String defaultSortFieldAscStyle;
+    private final String defaultSortFieldDescStyle;
+    private final String defaultSortFieldStyle;
+    private final String defaultTableStyle;
+    private final String defaultTitleAreaStyle;
+    private final String defaultTitleStyle;
+    private final String defaultTooltipStyle;
+    private final int defaultViewSize;
+    private final String defaultWidgetAreaStyle;
+    private final String defaultWidgetStyle;
+    private final String evenRowStyle;
+    /** This is a list of FieldGroups in the order they were created.
+     * Can also include Banner objects.
+     */
+    private final List<FieldGroupBase> fieldGroupList;
+    /** This Map is keyed with the field name and has a FieldGroup for the value.
+     * Can also include Banner objects.
+     */
+    private final Map<String, FieldGroupBase> fieldGroupMap;
+    /** This List will contain one copy of each field for each field name in the order
+     * they were encountered in the service, entity, or form definition; field definitions
+     * with constraints will also be in this list but may appear multiple times for the same
+     * field name.
+     *
+     * When rendering the form the order in this list should be following and it should not be
+     * necessary to use the Map. The Map is used when loading the form definition to keep the
+     * list clean and implement the override features for field definitions.
+     */
+    private final List<ModelFormField> fieldList;
+    private final String focusFieldName;
+    private final String formLocation;
+    private final String formTitleAreaStyle;
+    private final String formWidgetAreaStyle;
+    private final boolean groupColumns;
+    private final String headerRowStyle;
+    private final boolean hideHeader;
+    private final String itemIndexSeparator;
+    private final List<String> lastOrderFields;
+    private final String listEntryName;
+    private final String listName;
+    private final List<ModelFormField> multiSubmitFields;
+    private final String oddRowStyle;
+    /** On Paginate areas to be updated. */
+    private final List<UpdateArea> onPaginateUpdateAreas;
+    /** On Sort Column areas to be updated. */
+    private final List<UpdateArea> onSortColumnUpdateAreas;
+    /** On Submit areas to be updated. */
+    private final List<UpdateArea> onSubmitUpdateAreas;
+    private final FlexibleStringExpander overrideListSize;
+    private final FlexibleStringExpander paginate;
+    private final FlexibleStringExpander paginateFirstLabel;
+    private final FlexibleStringExpander paginateIndexField;
+    private final FlexibleStringExpander paginateLastLabel;
+    private final FlexibleStringExpander paginateNextLabel;
+    private final FlexibleStringExpander paginatePreviousLabel;
+    private final FlexibleStringExpander paginateSizeField;
+    private final String paginateStyle;
+    private final FlexibleStringExpander paginateTarget;
+    private final String paginateTargetAnchor;
+    private final FlexibleStringExpander paginateViewSizeLabel;
+    private final ModelForm parentModelForm;
+    private final List<ModelAction> rowActions;
+    private final FlexibleStringExpander rowCountExdr;
+    private final boolean separateColumns;
+    private final boolean skipEnd;
+    private final boolean skipStart;
+    private final String sortFieldParameterName;
+    private final List<SortField> sortOrderFields;
+    private final FlexibleStringExpander target;
+    private final String targetType;
+    private final FlexibleStringExpander targetWindowExdr;
+    private final String title;
+    private final String tooltip;
+    private final String type;
+    private final boolean useRowSubmit;
+    /** Keeps track of conditional fields to help ensure that only one is rendered
+     */
+    private final Set<String> useWhenFields;
+
+    /** XML Constructor */
+    public ModelForm(Element formElement, String formLocation, ModelReader entityModelReader, DispatchContext dispatchContext) {
+        super(formElement);
+        this.formLocation = formLocation;
+        parentModelForm = getParentForm(formElement, entityModelReader, dispatchContext);
+        int defaultViewSizeInt = DEFAULT_PAGE_SIZE;
+        String viewSize = formElement.getAttribute("view-size");
+        if (viewSize.isEmpty()) {
+            if (parentModelForm != null) {
+                defaultViewSizeInt = parentModelForm.defaultViewSize;
+            } else {
+                defaultViewSizeInt = UtilProperties.getPropertyAsInteger("widget.properties", "widget.form.defaultViewSize",
+                        defaultViewSizeInt);
+            }
+        } else {
+            try {
+                defaultViewSizeInt = Integer.valueOf(viewSize);
+            } catch (NumberFormatException e) {
+            }
+        }
+        this.defaultViewSize = defaultViewSizeInt;
+        String type = formElement.getAttribute("type");
+        if (type.isEmpty() && parentModelForm != null) {
+            type = parentModelForm.type;
+        }
+        this.type = type;
+        FlexibleStringExpander target = FlexibleStringExpander.getInstance(formElement.getAttribute("target"));
+        if (target.isEmpty() && parentModelForm != null) {
+            target = parentModelForm.target;
+        }
+        this.target = target;
+        String containerId = formElement.getAttribute("id");
+        if (containerId.isEmpty() && parentModelForm != null) {
+            containerId = parentModelForm.containerId;
+        }
+        this.containerId = containerId;
+        String containerStyle = formElement.getAttribute("style");
+        if (containerStyle.isEmpty() && parentModelForm != null) {
+            containerStyle = parentModelForm.containerStyle;
+        }
+        this.containerStyle = containerStyle;
+        String title = formElement.getAttribute("title");
+        if (title.isEmpty() && parentModelForm != null) {
+            title = parentModelForm.title;
+        }
+        this.title = title;
+        String tooltip = formElement.getAttribute("tooltip");
+        if (tooltip.isEmpty() && parentModelForm != null) {
+            tooltip = parentModelForm.tooltip;
+        }
+        this.tooltip = tooltip;
+        String listName = formElement.getAttribute("list-name");
+        if (listName.isEmpty()) {
+            if (parentModelForm != null) {
+                listName = parentModelForm.listName;
+            } else {
+                listName = DEFAULT_FORM_RESULT_LIST_NAME;
+            }
+        }
+        this.listName = listName;
+        String listEntryName = formElement.getAttribute("list-entry-name");
+        if (listEntryName.isEmpty() && parentModelForm != null) {
+            listEntryName = parentModelForm.listEntryName;
+        }
+        this.listEntryName = listEntryName;
+        String defaultEntityName = formElement.getAttribute("default-entity-name");
+        if (defaultEntityName.isEmpty() && parentModelForm != null) {
+            defaultEntityName = parentModelForm.defaultEntityName;
+        }
+        this.defaultEntityName = defaultEntityName;
+        String defaultServiceName = formElement.getAttribute("default-service-name");
+        if (defaultServiceName.isEmpty() && parentModelForm != null) {
+            defaultServiceName = parentModelForm.defaultServiceName;
+        }
+        this.defaultServiceName = defaultServiceName;
+        String formTitleAreaStyle = formElement.getAttribute("form-title-area-style");
+        if (formTitleAreaStyle.isEmpty() && parentModelForm != null) {
+            formTitleAreaStyle = parentModelForm.formTitleAreaStyle;
+        }
+        this.formTitleAreaStyle = formTitleAreaStyle;
+        String formWidgetAreaStyle = formElement.getAttribute("form-widget-area-style");
+        if (formWidgetAreaStyle.isEmpty() && parentModelForm != null) {
+            formWidgetAreaStyle = parentModelForm.formWidgetAreaStyle;
+        }
+        this.formWidgetAreaStyle = formWidgetAreaStyle;
+        String defaultTitleAreaStyle = formElement.getAttribute("default-title-area-style");
+        if (defaultTitleAreaStyle.isEmpty() && parentModelForm != null) {
+            defaultTitleAreaStyle = parentModelForm.defaultTitleAreaStyle;
+        }
+        this.defaultTitleAreaStyle = defaultTitleAreaStyle;
+        String defaultWidgetAreaStyle = formElement.getAttribute("default-widget-area-style");
+        if (defaultWidgetAreaStyle.isEmpty() && parentModelForm != null) {
+            defaultWidgetAreaStyle = parentModelForm.defaultWidgetAreaStyle;
+        }
+        this.defaultWidgetAreaStyle = defaultWidgetAreaStyle;
+        String oddRowStyle = formElement.getAttribute("odd-row-style");
+        if (oddRowStyle.isEmpty() && parentModelForm != null) {
+            oddRowStyle = parentModelForm.oddRowStyle;
+        }
+        this.oddRowStyle = oddRowStyle;
+        String evenRowStyle = formElement.getAttribute("even-row-style");
+        if (evenRowStyle.isEmpty() && parentModelForm != null) {
+            evenRowStyle = parentModelForm.evenRowStyle;
+        }
+        this.evenRowStyle = evenRowStyle;
+        String defaultTableStyle = formElement.getAttribute("default-table-style");
+        if (defaultTableStyle.isEmpty() && parentModelForm != null) {
+            defaultTableStyle = parentModelForm.defaultTableStyle;
+        }
+        this.defaultTableStyle = defaultTableStyle;
+        String headerRowStyle = formElement.getAttribute("header-row-style");
+        if (headerRowStyle.isEmpty() && parentModelForm != null) {
+            headerRowStyle = parentModelForm.headerRowStyle;
+        }
+        this.headerRowStyle = headerRowStyle;
+        String defaultTitleStyle = formElement.getAttribute("default-title-style");
+        if (defaultTitleStyle.isEmpty() && parentModelForm != null) {
+            defaultTitleStyle = parentModelForm.defaultTitleStyle;
+        }
+        this.defaultTitleStyle = defaultTitleStyle;
+        String defaultWidgetStyle = formElement.getAttribute("default-widget-style");
+        if (defaultWidgetStyle.isEmpty() && parentModelForm != null) {
+            defaultWidgetStyle = parentModelForm.defaultWidgetStyle;
+        }
+        this.defaultWidgetStyle = defaultWidgetStyle;
+        String defaultTooltipStyle = formElement.getAttribute("default-tooltip-style");
+        if (defaultTooltipStyle.isEmpty() && parentModelForm != null) {
+            defaultTooltipStyle = parentModelForm.defaultTooltipStyle;
+        }
+        this.defaultTooltipStyle = defaultTooltipStyle;
+        String itemIndexSeparator = formElement.getAttribute("item-index-separator");
+        if (itemIndexSeparator.isEmpty() && parentModelForm != null) {
+            itemIndexSeparator = parentModelForm.itemIndexSeparator;
+        }
+        this.itemIndexSeparator = itemIndexSeparator;
+        String separateColumns = formElement.getAttribute("separate-columns");
+        if (separateColumns.isEmpty() && parentModelForm != null) {
+            this.separateColumns = parentModelForm.separateColumns;
+        } else {
+            this.separateColumns = "true".equals(separateColumns);
+        }
+        String groupColumns = formElement.getAttribute("group-columns");
+        if (groupColumns.isEmpty() && parentModelForm != null) {
+            this.groupColumns = parentModelForm.groupColumns;
+        } else {
+            this.groupColumns = !"false".equals(groupColumns);
+        }
+        String targetType = formElement.getAttribute("target-type");
+        if (targetType.isEmpty() && parentModelForm != null) {
+            targetType = parentModelForm.targetType;
+        }
+        this.targetType = targetType;
+        FlexibleMapAccessor<Map<String, ? extends Object>> defaultMapName = FlexibleMapAccessor.getInstance(formElement
+                .getAttribute("default-map-name"));
+        if (defaultMapName.isEmpty() && parentModelForm != null) {
+            defaultMapName = parentModelForm.defaultMapName;
+        }
+        this.defaultMapName = defaultMapName;
+        FlexibleStringExpander targetWindowExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("target-window"));
+        if (targetWindowExdr.isEmpty() && parentModelForm != null) {
+            targetWindowExdr = parentModelForm.targetWindowExdr;
+        }
+        this.targetWindowExdr = targetWindowExdr;
+        String hideHeader = formElement.getAttribute("hide-header");
+        if (hideHeader.isEmpty() && parentModelForm != null) {
+            this.hideHeader = parentModelForm.hideHeader;
+        } else {
+            this.hideHeader = "true".equals(hideHeader);
+        }
+        String clientAutocompleteFields = formElement.getAttribute("client-autocomplete-fields");
+        if (clientAutocompleteFields.isEmpty() && parentModelForm != null) {
+            this.clientAutocompleteFields = parentModelForm.clientAutocompleteFields;
+        } else {
+            this.clientAutocompleteFields = !"false".equals(formElement.getAttribute("client-autocomplete-fields"));
+        }
+        FlexibleStringExpander paginateTarget = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate-target"));
+        if (paginateTarget.isEmpty() && parentModelForm != null) {
+            paginateTarget = parentModelForm.paginateTarget;
+        }
+        this.paginateTarget = paginateTarget;
+        ArrayList<AltTarget> altTargets = new ArrayList<AltTarget>();
+        if (parentModelForm != null) {
+            altTargets.addAll(parentModelForm.altTargets);
+        }
+        for (Element altTargetElement : UtilXml.childElementList(formElement, "alt-target")) {
+            altTargets.add(new AltTarget(altTargetElement));
+        }
+        altTargets.trimToSize();
+        this.altTargets = Collections.unmodifiableList(altTargets);
+        ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
+        if (parentModelForm != null) {
+            actions.addAll(parentModelForm.actions);
+        }
+        Element actionsElement = UtilXml.firstChildElement(formElement, "actions");
+        if (actionsElement != null) {
+            actions.addAll(ModelFormAction.readSubActions(this, actionsElement));
+        }
+        actions.trimToSize();
+        this.actions = Collections.unmodifiableList(actions);
+        ArrayList<ModelAction> rowActions = new ArrayList<ModelAction>();
+        if (parentModelForm != null) {
+            rowActions.addAll(parentModelForm.rowActions);
+        }
+        Element rowActionsElement = UtilXml.firstChildElement(formElement, "row-actions");
+        if (rowActionsElement != null) {
+            rowActions.addAll(ModelFormAction.readSubActions(this, rowActionsElement));
+        }
+        rowActions.trimToSize();
+        this.rowActions = Collections.unmodifiableList(rowActions);
+        ArrayList<UpdateArea> onPaginateUpdateAreas = new ArrayList<UpdateArea>();
+        ArrayList<UpdateArea> onSubmitUpdateAreas = new ArrayList<UpdateArea>();
+        ArrayList<UpdateArea> onSortColumnUpdateAreas = new ArrayList<UpdateArea>();
+        if (parentModelForm != null) {
+            onPaginateUpdateAreas.addAll(parentModelForm.onPaginateUpdateAreas);
+            onSubmitUpdateAreas.addAll(parentModelForm.onSubmitUpdateAreas);
+            onSortColumnUpdateAreas.addAll(parentModelForm.onSortColumnUpdateAreas);
+        }
+        for (Element updateAreaElement : UtilXml.childElementList(formElement, "on-event-update-area")) {
+            UpdateArea updateArea = new UpdateArea(updateAreaElement, defaultServiceName, defaultEntityName);
+            if ("paginate".equals(updateArea.getEventType())) {
+                int index = onPaginateUpdateAreas.indexOf(updateArea);
+                if (index != -1) {
+                    if (!updateArea.areaTarget.isEmpty()) {
+                        onPaginateUpdateAreas.set(index, updateArea);
+                    } else {
+                        // blank target indicates a removing override
+                        onPaginateUpdateAreas.remove(index);
+                    }
+                } else {
+                    onPaginateUpdateAreas.add(updateArea);
+                }
+            } else if ("submit".equals(updateArea.getEventType())) {
+                int index = onSubmitUpdateAreas.indexOf(updateArea);
+                if (index != -1) {
+                    onSubmitUpdateAreas.set(index, updateArea);
+                } else {
+                    onSubmitUpdateAreas.add(updateArea);
+                }
+            } else if ("sort-column".equals(updateArea.getEventType())) {
+                int index = onSortColumnUpdateAreas.indexOf(updateArea);
+                if (index != -1) {
+                    if (!updateArea.areaTarget.isEmpty()) {
+                        onSortColumnUpdateAreas.set(index, updateArea);
+                    } else {
+                        // blank target indicates a removing override
+                        onSortColumnUpdateAreas.remove(index);
+                    }
+                } else {
+                    onSortColumnUpdateAreas.add(updateArea);
+                }
+            }
+        }
+        onPaginateUpdateAreas.trimToSize();
+        this.onPaginateUpdateAreas = Collections.unmodifiableList(onPaginateUpdateAreas);
+        onSubmitUpdateAreas.trimToSize();
+        this.onSubmitUpdateAreas = Collections.unmodifiableList(onSubmitUpdateAreas);
+        onSortColumnUpdateAreas.trimToSize();
+        this.onSortColumnUpdateAreas = Collections.unmodifiableList(onSortColumnUpdateAreas);
+        ArrayList<AltRowStyle> altRowStyles = new ArrayList<AltRowStyle>();
+        if (parentModelForm != null) {
+            altRowStyles.addAll(parentModelForm.altRowStyles);
+        }
+        for (Element altRowStyleElement : UtilXml.childElementList(formElement, "alt-row-style")) {
+            AltRowStyle altRowStyle = new AltRowStyle(altRowStyleElement);
+            altRowStyles.add(altRowStyle);
+        }
+        altRowStyles.trimToSize();
+        this.altRowStyles = Collections.unmodifiableList(altRowStyles);
+        Set<String> useWhenFields = new HashSet<String>();
+        if (parentModelForm != null) {
+            useWhenFields.addAll(parentModelForm.useWhenFields);
+        }
+        ArrayList<ModelFormFieldBuilder> fieldBuilderList = new ArrayList<ModelFormFieldBuilder>();
+        Map<String, ModelFormFieldBuilder> fieldBuilderMap = new HashMap<String, ModelFormFieldBuilder>();
+        if (parentModelForm != null) {
+            // Create this fieldList/Map from clones of parentModelForm's
+            for (ModelFormField parentChildField : parentModelForm.fieldList) {
+                ModelFormFieldBuilder builder = new ModelFormFieldBuilder(parentChildField);
+                builder.setModelForm(this);
+                fieldBuilderList.add(builder);
+                fieldBuilderMap.put(builder.getName(), builder);
+            }
+        }
+        Map<String, FieldGroupBase> fieldGroupMap = new HashMap<String, FieldGroupBase>();
+        if (parentModelForm != null) {
+            fieldGroupMap.putAll(parentModelForm.fieldGroupMap);
+        }
+        ArrayList<FieldGroupBase> fieldGroupList = new ArrayList<FieldGroupBase>();
+        if (parentModelForm != null) {
+            fieldGroupList.addAll(parentModelForm.fieldGroupList);
+        }
+        ArrayList<String> lastOrderFields = new ArrayList<String>();
+        if (parentModelForm != null) {
+            lastOrderFields.addAll(parentModelForm.lastOrderFields);
+        }
+        String sortFieldParameterName = formElement.getAttribute("sort-field-parameter-name");
+        if (sortFieldParameterName.isEmpty() && parentModelForm != null) {
+            this.sortFieldParameterName = parentModelForm.targetType;
+        } else {
+            this.sortFieldParameterName = "sortField";
+        }
+        String defaultRequiredFieldStyle = formElement.getAttribute("default-required-field-style");
+        if (defaultRequiredFieldStyle.isEmpty() && parentModelForm != null) {
+            defaultRequiredFieldStyle = parentModelForm.defaultRequiredFieldStyle;
+        }
+        this.defaultRequiredFieldStyle = defaultRequiredFieldStyle;
+        String defaultSortFieldStyle = formElement.getAttribute("default-sort-field-style");
+        if (defaultSortFieldStyle.isEmpty() && parentModelForm != null) {
+            this.defaultSortFieldStyle = parentModelForm.defaultSortFieldStyle;
+        } else {
+            this.defaultSortFieldStyle = DEFAULT_SORT_FIELD_STYLE;
+        }
+        String defaultSortFieldAscStyle = formElement.getAttribute("default-sort-field-asc-style");
+        if (defaultSortFieldAscStyle.isEmpty() && parentModelForm != null) {
+            this.defaultSortFieldAscStyle = parentModelForm.defaultSortFieldAscStyle;
+        } else {
+            this.defaultSortFieldAscStyle = DEFAULT_SORT_FIELD_ASC_STYLE;
+        }
+        String defaultSortFieldDescStyle = formElement.getAttribute("default-sort-field-desc-style");
+        if (defaultSortFieldDescStyle.isEmpty() && parentModelForm != null) {
+            this.defaultSortFieldDescStyle = parentModelForm.defaultSortFieldDescStyle;
+        } else {
+            this.defaultSortFieldDescStyle = DEFAULT_SORT_FIELD_DESC_STYLE;
+        }
+        String paginateTargetAnchor = formElement.getAttribute("paginate-target-anchor");
+        if (paginateTargetAnchor.isEmpty() && parentModelForm != null) {
+            paginateTargetAnchor = parentModelForm.paginateTargetAnchor;
+        }
+        this.paginateTargetAnchor = paginateTargetAnchor;
+        FlexibleStringExpander paginateIndexField = FlexibleStringExpander.getInstance(formElement
+                .getAttribute("paginate-index-field"));
+        if (paginateIndexField.isEmpty() && parentModelForm != null) {
+            paginateIndexField = parentModelForm.paginateIndexField;
+        }
+        this.paginateIndexField = paginateIndexField;
+        FlexibleStringExpander paginateSizeField = FlexibleStringExpander.getInstance(formElement
+                .getAttribute("paginate-size-field"));
+        if (paginateSizeField.isEmpty() && parentModelForm != null) {
+            paginateSizeField = parentModelForm.paginateSizeField;
+        }
+        this.paginateSizeField = paginateSizeField;
+        FlexibleStringExpander overrideListSize = FlexibleStringExpander.getInstance(formElement
+                .getAttribute("override-list-size"));
+        if (overrideListSize.isEmpty() && parentModelForm != null) {
+            overrideListSize = parentModelForm.overrideListSize;
+        }
+        this.overrideListSize = overrideListSize;
+        FlexibleStringExpander paginateFirstLabel = FlexibleStringExpander.getInstance(formElement
+                .getAttribute("paginate-first-label"));
+        if (paginateFirstLabel.isEmpty() && parentModelForm != null) {
+            paginateFirstLabel = parentModelForm.paginateFirstLabel;
+        }
+        this.paginateFirstLabel = paginateFirstLabel;
+        FlexibleStringExpander paginatePreviousLabel = FlexibleStringExpander.getInstance(formElement
+                .getAttribute("paginate-previous-label"));
+        if (paginatePreviousLabel.isEmpty() && parentModelForm != null) {
+            paginatePreviousLabel = parentModelForm.paginatePreviousLabel;
+        }
+        this.paginatePreviousLabel = paginatePreviousLabel;
+        FlexibleStringExpander paginateNextLabel = FlexibleStringExpander.getInstance(formElement
+                .getAttribute("paginate-next-label"));
+        if (paginateNextLabel.isEmpty() && parentModelForm != null) {
+            paginateNextLabel = parentModelForm.paginateNextLabel;
+        }
+        this.paginateNextLabel = paginateNextLabel;
+        FlexibleStringExpander paginateLastLabel = FlexibleStringExpander.getInstance(formElement
+                .getAttribute("paginate-last-label"));
+        if (paginateLastLabel.isEmpty() && parentModelForm != null) {
+            paginateLastLabel = parentModelForm.paginateLastLabel;
+        }
+        this.paginateLastLabel = paginateLastLabel;
+        FlexibleStringExpander paginateViewSizeLabel = FlexibleStringExpander.getInstance(formElement
+                .getAttribute("paginate-viewsize-label"));
+        if (paginateViewSizeLabel.isEmpty() && parentModelForm != null) {
+            paginateViewSizeLabel = parentModelForm.paginateViewSizeLabel;
+        }
+        this.paginateViewSizeLabel = paginateViewSizeLabel;
+        String paginateStyle = formElement.getAttribute("paginate-style");
+        if (paginateStyle.isEmpty() && parentModelForm != null) {
+            this.paginateStyle = parentModelForm.paginateStyle;
+        } else {
+            this.paginateStyle = DEFAULT_PAG_STYLE;
+        }
+        FlexibleStringExpander paginate = FlexibleStringExpander.getInstance(formElement.getAttribute("paginate"));
+        if (paginate.isEmpty() && parentModelForm != null) {
+            paginate = parentModelForm.paginate;
+        }
+        this.paginate = paginate;
+        String skipStart = formElement.getAttribute("skip-start");
+        if (skipStart.isEmpty() && parentModelForm != null) {
+            this.skipStart = parentModelForm.skipStart;
+        } else {
+            this.skipStart = "true".equals(skipStart);
+        }
+        String skipEnd = formElement.getAttribute("skip-end");
+        if (skipEnd.isEmpty() && parentModelForm != null) {
+            this.skipEnd = parentModelForm.skipEnd;
+        } else {
+            this.skipEnd = "true".equals(skipEnd);
+        }
+        String useRowSubmit = formElement.getAttribute("use-row-submit");
+        if (useRowSubmit.isEmpty() && parentModelForm != null) {
+            this.useRowSubmit = parentModelForm.useRowSubmit;
+        } else {
+            this.useRowSubmit = "true".equals(useRowSubmit);
+        }
+        FlexibleStringExpander rowCountExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("row-count"));
+        if (rowCountExdr.isEmpty() && parentModelForm != null) {
+            rowCountExdr = parentModelForm.rowCountExdr;
+        }
+        this.rowCountExdr = paginate;
+        ArrayList<ModelFormFieldBuilder> multiSubmitBuilders = new ArrayList<ModelFormFieldBuilder>();
+        ArrayList<AutoFieldsService> autoFieldsServices = new ArrayList<AutoFieldsService>();
+        ArrayList<AutoFieldsEntity> autoFieldsEntities = new ArrayList<AutoFieldsEntity>();
+        ArrayList<SortField> sortOrderFields = new ArrayList<SortField>();
+        this.defaultFieldGroup = new FieldGroup(null, this, sortOrderFields, fieldGroupMap);
+        for (Element autoFieldsServiceElement : UtilXml.childElementList(formElement, "auto-fields-service")) {
+            AutoFieldsService autoFieldsService = new AutoFieldsService(autoFieldsServiceElement);
+            autoFieldsServices.add(autoFieldsService);
+            addAutoFieldsFromService(autoFieldsService, entityModelReader, dispatchContext, useWhenFields, fieldBuilderList, fieldBuilderMap);
+        }
+        for (Element autoFieldsEntityElement : UtilXml.childElementList(formElement, "auto-fields-entity")) {
+            AutoFieldsEntity autoFieldsEntity = new AutoFieldsEntity(autoFieldsEntityElement);
+            autoFieldsEntities.add(autoFieldsEntity);
+            addAutoFieldsFromEntity(autoFieldsEntity, entityModelReader, useWhenFields, fieldBuilderList, fieldBuilderMap);
+        }
+        String thisType = this.getType();
+        for (Element fieldElement : UtilXml.childElementList(formElement, "field")) {
+            ModelFormFieldBuilder builder = new ModelFormFieldBuilder(fieldElement, this, entityModelReader, dispatchContext);
+            FieldInfo fieldInfo = builder.getFieldInfo();
+            if (thisType.equals("multi") && fieldInfo instanceof ModelFormField.SubmitField) {
+                multiSubmitBuilders.add(builder);
+            } else {
+                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
+            }
+        }
+        // get the sort-order
+        Element sortOrderElement = UtilXml.firstChildElement(formElement, "sort-order");
+        if (sortOrderElement != null) {
+            FieldGroup lastFieldGroup = new FieldGroup(null, this, sortOrderFields, fieldGroupMap);
+            fieldGroupList.add(lastFieldGroup);
+            // read in sort-field
+            for (Element sortFieldElement : UtilXml.childElementList(sortOrderElement)) {
+                String tagName = sortFieldElement.getTagName();
+                if (tagName.equals("sort-field")) {
+                    String fieldName = sortFieldElement.getAttribute("name");
+                    String position = sortFieldElement.getAttribute("position");
+                    sortOrderFields.add(new SortField(fieldName, position));
+                    fieldGroupMap.put(fieldName, lastFieldGroup);
+                } else if (tagName.equals("last-field")) {
+                    String fieldName = sortFieldElement.getAttribute("name");
+                    fieldGroupMap.put(fieldName, lastFieldGroup);
+                    lastOrderFields.add(fieldName);
+                } else if (tagName.equals("banner")) {
+                    Banner thisBanner = new Banner(sortFieldElement);
+                    fieldGroupList.add(thisBanner);
+                    lastFieldGroup = new FieldGroup(null, this, sortOrderFields, fieldGroupMap);
+                    fieldGroupList.add(lastFieldGroup);
+                } else if (tagName.equals("field-group")) {
+                    FieldGroup thisFieldGroup = new FieldGroup(sortFieldElement, this, sortOrderFields, fieldGroupMap);
+                    fieldGroupList.add(thisFieldGroup);
+                    lastFieldGroup = new FieldGroup(null, this, sortOrderFields, fieldGroupMap);
+                    fieldGroupList.add(lastFieldGroup);
+                }
+            }
+        }
+        if (sortOrderFields.size() > 0) {
+            ArrayList<ModelFormFieldBuilder> sortedFields = new ArrayList<ModelFormFieldBuilder>();
+            for (SortField sortField : sortOrderFields) {
+                String fieldName = sortField.getFieldName();
+                if (UtilValidate.isEmpty(fieldName)) {
+                    continue;
+                }
+                // get all fields with the given name from the existing list and put them in the sorted list
+                Iterator<ModelFormFieldBuilder> fieldIter = fieldBuilderList.iterator();
+                while (fieldIter.hasNext()) {
+                    ModelFormFieldBuilder builder = fieldIter.next();
+                    if (fieldName.equals(builder.getName())) {
+                        // matched the name; remove from the original last and add to the sorted list
+                        if (UtilValidate.isNotEmpty(sortField.getPosition())) {
+                            builder.setPosition(sortField.getPosition());
+                        }
+                        fieldIter.remove();
+                        sortedFields.add(builder);
+                    }
+                }
+            }
+            // now add all of the rest of the fields from fieldList, ie those that were not explicitly listed in the sort order
+            sortedFields.addAll(fieldBuilderList);
+            // sortedFields all done, set fieldList
+            fieldBuilderList = sortedFields;
+        }
+        if (UtilValidate.isNotEmpty(lastOrderFields)) {
+            List<ModelFormFieldBuilder> lastedFields = new LinkedList<ModelFormFieldBuilder>();
+            for (String fieldName : lastOrderFields) {
+                if (UtilValidate.isEmpty(fieldName)) {
+                    continue;
+                }
+                // get all fields with the given name from the existing list and put them in the lasted list
+                Iterator<ModelFormFieldBuilder> fieldIter = fieldBuilderList.iterator();
+                while (fieldIter.hasNext()) {
+                    ModelFormFieldBuilder builder = fieldIter.next();
+                    if (fieldName.equals(builder.getName())) {
+                        // matched the name; remove from the original last and add to the lasted list
+                        fieldIter.remove();
+                        lastedFields.add(builder);
+                    }
+                }
+            }
+            //now put all lastedFields at the field list end
+            fieldBuilderList.addAll(lastedFields);
+        }
+        List<ModelFormField> fieldList = new ArrayList<ModelFormField>(fieldBuilderList.size());
+        for (ModelFormFieldBuilder builder : fieldBuilderList) {
+            fieldList.add(builder.build());
+        }
+        this.fieldList = Collections.unmodifiableList(fieldList);
+        List<ModelFormField> multiSubmitFields = new ArrayList<ModelFormField>(multiSubmitBuilders.size());
+        for (ModelFormFieldBuilder builder : multiSubmitBuilders) {
+            multiSubmitFields.add(builder.build());
+        }
+        this.multiSubmitFields = Collections.unmodifiableList(multiSubmitFields);
+        this.useWhenFields = Collections.unmodifiableSet(useWhenFields);
+        this.fieldGroupMap = Collections.unmodifiableMap(fieldGroupMap);
+        fieldGroupList.trimToSize();
+        this.fieldGroupList = Collections.unmodifiableList(fieldGroupList);
+        lastOrderFields.trimToSize();
+        this.lastOrderFields = Collections.unmodifiableList(lastOrderFields);
+        autoFieldsServices.trimToSize();
+        this.autoFieldsServices = Collections.unmodifiableList(autoFieldsServices);
+        autoFieldsEntities.trimToSize();
+        this.autoFieldsEntities = Collections.unmodifiableList(autoFieldsEntities);
+        sortOrderFields.trimToSize();
+        this.sortOrderFields = Collections.unmodifiableList(sortOrderFields);
+        String focusFieldName = formElement.getAttribute("focus-field-name");
+        if (focusFieldName.isEmpty() && parentModelForm != null) {
+            focusFieldName = parentModelForm.focusFieldName;
+        }
+        this.focusFieldName = focusFieldName;
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+
+    private void addAutoFieldsFromEntity(AutoFieldsEntity autoFieldsEntity, ModelReader entityModelReader,
+            Set<String> useWhenFields, List<ModelFormFieldBuilder> fieldBuilderList, Map<String, ModelFormFieldBuilder> fieldBuilderMap) {
+        // read entity def and auto-create fields
+        ModelEntity modelEntity = null;
+        try {
+            modelEntity = entityModelReader.getModelEntity(autoFieldsEntity.entityName);
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+        }
+        if (modelEntity == null) {
+            throw new IllegalArgumentException("Error finding Entity with name " + autoFieldsEntity.entityName
+                    + " for auto-fields-entity in a form widget");
+        }
+        Iterator<ModelField> modelFieldIter = modelEntity.getFieldsIterator();
+        while (modelFieldIter.hasNext()) {
+            ModelField modelField = modelFieldIter.next();
+            if (modelField.getIsAutoCreatedInternal()) {
+                // don't ever auto-add these, should only be added if explicitly referenced
+                continue;
+            }
+            ModelFormFieldBuilder builder = new ModelFormFieldBuilder();
+            builder.setModelForm(this);
+            builder.setName(modelField.getName());
+            builder.setEntityName(modelEntity.getEntityName());
+            builder.setFieldName(modelField.getName());
+            builder.induceFieldInfoFromEntityField(modelEntity, modelField, autoFieldsEntity.defaultFieldType);
+            builder.setPosition(autoFieldsEntity.defaultPosition);
+            if (UtilValidate.isNotEmpty(autoFieldsEntity.mapName)) {
+                builder.setMapName(autoFieldsEntity.mapName);
+            }
+            addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
+        }
+    }
+
+    private void addAutoFieldsFromService(AutoFieldsService autoFieldsService, ModelReader entityModelReader,
+            DispatchContext dispatchContext, Set<String> useWhenFields, List<ModelFormFieldBuilder> fieldBuilderList,
+            Map<String, ModelFormFieldBuilder> fieldBuilderMap) {
+        // read service def and auto-create fields
+        ModelService modelService = null;
+        try {
+            modelService = dispatchContext.getModelService(autoFieldsService.serviceName);
+        } catch (GenericServiceException e) {
+            String errmsg = "Error finding Service with name " + autoFieldsService.serviceName
+                    + " for auto-fields-service in a form widget";
+            Debug.logError(e, errmsg, module);
+            throw new IllegalArgumentException(errmsg);
+        }
+        for (ModelParam modelParam : modelService.getInModelParamList()) {
+            if (modelParam.internal) {
+                // skip auto params that the service engine populates...
+                continue;
+            }
+            if (modelParam.formDisplay) {
+                if (UtilValidate.isNotEmpty(modelParam.entityName) && UtilValidate.isNotEmpty(modelParam.fieldName)) {
+                    ModelEntity modelEntity;
+                    try {
+                        modelEntity = entityModelReader.getModelEntity(modelParam.entityName);
+                        if (modelEntity != null) {
+                            ModelField modelField = modelEntity.getField(modelParam.fieldName);
+                            if (modelField != null) {
+                                // okay, populate using the entity field info...
+                                ModelFormFieldBuilder builder = new ModelFormFieldBuilder();
+                                builder.setModelForm(this);
+                                builder.setName(modelField.getName());
+                                builder.setEntityName(modelEntity.getEntityName());
+                                builder.setFieldName(modelField.getName());
+                                builder.induceFieldInfoFromEntityField(modelEntity, modelField, autoFieldsService.defaultFieldType);
+                                if (UtilValidate.isNotEmpty(autoFieldsService.mapName)) {
+                                    builder.setMapName(autoFieldsService.mapName);
+                                }
+                                builder.setRequiredField(!modelParam.optional);
+                                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
+                                // continue to skip creating based on service param
+                                continue;
+                            }
+                        }
+                    } catch (GenericEntityException e) {
+                        Debug.logError(e, module);
+                    }
+                }
+                ModelFormFieldBuilder builder = new ModelFormFieldBuilder();
+                builder.setModelForm(this);
+                builder.setName(modelParam.name);
+                builder.setServiceName(modelService.name);
+                builder.setAttributeName(modelParam.name);
+                builder.setTitle(modelParam.formLabel);
+                builder.setRequiredField(!modelParam.optional);
+                builder.induceFieldInfoFromServiceParam(modelService, modelParam, autoFieldsService.defaultFieldType);
+                builder.setPosition(autoFieldsService.defaultPosition);
+                if (UtilValidate.isNotEmpty(autoFieldsService.mapName)) {
+                    builder.setMapName(autoFieldsService.mapName);
+                }
+                addUpdateField(builder, useWhenFields, fieldBuilderList, fieldBuilderMap);
+            }
+        }
+    }
+
+    private void addUpdateField(ModelFormFieldBuilder builder, Set<String> useWhenFields,
+            List<ModelFormFieldBuilder> fieldBuilderList, Map<String, ModelFormFieldBuilder> fieldBuilderMap) {
+        if (!builder.getUseWhen().isEmpty() || useWhenFields.contains(builder.getName())) {
+            useWhenFields.add(builder.getName());
+            // is a conditional field, add to the List but don't worry about the Map
+            //for adding to list, see if there is another field with that name in the list and if so, put it before that one
+            boolean inserted = false;
+            for (int i = 0; i < fieldBuilderList.size(); i++) {
+                ModelFormFieldBuilder curField = fieldBuilderList.get(i);
+                if (curField.getName() != null && curField.getName().equals(builder.getName())) {
+                    fieldBuilderList.add(i, builder);
+                    inserted = true;
+                    break;
+                }
+            }
+            if (!inserted) {
+                fieldBuilderList.add(builder);
+            }
+            return;
+        } else {
+            // not a conditional field, see if a named field exists in Map
+            ModelFormFieldBuilder existingField = fieldBuilderMap.get(builder.getName());
+            if (existingField != null) {
+                // does exist, update the field by doing a merge/override
+                existingField.mergeOverrideModelFormField(builder);
+            } else {
+                // does not exist, add to List and Map
+                fieldBuilderList.add(builder);
+                fieldBuilderMap.put(builder.getName(), builder);
+            }
+        }
+    }
+
+    public List<ModelAction> getActions() {
+        return actions;
+    }
+
+    public List<AltRowStyle> getAltRowStyles() {
+        return altRowStyles;
+    }
+
+    public List<AltTarget> getAltTargets() {
+        return altTargets;
+    }
+
+    public List<AutoFieldsEntity> getAutoFieldsEntities() {
+        return autoFieldsEntities;
+    }
+
+    public List<AutoFieldsService> getAutoFieldsServices() {
+        return autoFieldsServices;
+    }
+
+    public Interpreter getBshInterpreter(Map<String, Object> context) throws EvalError {
+        Interpreter bsh = (Interpreter) context.get("bshInterpreter");
+        if (bsh == null) {
+            bsh = BshUtil.makeInterpreter(context);
+            context.put("bshInterpreter", bsh);
+        }
+        return bsh;
+    }
+
+    @Override
+    public String getBoundaryCommentName() {
+        return formLocation + "#" + getName();
+    }
+
+    public boolean getClientAutocompleteFields() {
+        return this.clientAutocompleteFields;
+    }
+
+    public String getContainerId() {
+        // use the name if there is no id
+        if (UtilValidate.isNotEmpty(this.containerId)) {
+            return this.containerId;
+        } else {
+            return this.getName();
+        }
+    }
+
+    public String getContainerStyle() {
+        return this.containerStyle;
+    }
+
+    public String getDefaultEntityName() {
+        return this.defaultEntityName;
+    }
+
+    public FieldGroup getDefaultFieldGroup() {
+        return defaultFieldGroup;
+    }
+
+    public Map<String, ? extends Object> getDefaultMap(Map<String, ? extends Object> context) {
+        return this.defaultMapName.get(context);
+    }
+
+    public String getDefaultMapName() {
+        return this.defaultMapName.getOriginalName();
+    }
+
+    public String getDefaultRequiredFieldStyle() {
+        return this.defaultRequiredFieldStyle;
+    }
+
+    public String getDefaultServiceName() {
+        return this.defaultServiceName;
+    }
+
+    public String getDefaultSortFieldAscStyle() {
+        return this.defaultSortFieldAscStyle;
+    }
+
+    public String getDefaultSortFieldDescStyle() {
+        return this.defaultSortFieldDescStyle;
+    }
+
+    public String getDefaultSortFieldStyle() {
+        return this.defaultSortFieldStyle;
+    }
+
+    public String getDefaultTableStyle() {
+        return this.defaultTableStyle;
+    }
+
+    public String getDefaultTitleAreaStyle() {
+        return this.defaultTitleAreaStyle;
+    }
+
+    public String getDefaultTitleStyle() {
+        return this.defaultTitleStyle;
+    }
+
+    public String getDefaultTooltipStyle() {
+        return this.defaultTooltipStyle;
+    }
+
+    public int getDefaultViewSize() {
+        return defaultViewSize;
+    }
+
+    public String getDefaultWidgetAreaStyle() {
+        return this.defaultWidgetAreaStyle;
+    }
+
+    public String getDefaultWidgetStyle() {
+        return this.defaultWidgetStyle;
+    }
+
+    public String getEvenRowStyle() {
+        return this.evenRowStyle;
+    }
+
+    public List<FieldGroupBase> getFieldGroupList() {
+        return fieldGroupList;
+    }
+
+    public Map<String, FieldGroupBase> getFieldGroupMap() {
+        return fieldGroupMap;
+    }
+
+    public List<ModelFormField> getFieldList() {
+        return fieldList;
+    }
+
+    public String getFocusFieldName() {
+        return focusFieldName;
+    }
+
+    public String getFormLocation() {
+        return this.formLocation;
+    }
+
+    public String getFormTitleAreaStyle() {
+        return this.formTitleAreaStyle;
+    }
+
+    public String getFormWidgetAreaStyle() {
+        return this.formWidgetAreaStyle;
+    }
+
+    public String getHeaderRowStyle() {
+        return this.headerRowStyle;
+    }
+
+    public boolean getHideHeader() {
+        return this.hideHeader;
+    }
+
+    public String getItemIndexSeparator() {
+        if (UtilValidate.isNotEmpty(this.itemIndexSeparator)) {
+            return this.itemIndexSeparator;
+        } else {
+            return "_o_";
+        }
+    }
+
+    public List<String> getLastOrderFields() {
+        return lastOrderFields;
+    }
+
+    public String getListEntryName() {
+        return this.listEntryName;
+    }
+
+    public String getListName() {
+        return this.listName;
+    }
+
+    public String getMultiPaginateIndexField(Map<String, Object> context) {
+        String field = this.paginateIndexField.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = DEFAULT_PAG_INDEX_FIELD;
+        }
+        //  append the paginator number
+        field = field + "_" + WidgetWorker.getPaginatorNumber(context);
+        return field;
+    }
+
+    public String getMultiPaginateSizeField(Map<String, Object> context) {
+        String field = this.paginateSizeField.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = DEFAULT_PAG_SIZE_FIELD;
+        }
+        //  append the paginator number
+        field = field + "_" + WidgetWorker.getPaginatorNumber(context);
+        return field;
+    }
+
+    public List<ModelFormField> getMultiSubmitFields() {
+        return this.multiSubmitFields;
+    }
+
+    public String getOddRowStyle() {
+        return this.oddRowStyle;
+    }
+
+    public List<UpdateArea> getOnPaginateUpdateAreas() {
+        return this.onPaginateUpdateAreas;
+    }
+
+    public List<UpdateArea> getOnSortColumnUpdateAreas() {
+        return this.onSortColumnUpdateAreas;
+    }
+
+    /* Returns the list of ModelForm.UpdateArea objects.
+     */
+    public List<UpdateArea> getOnSubmitUpdateAreas() {
+        return this.onSubmitUpdateAreas;
+    }
+
+    public String getOverrideListSize() {
+        return overrideListSize.getOriginal();
+    }
+
+    public int getOverrideListSize(Map<String, Object> context) {
+        int listSize = 0;
+        if (!this.overrideListSize.isEmpty()) {
+            String size = this.overrideListSize.expandString(context);
+            try {
+                size = size.replaceAll("[^0-9.]", "");
+                listSize = Integer.parseInt(size);
+            } catch (NumberFormatException e) {
+                Debug.logError(e, "Error getting override list size from value " + size, module);
+            }
+        }
+        return listSize;
+    }
+
+    public String getPaginate() {
+        return paginate.getOriginal();
+    }
+
+    public boolean getPaginate(Map<String, Object> context) {
+        String paginate = this.paginate.expandString(context);
+        if (!paginate.isEmpty()) {
+            return Boolean.valueOf(paginate).booleanValue();
+        } else {
+            return true;
+        }
+    }
+
+    public String getPaginateFirstLabel() {
+        return paginateFirstLabel.getOriginal();
+    }
+
+    public String getPaginateFirstLabel(Map<String, Object> context) {
+        Locale locale = (Locale) context.get("locale");
+        String field = this.paginateFirstLabel.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonFirst", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateFirstStyle() {
+        return DEFAULT_PAG_FIRST_STYLE;
+    }
+
+    public String getPaginateIndexField() {
+        return paginateIndexField.getOriginal();
+    }
+
+    public String getPaginateIndexField(Map<String, Object> context) {
+        String field = this.paginateIndexField.expandString(context);
+        if (field.isEmpty()) {
+            return DEFAULT_PAG_INDEX_FIELD;
+        }
+        return field;
+    }
+
+    public String getPaginateLastLabel() {
+        return paginateLastLabel.getOriginal();
+    }
+
+    public String getPaginateLastLabel(Map<String, Object> context) {
+        Locale locale = (Locale) context.get("locale");
+        String field = this.paginateLastLabel.expandString(context);
+        if (UtilValidate.isEmpty(field)) {
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonLast", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateLastStyle() {
+        return DEFAULT_PAG_LAST_STYLE;
+    }
+
+    public String getPaginateNextLabel() {
+        return paginateNextLabel.getOriginal();
+    }
+
+    public String getPaginateNextLabel(Map<String, Object> context) {
+        String field = this.paginateNextLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            return UtilProperties.getMessage("CommonUiLabels", "CommonNext", locale);
+        }
+        return field;
+    }
+
+    public String getPaginateNextStyle() {
+        return DEFAULT_PAG_NEXT_STYLE;
+    }
+
+    public String getPaginatePreviousLabel() {
+        return paginatePreviousLabel.getOriginal();
+    }
+
+    public String getPaginatePreviousLabel(Map<String, Object> context) {
+        String field = this.paginatePreviousLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            field = UtilProperties.getMessage("CommonUiLabels", "CommonPrevious", locale);
+        }
+        return field;
+    }
+
+    public String getPaginatePreviousStyle() {
+        return DEFAULT_PAG_PREV_STYLE;
+    }
+
+    public String getPaginateSizeField() {
+        return paginateSizeField.getOriginal();
+    }
+
+    public String getPaginateSizeField(Map<String, Object> context) {
+        String field = this.paginateSizeField.expandString(context);
+        if (field.isEmpty()) {
+            return DEFAULT_PAG_SIZE_FIELD;
+        }
+        return field;
+    }
+
+    public String getPaginateStyle() {
+        return this.paginateStyle;
+    }
+
+    public String getPaginateTarget() {
+        return paginateTarget.getOriginal();
+    }
+
+    public String getPaginateTarget(Map<String, Object> context) {
+        String targ = this.paginateTarget.expandString(context);
+        if (targ.isEmpty()) {
+            Map<String, ?> parameters = UtilGenerics.cast(context.get("parameters"));
+            if (parameters != null && parameters.containsKey("targetRequestUri")) {
+                targ = (String) parameters.get("targetRequestUri");
+            }
+        }
+        return targ;
+    }
+
+    public String getPaginateTargetAnchor() {
+        return this.paginateTargetAnchor;
+    }
+
+    public String getPaginateViewSizeLabel() {
+        return paginateViewSizeLabel.getOriginal();
+    }
+
+    public String getPaginateViewSizeLabel(Map<String, Object> context) {
+        String field = this.paginateViewSizeLabel.expandString(context);
+        if (field.isEmpty()) {
+            Locale locale = (Locale) context.get("locale");
+            return UtilProperties.getMessage("CommonUiLabels", "CommonItemsPerPage", locale);
+        }
+        return field;
+    }
+
+    private ModelForm getParentForm(Element formElement, ModelReader entityModelReader, DispatchContext dispatchContext) {
+        ModelForm parent = null;
+        String parentResource = formElement.getAttribute("extends-resource");
+        String parentForm = formElement.getAttribute("extends");
+        if (parentForm.length() > 0) {
+            // check if we have a resource name (part of the string before the ?)
+            if (parentResource.length() > 0) {
+                try {
+                    parent = FormFactory.getFormFromLocation(parentResource, parentForm, entityModelReader, dispatchContext);
+                } catch (Exception e) {
+                    Debug.logError(e, "Failed to load parent form definition '" + parentForm + "' at resource '" + parentResource
+                            + "'", module);
+                }
+            } else if (!parentForm.equals(formElement.getAttribute("name"))) {
+                // try to find a form definition in the same file
+                Element rootElement = formElement.getOwnerDocument().getDocumentElement();
+                List<? extends Element> formElements = UtilXml.childElementList(rootElement, "form");
+                //Uncomment below to add support for abstract forms
+                //formElements.addAll(UtilXml.childElementList(rootElement, "abstract-form"));
+                for (Element formElementEntry : formElements) {
+                    if (formElementEntry.getAttribute("name").equals(parentForm)) {
+                        parent = new ModelForm(formElementEntry, parentResource, entityModelReader, dispatchContext);
+                        break;
+                    }
+                }
+                if (parent == null) {
+                    Debug.logError("Failed to find parent form definition '" + parentForm + "' in same document.", module);
+                }
+            } else {
+                Debug.logError("Recursive form definition found for '" + formElement.getAttribute("name") + ".'", module);
+            }
+        }
+        return parent;
+    }
+
+    public String getParentFormLocation() {
+        return this.parentModelForm == null ? null : this.parentModelForm.getFormLocation();
+    }
+
+    public String getParentFormName() {
+        return this.parentModelForm == null ? null : this.parentModelForm.getName();
+    }
+
+    public ModelForm getParentModelForm() {
+        return parentModelForm;
+    }
+
+    public String getPassedRowCount(Map<String, Object> context) {
+        return rowCountExdr.expandString(context);
+    }
+
+    public List<ModelAction> getRowActions() {
+        return rowActions;
+    }
+
+    public String getRowCount() {
+        return rowCountExdr.getOriginal();
+    }
+
+    public boolean getSeparateColumns() {
+        return this.separateColumns;
+    }
+
+    public boolean getSkipEnd() {
+        return this.skipEnd;
+    }
+
+    public boolean getSkipStart() {
+        return this.skipStart;
+    }
+
+    public String getSortField(Map<String, Object> context) {
+        String value = null;
+        try {
+            value = (String) context.get(this.sortFieldParameterName);
+            if (value == null) {
+                Map<String, String> parameters = UtilGenerics.cast(context.get("parameters"));
+                if (parameters != null) {
+                    value = parameters.get(this.sortFieldParameterName);
+                }
+            }
+        } catch (Exception e) {
+            Debug.logWarning(e, "Error getting sortField: " + e.toString(), module);
+        }
+        return value;
+    }
+
+    public String getSortFieldParameterName() {
+        return this.sortFieldParameterName;
+    }
+
+    public List<SortField> getSortOrderFields() {
+        return sortOrderFields;
+    }
+
+    /**
+     * iterate through alt-row-styles list to see if should be used, then add style
+     * @return The style for item row
+     */
+    public String getStyleAltRowStyle(Map<String, Object> context) {
+        String styles = "";
+        try {
+            // use the same Interpreter (ie with the same context setup) for all evals
+            Interpreter bsh = this.getBshInterpreter(context);
+            for (AltRowStyle altRowStyle : this.altRowStyles) {
+                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(altRowStyle.useWhen));
+                // retVal should be a Boolean, if not something weird is up...
+                if (retVal instanceof Boolean) {
+                    Boolean boolVal = (Boolean) retVal;
+                    if (boolVal.booleanValue()) {
+                        styles += altRowStyle.style;
+                    }
+                } else {
+                    throw new IllegalArgumentException("Return value from style condition eval was not a Boolean: "
+                            + retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
+                }
+            }
+        } catch (EvalError e) {
+            String errmsg = "Error evaluating BeanShell style conditions on form " + getName();
+            Debug.logError(e, errmsg, module);
+            throw new IllegalArgumentException(errmsg);
+        }
+        return styles;
+    }
+
+    public String getTarget() {
+        return target.getOriginal();
+    }
+
+    /** iterate through altTargets list to see if any should be used, if not return original target
+     * @return The target for this Form
+     */
+    public String getTarget(Map<String, Object> context, String targetType) {
+        Map<String, Object> expanderContext = context;
+        UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+        if (simpleEncoder != null) {
+            expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
+        }
+        try {
+            // use the same Interpreter (ie with the same context setup) for all evals
+            Interpreter bsh = this.getBshInterpreter(context);
+            for (AltTarget altTarget : this.altTargets) {
+                String useWhen = FlexibleStringExpander.expandString(altTarget.useWhen, context);
+                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
+                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 target condition eval was not a Boolean: "
+                            + retVal.getClass().getName() + " [" + retVal + "] of form " + getName());
+                }
+
+                if (condTrue && !targetType.equals("inter-app")) {
+                    return altTarget.targetExdr.expandString(expanderContext);
+                }
+            }
+        } catch (EvalError e) {
+            String errmsg = "Error evaluating BeanShell target conditions on form " + getName();
+            Debug.logError(e, errmsg, module);
+            throw new IllegalArgumentException(errmsg);
+        }
+        return target.expandString(expanderContext);
+    }
+
+    public String getTargetType() {
+        return this.targetType;
+    }
+
+    public String getTargetWindow() {
+        return targetWindowExdr.getOriginal();
+    }
+
+    public String getTargetWindow(Map<String, Object> context) {
+        return this.targetWindowExdr.expandString(context);
+    }
+
+    public String getTitle() {
+        return this.title;
+    }
+
+    public String getTooltip() {
+        return this.tooltip;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public boolean getUseRowSubmit() {
+        return this.useRowSubmit;
+    }
+
+    public Set<String> getUseWhenFields() {
+        return useWhenFields;
+    }
+    public boolean getGroupColumns() {
+        return groupColumns;
+    }
+
+    public boolean isOverridenListSize() {
+        return !this.overrideListSize.isEmpty();
+    }
+
+    public void runFormActions(Map<String, Object> context) {
+        AbstractModelAction.runSubActions(this.actions, context);
+    }
+
+    public static class AltRowStyle {
+        public final String useWhen;
+        public final String style;
+
+        public AltRowStyle(Element altRowStyleElement) {
+            this.useWhen = altRowStyleElement.getAttribute("use-when");
+            this.style = altRowStyleElement.getAttribute("style");
+        }
+    }
+
+    public static class AltTarget {
+        public final String useWhen;
+        public final FlexibleStringExpander targetExdr;
+
+        public AltTarget(Element altTargetElement) {
+            this.useWhen = altTargetElement.getAttribute("use-when");
+            this.targetExdr = FlexibleStringExpander.getInstance(altTargetElement.getAttribute("target"));
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj instanceof AltTarget && obj.hashCode() == this.hashCode();
+        }
+
+        @Override
+        public int hashCode() {
+            return useWhen.hashCode();
+        }
+    }
+
+    public static class AutoFieldsEntity {
+        public final String entityName;
+        public final String mapName;
+        public final String defaultFieldType;
+        public final int defaultPosition;
+
+        public AutoFieldsEntity(Element element) {
+            this.entityName = element.getAttribute("entity-name");
+            this.mapName = element.getAttribute("map-name");
+            this.defaultFieldType = element.getAttribute("default-field-type");
+            String positionStr = element.getAttribute("default-position");
+            int position = 1;
+            try {
+                if (UtilValidate.isNotEmpty(positionStr)) {
+                    position = Integer.valueOf(positionStr);
+                }
+            } catch (Exception e) {
+                Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr
+                        + "], using the default of the form renderer", module);
+            }
+            this.defaultPosition = position;
+        }
+    }
+
+    public static class AutoFieldsService {
+        public final String serviceName;
+        public final String mapName;
+        public final String defaultFieldType;
+        public final int defaultPosition;
+
+        public AutoFieldsService(Element element) {
+            this.serviceName = element.getAttribute("service-name");
+            this.mapName = element.getAttribute("map-name");
+            this.defaultFieldType = element.getAttribute("default-field-type");
+            String positionStr = element.getAttribute("default-position");
+            int position = 1;
+            try {
+                if (UtilValidate.isNotEmpty(positionStr)) {
+                    position = Integer.valueOf(positionStr);
+                }
+            } catch (Exception e) {
+                Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr
+                        + "], using the default of the form renderer", module);
+            }
+            this.defaultPosition = position;
+        }
+    }
+
+    public static class Banner implements FieldGroupBase {
+        public final FlexibleStringExpander style;
+        public final FlexibleStringExpander text;
+        public final FlexibleStringExpander textStyle;
+        public final FlexibleStringExpander leftText;
+        public final FlexibleStringExpander leftTextStyle;
+        public final FlexibleStringExpander rightText;
+        public final FlexibleStringExpander rightTextStyle;
+
+        public Banner(Element sortOrderElement) {
+            this.style = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("style"));
+            this.text = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("text"));
+            this.textStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("text-style"));
+            this.leftText = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("left-text"));
+            this.leftTextStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("left-text-style"));
+            this.rightText = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("right-text"));
+            this.rightTextStyle = FlexibleStringExpander.getInstance(sortOrderElement.getAttribute("right-text-style"));
+        }
+
+        public String getLeftText(Map<String, Object> context) {
+            return this.leftText.expandString(context);
+        }
+
+        public String getLeftTextStyle(Map<String, Object> context) {
+            return this.leftTextStyle.expandString(context);
+        }
+
+        public String getRightText(Map<String, Object> context) {
+            return this.rightText.expandString(context);
+        }
+
+        public String getRightTextStyle(Map<String, Object> context) {
+            return this.rightTextStyle.expandString(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.style.expandString(context);
+        }
+
+        public String getText(Map<String, Object> context) {
+            return this.text.expandString(context);
+        }
+
+        public String getTextStyle(Map<String, Object> context) {
+            return this.textStyle.expandString(context);
+        }
+
+        public void renderString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderBanner(writer, context, this);
+        }
+    }
+
+    public static class FieldGroup implements FieldGroupBase {
+        private static AtomicInteger baseSeqNo = new AtomicInteger(0);
+        private static final String baseId = "_G";
+        private final String id;
+        private final String style;
+        private final String title;
+        private final boolean collapsible;
+        private final boolean initiallyCollapsed;
+        private final ModelForm modelForm;
+
+        public FieldGroup(Element sortOrderElement, ModelForm modelForm, List<SortField> sortOrderFields,
+                Map<String, FieldGroupBase> fieldGroupMap) {
+            this.modelForm = modelForm;
+            String id;
+            String style = "";
+            String title = "";
+            boolean collapsible = false;
+            boolean initiallyCollapsed = false;
+            if (sortOrderElement != null) {
+                id = sortOrderElement.getAttribute("id");
+                if (id.isEmpty()) {
+                    String lastGroupId = baseId + baseSeqNo.getAndIncrement() + "_";
+                    id = lastGroupId;
+                }
+                style = sortOrderElement.getAttribute("style");
+                title = sortOrderElement.getAttribute("title");
+                collapsible = "true".equals(sortOrderElement.getAttribute("collapsible"));
+                initiallyCollapsed = "true".equals(sortOrderElement.getAttribute("initially-collapsed"));
+                if (initiallyCollapsed) {
+                    collapsible = true;
+                }
+                for (Element sortFieldElement : UtilXml.childElementList(sortOrderElement, "sort-field")) {
+                    sortOrderFields.add(new SortField(sortFieldElement.getAttribute("name"), sortFieldElement
+                            .getAttribute("position")));
+                    fieldGroupMap.put(sortFieldElement.getAttribute("name"), this);
+                }
+            } else {
+                String lastGroupId = baseId + baseSeqNo.getAndIncrement() + "_";
+                id = lastGroupId;
+            }
+            this.id = id;
+            this.style = style;
+            this.title = title;
+            this.collapsible = collapsible;
+            this.initiallyCollapsed = initiallyCollapsed;
+        }
+
+        public Boolean collapsible() {
+            return this.collapsible;
+        }
+
+        public String getId() {
+            return this.id;
+        }
+
+        public String getStyle() {
+            return this.style;
+        }
+
+        public String getTitle() {
+            return this.title;
+        }
+
+        public Boolean initiallyCollapsed() {
+            return this.initiallyCollapsed;
+        }
+
+        public void renderEndString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderFormatSingleWrapperClose(writer, context, modelForm);
+            if (!modelForm.fieldGroupList.isEmpty()) {
+                if (shouldUse(context)) {
+                    formStringRenderer.renderFieldGroupClose(writer, context, this);
+                }
+            }
+        }
+
+        public void renderStartString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            if (!modelForm.fieldGroupList.isEmpty()) {
+                if (shouldUse(context)) {
+                    formStringRenderer.renderFieldGroupOpen(writer, context, this);
+                }
+            }
+            formStringRenderer.renderFormatSingleWrapperOpen(writer, context, modelForm);
+        }
+
+        public boolean shouldUse(Map<String, Object> context) {
+            for (String fieldName : modelForm.fieldGroupMap.keySet()) {
+                FieldGroupBase group = modelForm.fieldGroupMap.get(fieldName);
+                if (group instanceof FieldGroup) {
+                    FieldGroup fieldgroup = (FieldGroup) group;
+                    if (this.id.equals(fieldgroup.getId())) {
+                        for (ModelFormField modelField : modelForm.fieldList) {
+                            if (fieldName.equals(modelField.getName()) && modelField.shouldUse(context)) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    public static interface FieldGroupBase {
+    }
+
+    public static class SortField {
+        private final String fieldName;
+        private final Integer position;
+
+        public SortField(String name) {
+            this(name, null);
+        }
+
+        public SortField(String name, String position) {
+            this.fieldName = name;
+            if (UtilValidate.isNotEmpty(position)) {
+                Integer posParam = null;
+                try {
+                    posParam = Integer.valueOf(position);
+                } catch (Exception e) {/* just ignore the exception*/
+                }
+                this.position = posParam;
+            } else {
+                this.position = null;
+            }
+        }
+
+        public String getFieldName() {
+            return this.fieldName;
+        }
+
+        public Integer getPosition() {
+            return this.position;
+        }
+    }
+
+    /** The UpdateArea class implements the <code>&lt;on-event-update-area&gt;</code>
+     * elements used in form widgets.
+     */
+    public static class UpdateArea {
+        private final String eventType;
+        private final String areaId;
+        private final String areaTarget;
+        private final String defaultServiceName;
+        private final String defaultEntityName;
+        private final CommonWidgetModels.AutoEntityParameters autoEntityParameters;
+        private final CommonWidgetModels.AutoServiceParameters autoServiceParameters;
+        private final List<CommonWidgetModels.Parameter> parameterList;
+
+        public UpdateArea(Element updateAreaElement) {
+            this(updateAreaElement, null, null);
+        }
+
+        /** XML constructor.
+         * @param updateAreaElement The <code>&lt;on-xxx-update-area&gt;</code>
+         * XML element.
+         */
+        public UpdateArea(Element updateAreaElement, String defaultServiceName, String defaultEntityName) {
+            this.eventType = updateAreaElement.getAttribute("event-type");
+            this.areaId = updateAreaElement.getAttribute("area-id");
+            this.areaTarget = updateAreaElement.getAttribute("area-target");
+            this.defaultServiceName = defaultServiceName;
+            this.defaultEntityName = defaultEntityName;
+            List<? extends Element> parameterElementList = UtilXml.childElementList(updateAreaElement, "parameter");
+            if (parameterElementList.isEmpty()) {
+                this.parameterList = Collections.emptyList();
+            } else {
+                List<CommonWidgetModels.Parameter> parameterList = new ArrayList<CommonWidgetModels.Parameter>(parameterElementList.size());
+                for (Element parameterElement : parameterElementList) {
+                    parameterList.add(new CommonWidgetModels.Parameter(parameterElement));
+                }
+                this.parameterList = Collections.unmodifiableList(parameterList);
+            }
+            Element autoServiceParamsElement = UtilXml.firstChildElement(updateAreaElement, "auto-parameters-service");
+            if (autoServiceParamsElement != null) {
+                this.autoServiceParameters = new CommonWidgetModels.AutoServiceParameters(autoServiceParamsElement);
+            } else {
+                this.autoServiceParameters = null;
+            }
+            Element autoEntityParamsElement = UtilXml.firstChildElement(updateAreaElement, "auto-parameters-entity");
+            if (autoEntityParamsElement != null) {
+                this.autoEntityParameters = new CommonWidgetModels.AutoEntityParameters(autoEntityParamsElement);
+            } else {
+                this.autoEntityParameters = null;
+            }
+        }
+
+        /** String constructor.
+         * @param areaId The id of the widget element to be updated
+         * @param areaTarget The target URL called to update the area
+         */
+        public UpdateArea(String eventType, String areaId, String areaTarget) {
+            this.eventType = eventType;
+            this.areaId = areaId;
+            this.areaTarget = areaTarget;
+            this.defaultServiceName = null;
+            this.defaultEntityName = null;
+            this.parameterList = Collections.emptyList();
+            this.autoServiceParameters = null;
+            this.autoEntityParameters = null;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj instanceof UpdateArea && obj.hashCode() == this.hashCode();
+        }
+
+        public String getAreaId() {
+            return areaId;
+        }
+
+        public String getAreaTarget(Map<String, ? extends Object> context) {
+            return FlexibleStringExpander.expandString(areaTarget, context);
+        }
+
+        public String getEventType() {
+            return eventType;
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> context) {
+            Map<String, String> fullParameterMap = new HashMap<String, String>();
+            if (autoServiceParameters != null) {
+                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, defaultServiceName));
+            }
+            if (autoEntityParameters != null) {
+                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, defaultEntityName));
+            }
+            for (CommonWidgetModels.Parameter parameter : this.parameterList) {
+                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
+            }
+
+            return fullParameterMap;
+        }
+
+        @Override
+        public int hashCode() {
+            return areaId.hashCode();
+        }
+
+        public String getAreaTarget() {
+            return areaTarget;
+        }
+
+        public String getDefaultServiceName() {
+            return defaultServiceName;
+        }
+
+        public String getDefaultEntityName() {
+            return defaultEntityName;
+        }
+
+        public CommonWidgetModels.AutoEntityParameters getAutoEntityParameters() {
+            return autoEntityParameters;
+        }
+
+        public CommonWidgetModels.AutoServiceParameters getAutoServiceParameters() {
+            return autoServiceParameters;
+        }
+
+        public List<CommonWidgetModels.Parameter> getParameterList() {
+            return parameterList;
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java b/framework/widget/src/org/ofbiz/widget/model/ModelFormAction.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelFormAction.java
index 29a0879..46c60c5 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelFormAction.java
@@ -1,275 +1,272 @@
-/*******************************************************************************
- * 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.ofbiz.widget.form;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.regex.PatternSyntaxException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.finder.EntityFinderUtil;
-import org.ofbiz.service.GenericServiceException;
-import org.ofbiz.service.ModelService;
-import org.ofbiz.widget.AbstractModelAction;
-import org.ofbiz.widget.ModelAction;
-import org.ofbiz.widget.ModelActionVisitor;
-import org.ofbiz.widget.WidgetWorker;
-import org.w3c.dom.Element;
-
-/**
- * Abstract form action.
- */
-public abstract class ModelFormAction {
-
-    public static final String module = ModelFormAction.class.getName();
-
-    public static List<ModelAction> readSubActions(ModelForm modelForm, Element parentElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
-        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
-        for (Element actionElement : UtilXml.childElementList(parentElement)) {
-            if ("service".equals(actionElement.getNodeName())) {
-                actions.add(new Service(modelForm, actionElement));
-            } else if ("entity-and".equals(actionElement.getNodeName()) || "entity-condition".equals(actionElement.getNodeName())
-                    || "get-related".equals(actionElement.getNodeName())) {
-                if (!actionElement.hasAttribute("list")) {
-                    String listName = modelForm.getListName();
-                    if (UtilValidate.isEmpty(listName)) {
-                        listName = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME;
-                    }
-                    actionElement.setAttribute("list", listName);
-                }
-                actions.add(AbstractModelAction.newInstance(modelForm, actionElement));
-            } else if ("call-parent-actions".equals(actionElement.getNodeName())) {
-                actions.add(new CallParentActions(modelForm, actionElement));
-            } else {
-                actions.add(AbstractModelAction.newInstance(modelForm, actionElement));
-            }
-        }
-        return Collections.unmodifiableList(actions);
-    }
-
-    /**
-     * Models the &lt;call-parent-actions&gt; element.
-     * 
-     * @see <code>widget-form.xsd</code>
-     */
-    @SuppressWarnings("serial")
-    public static class CallParentActions extends AbstractModelAction {
-        private final ActionsKind kind;;
-        private final ModelForm modelForm;
-
-        public CallParentActions(ModelForm modelForm, Element callParentActionsElement) {
-            super(modelForm, callParentActionsElement);
-            String parentName = callParentActionsElement.getParentNode().getNodeName();
-            if ("actions".equals(parentName)) {
-                kind = ActionsKind.ACTIONS;
-            } else if ("row-actions".equals(parentName)) {
-                kind = ActionsKind.ROW_ACTIONS;
-            } else {
-                throw new IllegalArgumentException("Action element not supported for call-parent-actions : " + parentName);
-            }
-            ModelForm parentModel = modelForm.getParentModelForm();
-            if (parentModel == null) {
-                throw new IllegalArgumentException("call-parent-actions can only be used with form extending another form");
-            }
-            this.modelForm = modelForm;
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            ModelForm parentModel = modelForm.getParentModelForm();
-            switch (kind) {
-            case ACTIONS:
-                parentModel.runFormActions(context);
-                break;
-            case ROW_ACTIONS:
-                AbstractModelAction.runSubActions(parentModel.getRowActions(), context);
-                break;
-            }
-        }
-
-        protected static enum ActionsKind {
-            ACTIONS, ROW_ACTIONS
-        }
-    }
-
-    /**
-     * Models the &lt;service&gt; element.
-     * 
-     * @see <code>widget-form.xsd</code>
-     */
-    @SuppressWarnings("serial")
-    public static class Service extends AbstractModelAction {
-        private final FlexibleStringExpander autoFieldMapExdr;
-        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
-        private final boolean ignoreError;
-        private final FlexibleStringExpander resultMapListNameExdr;
-        private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
-        private final FlexibleStringExpander serviceNameExdr;
-
-        public Service(ModelForm modelForm, Element serviceElement) {
-            super(modelForm, serviceElement);
-            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
-            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
-            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
-            FlexibleStringExpander resultMapListNameExdr = FlexibleStringExpander.getInstance("");
-            if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list"))
-                    && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-name"))) {
-                if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator"))
-                        && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator-name"))) {
-                    String lstNm = modelForm.getListName();
-                    if (UtilValidate.isEmpty(lstNm)) {
-                        lstNm = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME;
-                    }
-                    resultMapListNameExdr = FlexibleStringExpander.getInstance(lstNm);
-                } else {
-                    // this is deprecated, but support it for now anyway
-                    resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
-                            .getAttribute("result-map-list-iterator"));
-                    if (resultMapListNameExdr.isEmpty())
-                        resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
-                                .getAttribute("result-map-list-iterator-name"));
-                }
-            } else {
-                resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
-                if (resultMapListNameExdr.isEmpty())
-                    resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
-                            .getAttribute("result-map-list-name"));
-            }
-            this.resultMapListNameExdr = resultMapListNameExdr;
-            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
-            this.ignoreError = "true".equals(serviceElement.getAttribute("ignore-error"));
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public String getServiceName() {
-            return serviceNameExdr.getOriginal();
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            String serviceNameExpanded = this.serviceNameExdr.expandString(context);
-            if (UtilValidate.isEmpty(serviceNameExpanded)) {
-                throw new IllegalArgumentException("Service name was empty, expanded from: " + this.serviceNameExdr.getOriginal());
-            }
-            String autoFieldMapString = this.autoFieldMapExdr.expandString(context);
-            boolean autoFieldMapBool = !"false".equals(autoFieldMapString);
-            try {
-                Map<String, Object> serviceContext = null;
-                if (autoFieldMapBool) {
-                    if (!"true".equals(autoFieldMapString)) {
-                        Map<String, Object> autoFieldMap = UtilGenerics.checkMap(context.get(autoFieldMapString));
-                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
-                                .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, autoFieldMap);
-                    } else {
-                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
-                                .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context);
-                    }
-                } else {
-                    serviceContext = new HashMap<String, Object>();
-                }
-                if (this.fieldMap != null) {
-                    EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, serviceContext);
-                }
-                Map<String, Object> result = null;
-                if (this.ignoreError) {
-                    result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext, -1, true);
-                } else {
-                    result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext);
-                }
-                if (!this.resultMapNameAcsr.isEmpty()) {
-                    this.resultMapNameAcsr.put(context, result);
-                    String queryString = (String) result.get("queryString");
-                    context.put("queryString", queryString);
-                    context.put("queryStringMap", result.get("queryStringMap"));
-                    if (UtilValidate.isNotEmpty(queryString)) {
-                        try {
-                            String queryStringEncoded = queryString.replaceAll("&", "%26");
-                            context.put("queryStringEncoded", queryStringEncoded);
-                        } catch (PatternSyntaxException e) {
-
-                        }
-                    }
-                } else {
-                    context.putAll(result);
-                }
-                String listName = resultMapListNameExdr.expandString(context);
-                Object listObj = result.get(listName);
-                if (listObj != null) {
-                    if (!(listObj instanceof List<?>) && !(listObj instanceof ListIterator<?>)) {
-                        throw new IllegalArgumentException("Error in form [" + this.getModelWidget().getName()
-                                + "] calling service with name [" + serviceNameExpanded
-                                + "]: the result that is supposed to be a List or ListIterator and is not.");
-                    }
-                    context.put("listName", listName);
-                    context.put(listName, listObj);
-                }
-            } catch (GenericServiceException e) {
-                String errMsg = "Error in form [" + this.getModelWidget().getName() + "] calling service with name ["
-                        + serviceNameExpanded + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                if (!this.ignoreError) {
-                    throw new IllegalArgumentException(errMsg);
-                }
-            }
-        }
-
-        public FlexibleStringExpander getAutoFieldMapExdr() {
-            return autoFieldMapExdr;
-        }
-
-        public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() {
-            return fieldMap;
-        }
-
-        public boolean getIgnoreError() {
-            return ignoreError;
-        }
-
-        public FlexibleStringExpander getResultMapListNameExdr() {
-            return resultMapListNameExdr;
-        }
-
-        public FlexibleMapAccessor<Map<String, Object>> getResultMapNameAcsr() {
-            return resultMapNameAcsr;
-        }
-
-        public FlexibleStringExpander getServiceNameExdr() {
-            return serviceNameExdr;
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.regex.PatternSyntaxException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.finder.EntityFinderUtil;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.ModelService;
+import org.ofbiz.widget.WidgetWorker;
+import org.w3c.dom.Element;
+
+/**
+ * Abstract form action.
+ */
+public abstract class ModelFormAction {
+
+    public static final String module = ModelFormAction.class.getName();
+
+    public static List<ModelAction> readSubActions(ModelForm modelForm, Element parentElement) {
+        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
+        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
+        for (Element actionElement : UtilXml.childElementList(parentElement)) {
+            if ("service".equals(actionElement.getNodeName())) {
+                actions.add(new Service(modelForm, actionElement));
+            } else if ("entity-and".equals(actionElement.getNodeName()) || "entity-condition".equals(actionElement.getNodeName())
+                    || "get-related".equals(actionElement.getNodeName())) {
+                if (!actionElement.hasAttribute("list")) {
+                    String listName = modelForm.getListName();
+                    if (UtilValidate.isEmpty(listName)) {
+                        listName = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME;
+                    }
+                    actionElement.setAttribute("list", listName);
+                }
+                actions.add(AbstractModelAction.newInstance(modelForm, actionElement));
+            } else if ("call-parent-actions".equals(actionElement.getNodeName())) {
+                actions.add(new CallParentActions(modelForm, actionElement));
+            } else {
+                actions.add(AbstractModelAction.newInstance(modelForm, actionElement));
+            }
+        }
+        return Collections.unmodifiableList(actions);
+    }
+
+    /**
+     * Models the &lt;call-parent-actions&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    @SuppressWarnings("serial")
+    public static class CallParentActions extends AbstractModelAction {
+        private final ActionsKind kind;;
+        private final ModelForm modelForm;
+
+        public CallParentActions(ModelForm modelForm, Element callParentActionsElement) {
+            super(modelForm, callParentActionsElement);
+            String parentName = callParentActionsElement.getParentNode().getNodeName();
+            if ("actions".equals(parentName)) {
+                kind = ActionsKind.ACTIONS;
+            } else if ("row-actions".equals(parentName)) {
+                kind = ActionsKind.ROW_ACTIONS;
+            } else {
+                throw new IllegalArgumentException("Action element not supported for call-parent-actions : " + parentName);
+            }
+            ModelForm parentModel = modelForm.getParentModelForm();
+            if (parentModel == null) {
+                throw new IllegalArgumentException("call-parent-actions can only be used with form extending another form");
+            }
+            this.modelForm = modelForm;
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            ModelForm parentModel = modelForm.getParentModelForm();
+            switch (kind) {
+            case ACTIONS:
+                parentModel.runFormActions(context);
+                break;
+            case ROW_ACTIONS:
+                AbstractModelAction.runSubActions(parentModel.getRowActions(), context);
+                break;
+            }
+        }
+
+        protected static enum ActionsKind {
+            ACTIONS, ROW_ACTIONS
+        }
+    }
+
+    /**
+     * Models the &lt;service&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    @SuppressWarnings("serial")
+    public static class Service extends AbstractModelAction {
+        private final FlexibleStringExpander autoFieldMapExdr;
+        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
+        private final boolean ignoreError;
+        private final FlexibleStringExpander resultMapListNameExdr;
+        private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
+        private final FlexibleStringExpander serviceNameExdr;
+
+        public Service(ModelForm modelForm, Element serviceElement) {
+            super(modelForm, serviceElement);
+            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
+            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
+            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
+            FlexibleStringExpander resultMapListNameExdr = FlexibleStringExpander.getInstance("");
+            if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list"))
+                    && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-name"))) {
+                if (UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator"))
+                        && UtilValidate.isEmpty(serviceElement.getAttribute("result-map-list-iterator-name"))) {
+                    String lstNm = modelForm.getListName();
+                    if (UtilValidate.isEmpty(lstNm)) {
+                        lstNm = ModelForm.DEFAULT_FORM_RESULT_LIST_NAME;
+                    }
+                    resultMapListNameExdr = FlexibleStringExpander.getInstance(lstNm);
+                } else {
+                    // this is deprecated, but support it for now anyway
+                    resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
+                            .getAttribute("result-map-list-iterator"));
+                    if (resultMapListNameExdr.isEmpty())
+                        resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
+                                .getAttribute("result-map-list-iterator-name"));
+                }
+            } else {
+                resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
+                if (resultMapListNameExdr.isEmpty())
+                    resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement
+                            .getAttribute("result-map-list-name"));
+            }
+            this.resultMapListNameExdr = resultMapListNameExdr;
+            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
+            this.ignoreError = "true".equals(serviceElement.getAttribute("ignore-error"));
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public String getServiceName() {
+            return serviceNameExdr.getOriginal();
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            String serviceNameExpanded = this.serviceNameExdr.expandString(context);
+            if (UtilValidate.isEmpty(serviceNameExpanded)) {
+                throw new IllegalArgumentException("Service name was empty, expanded from: " + this.serviceNameExdr.getOriginal());
+            }
+            String autoFieldMapString = this.autoFieldMapExdr.expandString(context);
+            boolean autoFieldMapBool = !"false".equals(autoFieldMapString);
+            try {
+                Map<String, Object> serviceContext = null;
+                if (autoFieldMapBool) {
+                    if (!"true".equals(autoFieldMapString)) {
+                        Map<String, Object> autoFieldMap = UtilGenerics.checkMap(context.get(autoFieldMapString));
+                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
+                                .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, autoFieldMap);
+                    } else {
+                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
+                                .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context);
+                    }
+                } else {
+                    serviceContext = new HashMap<String, Object>();
+                }
+                if (this.fieldMap != null) {
+                    EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, serviceContext);
+                }
+                Map<String, Object> result = null;
+                if (this.ignoreError) {
+                    result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext, -1, true);
+                } else {
+                    result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext);
+                }
+                if (!this.resultMapNameAcsr.isEmpty()) {
+                    this.resultMapNameAcsr.put(context, result);
+                    String queryString = (String) result.get("queryString");
+                    context.put("queryString", queryString);
+                    context.put("queryStringMap", result.get("queryStringMap"));
+                    if (UtilValidate.isNotEmpty(queryString)) {
+                        try {
+                            String queryStringEncoded = queryString.replaceAll("&", "%26");
+                            context.put("queryStringEncoded", queryStringEncoded);
+                        } catch (PatternSyntaxException e) {
+
+                        }
+                    }
+                } else {
+                    context.putAll(result);
+                }
+                String listName = resultMapListNameExdr.expandString(context);
+                Object listObj = result.get(listName);
+                if (listObj != null) {
+                    if (!(listObj instanceof List<?>) && !(listObj instanceof ListIterator<?>)) {
+                        throw new IllegalArgumentException("Error in form [" + this.getModelWidget().getName()
+                                + "] calling service with name [" + serviceNameExpanded
+                                + "]: the result that is supposed to be a List or ListIterator and is not.");
+                    }
+                    context.put("listName", listName);
+                    context.put(listName, listObj);
+                }
+            } catch (GenericServiceException e) {
+                String errMsg = "Error in form [" + this.getModelWidget().getName() + "] calling service with name ["
+                        + serviceNameExpanded + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                if (!this.ignoreError) {
+                    throw new IllegalArgumentException(errMsg);
+                }
+            }
+        }
+
+        public FlexibleStringExpander getAutoFieldMapExdr() {
+            return autoFieldMapExdr;
+        }
+
+        public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() {
+            return fieldMap;
+        }
+
+        public boolean getIgnoreError() {
+            return ignoreError;
+        }
+
+        public FlexibleStringExpander getResultMapListNameExdr() {
+            return resultMapListNameExdr;
+        }
+
+        public FlexibleMapAccessor<Map<String, Object>> getResultMapNameAcsr() {
+            return resultMapNameAcsr;
+        }
+
+        public FlexibleStringExpander getServiceNameExdr() {
+            return serviceNameExdr;
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java b/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
index f9d3ddd..4e6f3c6 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
@@ -1,3802 +1,3806 @@
-/*******************************************************************************
- * 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.ofbiz.widget.form;
-
-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.Collections;
-import java.util.Date;
-import java.util.HashMap;
-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.ofbiz.base.conversion.ConversionException;
-import org.ofbiz.base.conversion.DateTimeConverters;
-import org.ofbiz.base.conversion.DateTimeConverters.StringToTimestamp;
-import org.ofbiz.base.util.BshUtil;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.ObjectType;
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilDateTime;
-import org.ofbiz.base.util.UtilFormatOut;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.collections.MapStack;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntity;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.condition.EntityCondition;
-import org.ofbiz.entity.finder.EntityFinderUtil;
-import org.ofbiz.entity.model.ModelEntity;
-import org.ofbiz.entity.util.EntityUtil;
-import org.ofbiz.widget.CommonWidgetModels.*;
-import org.ofbiz.widget.ModelFieldVisitor;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.ModelForm.UpdateArea;
-import org.w3c.dom.Element;
-
-import bsh.EvalError;
-import bsh.Interpreter;
-
-/**
- * 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 String widgetAreaStyle;
-    private final String widgetStyle;
-
-    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.widgetAreaStyle = builder.getWidgetAreaStyle();
-        this.widgetStyle = builder.getWidgetStyle();
-    }
-
-    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();
-
-        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.DATE_FORMAT, timeZone, null);
-                    return df.format((java.util.Date) retVal);
-                } else if (retVal instanceof java.sql.Time) {
-                    DateFormat df = UtilDateTime.toTimeFormat(UtilDateTime.TIME_FORMAT, timeZone, null);
-                    return df.format((java.util.Date) retVal);
-                } else if (retVal instanceof java.sql.Timestamp) {
-                    DateFormat df = UtilDateTime.toDateTimeFormat(UtilDateTime.DATE_TIME_FORMAT, 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 {
-                    returnValue = retVal.toString();
-                }
-            } else {
-                returnValue = defaultValue;
-            }
-        }
-
-        if (this.getEncodeOutput() && returnValue != null) {
-            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-            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;
-        return this.modelForm.getName() + "_" + this.getFieldName();
-    }
-
-    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 (java.lang.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 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();
-    }
-
-    /**
-     * 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 (Exception e) {
-            // okay, not a timestamp...
-        }
-
-        if (timestampVal == null) {
-            try {
-                dateVal = java.sql.Date.valueOf(value);
-            } catch (Exception e) {
-                // okay, not a date...
-            }
-        }
-
-        if (timestampVal == null && dateVal == null) {
-            try {
-                timeVal = java.sql.Time.valueOf(value);
-            } catch (Exception 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 {
-            Interpreter bsh = this.modelForm.getBshInterpreter(context);
-            Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhenStr));
-            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 (EvalError e) {
-            String errMsg = "Error evaluating BeanShell use-when condition [" + useWhenStr + "] on the field " + this.name
-                    + " of form " + this.modelForm.getName() + ": " + e.toString();
-            Debug.logError(e, errMsg, module);
-            //Debug.logError("For use-when eval error context is: " + context, 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 getDefaultOptionThru() {
-            return this.defaultOptionThru;
-        }
-
-        @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 = "";
-            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 (Exception 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"));
-
-                List<GenericValue> values = null;
-                values = delegator.findList(this.entityName, findCondition, null, this.orderByList, null, this.cache);
-
-                // 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
-                    ModelEntity modelEntity = delegator.getModelEntity(this.entityName);
-                    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;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 confirmationMsgExdr;
-        private final FlexibleStringExpander description;
-        private final boolean requestConfirmation;
-        private final Link link;
-        public HyperlinkField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.alsoHidden = !"false".equals(element.getAttribute("also-hidden"));
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message"));
-            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
-            this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation"));
-            this.link = new Link(element);
-        }
-
-        private HyperlinkField(HyperlinkField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.alsoHidden = original.alsoHidden;
-            this.confirmationMsgExdr = original.confirmationMsgExdr;
-            this.description = original.description;
-            this.requestConfirmation = original.requestConfirmation;
-            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 this.confirmationMsgExdr.expandString(context);
-        }
-
-        public FlexibleStringExpander getConfirmationMsgExdr() {
-            return confirmationMsgExdr;
-        }
-
-        public FlexibleStringExpander getDescription() {
-            return description;
-        }
-
-        public String getDescription(Map<String, Object> context) {
-            return this.description.expandString(context);
-        }
-
-        public boolean getRequestConfirmation() {
-            return this.requestConfirmation;
-        }
-
-        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) {
-            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);
-        }
-    }
-
-    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);
-            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;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"));
-            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) {
-            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 {
-                    Interpreter bsh = (Interpreter) context.get("bshInterpreter");
-                    if (bsh == null) {
-                        bsh = BshUtil.makeInterpreter(context);
-                        context.put("bshInterpreter", bsh);
-                    }
-
-                    Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
-
-                    // 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 (EvalError e) {
-                    String errmsg = "Error evaluating BeanShell target conditions";
-                    Debug.logError(e, errmsg, module);
-                    throw new IllegalArgumentException(errmsg);
-                }
-            }
-            return shouldUse;
-        }
-    }
-
-    /**
-     * 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;
-
-        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 (Exception e) {
-                    if (UtilValidate.isNotEmpty(colsStr)) {
-                        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 (Exception e) {
-                    if (UtilValidate.isNotEmpty(rowsStr)) {
-                        Debug.logError("Could not parse the size value of the text element: [" + rowsStr
-                                + "], setting to default of " + rows, module);
-                    }
-                }
-            }
-            this.rows = rows;
-            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.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;
-        }
-
-        @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 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 (Exception 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.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 (Exception 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) {
-            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 boolean getHideIgnoreCase() {
-            return this.hideIgnoreCase;
-        }
-
-        public boolean getHideOptions() {
-            return this.hideOptions;
-        }
-
-        public boolean getIgnoreCase() {
-            return this.ignoreCase;
-        }
-
-        @Override
-        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
-                throws IOException {
-            formStringRenderer.renderTextFindField(writer, context, this);
-        }
-    }
-}
+/*******************************************************************************
+ * 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.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.Collections;
+import java.util.Date;
+import java.util.HashMap;
+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.ofbiz.base.conversion.ConversionException;
+import org.ofbiz.base.conversion.DateTimeConverters;
+import org.ofbiz.base.conversion.DateTimeConverters.StringToTimestamp;
+import org.ofbiz.base.util.BshUtil;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.ObjectType;
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilDateTime;
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntity;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.finder.EntityFinderUtil;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.util.EntityUtil;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.CommonWidgetModels.AutoEntityParameters;
+import org.ofbiz.widget.model.CommonWidgetModels.AutoServiceParameters;
+import org.ofbiz.widget.model.CommonWidgetModels.Image;
+import org.ofbiz.widget.model.CommonWidgetModels.Link;
+import org.ofbiz.widget.model.CommonWidgetModels.Parameter;
+import org.ofbiz.widget.model.ModelForm.UpdateArea;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.w3c.dom.Element;
+
+import bsh.EvalError;
+import bsh.Interpreter;
+
+/**
+ * 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 String widgetAreaStyle;
+    private final String widgetStyle;
+
+    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.widgetAreaStyle = builder.getWidgetAreaStyle();
+        this.widgetStyle = builder.getWidgetStyle();
+    }
+
+    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();
+
+        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.DATE_FORMAT, timeZone, null);
+                    return df.format((java.util.Date) retVal);
+                } else if (retVal instanceof java.sql.Time) {
+                    DateFormat df = UtilDateTime.toTimeFormat(UtilDateTime.TIME_FORMAT, timeZone, null);
+                    return df.format((java.util.Date) retVal);
+                } else if (retVal instanceof java.sql.Timestamp) {
+                    DateFormat df = UtilDateTime.toDateTimeFormat(UtilDateTime.DATE_TIME_FORMAT, 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 {
+                    returnValue = retVal.toString();
+                }
+            } else {
+                returnValue = defaultValue;
+            }
+        }
+
+        if (this.getEncodeOutput() && returnValue != null) {
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+            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;
+        return this.modelForm.getName() + "_" + this.getFieldName();
+    }
+
+    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 (java.lang.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 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();
+    }
+
+    /**
+     * 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 (Exception e) {
+            // okay, not a timestamp...
+        }
+
+        if (timestampVal == null) {
+            try {
+                dateVal = java.sql.Date.valueOf(value);
+            } catch (Exception e) {
+                // okay, not a date...
+            }
+        }
+
+        if (timestampVal == null && dateVal == null) {
+            try {
+                timeVal = java.sql.Time.valueOf(value);
+            } catch (Exception 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 {
+            Interpreter bsh = this.modelForm.getBshInterpreter(context);
+            Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhenStr));
+            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 (EvalError e) {
+            String errMsg = "Error evaluating BeanShell use-when condition [" + useWhenStr + "] on the field " + this.name
+                    + " of form " + this.modelForm.getName() + ": " + e.toString();
+            Debug.logError(e, errMsg, module);
+            //Debug.logError("For use-when eval error context is: " + context, 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 getDefaultOptionThru() {
+            return this.defaultOptionThru;
+        }
+
+        @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 = "";
+            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 (Exception 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"));
+
+                List<GenericValue> values = null;
+                values = delegator.findList(this.entityName, findCondition, null, this.orderByList, null, this.cache);
+
+                // 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
+                    ModelEntity modelEntity = delegator.getModelEntity(this.entityName);
+                    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;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 confirmationMsgExdr;
+        private final FlexibleStringExpander description;
+        private final boolean requestConfirmation;
+        private final Link link;
+        public HyperlinkField(Element element, ModelFormField modelFormField) {
+            super(element, modelFormField);
+            this.alsoHidden = !"false".equals(element.getAttribute("also-hidden"));
+            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message"));
+            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
+            this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation"));
+            this.link = new Link(element);
+        }
+
+        private HyperlinkField(HyperlinkField original, ModelFormField modelFormField) {
+            super(original.getFieldSource(), original.getFieldType(), modelFormField);
+            this.alsoHidden = original.alsoHidden;
+            this.confirmationMsgExdr = original.confirmationMsgExdr;
+            this.description = original.description;
+            this.requestConfirmation = original.requestConfirmation;
+            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 this.confirmationMsgExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getConfirmationMsgExdr() {
+            return confirmationMsgExdr;
+        }
+
+        public FlexibleStringExpander getDescription() {
+            return description;
+        }
+
+        public String getDescription(Map<String, Object> context) {
+            return this.description.expandString(context);
+        }
+
+        public boolean getRequestConfirmation() {
+            return this.requestConfirmation;
+        }
+
+        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) {
+            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);
+        }
+    }
+
+    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);
+            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;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"));
+            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) {
+            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 {
+                    Interpreter bsh = (Interpreter) context.get("bshInterpreter");
+                    if (bsh == null) {
+                        bsh = BshUtil.makeInterpreter(context);
+                        context.put("bshInterpreter", bsh);
+                    }
+
+                    Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhen));
+
+                    // 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 (EvalError e) {
+                    String errmsg = "Error evaluating BeanShell target conditions";
+                    Debug.logError(e, errmsg, module);
+                    throw new IllegalArgumentException(errmsg);
+                }
+            }
+            return shouldUse;
+        }
+    }
+
+    /**
+     * 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;
+
+        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 (Exception e) {
+                    if (UtilValidate.isNotEmpty(colsStr)) {
+                        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 (Exception e) {
+                    if (UtilValidate.isNotEmpty(rowsStr)) {
+                        Debug.logError("Could not parse the size value of the text element: [" + rowsStr
+                                + "], setting to default of " + rows, module);
+                    }
+                }
+            }
+            this.rows = rows;
+            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.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;
+        }
+
+        @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 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 (Exception 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.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 (Exception 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) {
+            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 boolean getHideIgnoreCase() {
+            return this.hideIgnoreCase;
+        }
+
+        public boolean getHideOptions() {
+            return this.hideOptions;
+        }
+
+        public boolean getIgnoreCase() {
+            return this.ignoreCase;
+        }
+
+        @Override
+        public void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
+                throws IOException {
+            formStringRenderer.renderTextFindField(writer, context, this);
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelFormFieldBuilder.java b/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
similarity index 96%
rename from framework/widget/src/org/ofbiz/widget/form/ModelFormFieldBuilder.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
index e77d8d5..be52bd7 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelFormFieldBuilder.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelFormFieldBuilder.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.form;
+package org.ofbiz.widget.model;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -35,29 +35,29 @@
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.ModelParam;
 import org.ofbiz.service.ModelService;
-import org.ofbiz.widget.form.ModelForm.UpdateArea;
-import org.ofbiz.widget.form.ModelFormField.CheckField;
-import org.ofbiz.widget.form.ModelFormField.ContainerField;
-import org.ofbiz.widget.form.ModelFormField.DateFindField;
-import org.ofbiz.widget.form.ModelFormField.DateTimeField;
-import org.ofbiz.widget.form.ModelFormField.DisplayEntityField;
-import org.ofbiz.widget.form.ModelFormField.DisplayField;
-import org.ofbiz.widget.form.ModelFormField.DropDownField;
-import org.ofbiz.widget.form.ModelFormField.FileField;
-import org.ofbiz.widget.form.ModelFormField.HiddenField;
-import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
-import org.ofbiz.widget.form.ModelFormField.IgnoredField;
-import org.ofbiz.widget.form.ModelFormField.ImageField;
-import org.ofbiz.widget.form.ModelFormField.LookupField;
-import org.ofbiz.widget.form.ModelFormField.OptionSource;
-import org.ofbiz.widget.form.ModelFormField.PasswordField;
-import org.ofbiz.widget.form.ModelFormField.RadioField;
-import org.ofbiz.widget.form.ModelFormField.RangeFindField;
-import org.ofbiz.widget.form.ModelFormField.ResetField;
-import org.ofbiz.widget.form.ModelFormField.SubmitField;
-import org.ofbiz.widget.form.ModelFormField.TextField;
-import org.ofbiz.widget.form.ModelFormField.TextFindField;
-import org.ofbiz.widget.form.ModelFormField.TextareaField;
+import org.ofbiz.widget.model.ModelForm.UpdateArea;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayEntityField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.OptionSource;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
 import org.w3c.dom.Element;
 
 /**
diff --git a/framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java b/framework/widget/src/org/ofbiz/widget/model/ModelMenu.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelMenu.java
index 44fc162..7d98c20 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelMenu.java
@@ -1,536 +1,534 @@
-/*******************************************************************************
- * 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.ofbiz.widget.menu;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.*;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.w3c.dom.Element;
-
-/**
- * Models the &lt;menu&gt; element.
- * 
- * @see <code>widget-menu.xsd</code>
- */
-@SuppressWarnings("serial")
-public class ModelMenu extends ModelWidget {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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.
-     * 
-     * 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 = ModelMenu.class.getName();
-
-    private final List<ModelAction> actions;
-    private final String defaultAlign;
-    private final String defaultAlignStyle;
-    private final FlexibleStringExpander defaultAssociatedContentId;
-    private final String defaultCellWidth;
-    private final String defaultDisabledTitleStyle;
-    private final String defaultEntityName;
-    private final Boolean defaultHideIfSelected;
-    private final String defaultMenuItemName;
-    private final String defaultPermissionEntityAction;
-    private final String defaultPermissionOperation;
-    private final String defaultSelectedStyle;
-    private final String defaultTitleStyle;
-    private final String defaultTooltipStyle;
-    private final String defaultWidgetStyle;
-    private final FlexibleStringExpander extraIndex;
-    private final String fillStyle;
-    private final String id;
-    private final FlexibleStringExpander menuContainerStyleExdr;
-    /** This List will contain one copy of each item for each item name in the order
-     * they were encountered in the service, entity, or menu definition; item definitions
-     * with constraints will also be in this list but may appear multiple times for the same
-     * item name.
-     *
-     * When rendering the menu the order in this list should be following and it should not be
-     * necessary to use the Map. The Map is used when loading the menu definition to keep the
-     * list clean and implement the override features for item definitions.
-     */
-    private final List<ModelMenuItem> menuItemList;
-    /** This Map is keyed with the item name and has a ModelMenuItem for the value; items
-     * with conditions will not be put in this Map so item definition overrides for items
-     * with conditions is not possible.
-     */
-    private final Map<String, ModelMenuItem> menuItemMap;
-    private final String menuLocation;
-    private final String menuWidth;
-    private final String orientation;
-    private final ModelMenu parentMenu;
-    private final FlexibleMapAccessor<String> selectedMenuItemContextFieldName;
-    private final String target;
-    private final FlexibleStringExpander title;
-    private final String tooltip;
-    private final String type;
-
-    /** XML Constructor */
-    public ModelMenu(Element menuElement, String menuLocation) {
-        super(menuElement);
-        ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
-        String defaultAlign = "";
-        String defaultAlignStyle = "";
-        FlexibleStringExpander defaultAssociatedContentId = FlexibleStringExpander.getInstance("");
-        String defaultCellWidth = "";
-        String defaultDisabledTitleStyle = "";
-        String defaultEntityName = "";
-        Boolean defaultHideIfSelected = Boolean.FALSE;
-        String defaultMenuItemName = "";
-        String defaultPermissionEntityAction = "";
-        String defaultPermissionOperation = "";
-        String defaultSelectedStyle = "";
-        String defaultTitleStyle = "";
-        String defaultTooltipStyle = "";
-        String defaultWidgetStyle = "";
-        FlexibleStringExpander extraIndex = FlexibleStringExpander.getInstance("");
-        String fillStyle = "";
-        String id = "";
-        FlexibleStringExpander menuContainerStyleExdr = FlexibleStringExpander.getInstance("");
-        ArrayList<ModelMenuItem> menuItemList = new ArrayList<ModelMenuItem>();
-        Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>();
-        String menuWidth = "";
-        String orientation = "horizontal";
-        FlexibleMapAccessor<String> selectedMenuItemContextFieldName = FlexibleMapAccessor.getInstance("");
-        String target = "";
-        FlexibleStringExpander title = FlexibleStringExpander.getInstance("");
-        String tooltip = "";
-        String type = "";
-        // check if there is a parent menu to inherit from
-        ModelMenu parent = null;
-        String parentResource = menuElement.getAttribute("extends-resource");
-        String parentMenu = menuElement.getAttribute("extends");
-        if (!parentMenu.isEmpty()) {
-            if (!parentResource.isEmpty()) {
-                try {
-                    parent = MenuFactory.getMenuFromLocation(parentResource, parentMenu);
-                } catch (Exception e) {
-                    Debug.logError(e, "Failed to load parent menu definition '" + parentMenu + "' at resource '" + parentResource
-                            + "'", module);
-                }
-            } else {
-                parentResource = menuLocation;
-                // try to find a menu definition in the same file
-                Element rootElement = menuElement.getOwnerDocument().getDocumentElement();
-                List<? extends Element> menuElements = UtilXml.childElementList(rootElement, "menu");
-                for (Element menuElementEntry : menuElements) {
-                    if (menuElementEntry.getAttribute("name").equals(parentMenu)) {
-                        parent = new ModelMenu(menuElementEntry, parentResource);
-                        break;
-                    }
-                }
-                if (parent == null) {
-                    Debug.logError("Failed to find parent menu definition '" + parentMenu + "' in same document.", module);
-                }
-            }
-            if (parent != null) {
-                type = parent.type;
-                target = parent.target;
-                id = parent.id;
-                title = parent.title;
-                tooltip = parent.tooltip;
-                defaultEntityName = parent.defaultEntityName;
-                defaultTitleStyle = parent.defaultTitleStyle;
-                defaultSelectedStyle = parent.defaultSelectedStyle;
-                defaultWidgetStyle = parent.defaultWidgetStyle;
-                defaultTooltipStyle = parent.defaultTooltipStyle;
-                defaultMenuItemName = parent.defaultMenuItemName;
-                menuItemList.addAll(parent.menuItemList);
-                menuItemMap.putAll(parent.menuItemMap);
-                defaultPermissionOperation = parent.defaultPermissionOperation;
-                defaultPermissionEntityAction = parent.defaultPermissionEntityAction;
-                defaultAssociatedContentId = parent.defaultAssociatedContentId;
-                defaultHideIfSelected = parent.defaultHideIfSelected;
-                orientation = parent.orientation;
-                menuWidth = parent.menuWidth;
-                defaultCellWidth = parent.defaultCellWidth;
-                defaultDisabledTitleStyle = parent.defaultDisabledTitleStyle;
-                defaultAlign = parent.defaultAlign;
-                defaultAlignStyle = parent.defaultAlignStyle;
-                fillStyle = parent.fillStyle;
-                extraIndex = parent.extraIndex;
-                selectedMenuItemContextFieldName = parent.selectedMenuItemContextFieldName;
-                menuContainerStyleExdr = parent.menuContainerStyleExdr;
-                if (parent.actions != null) {
-                    actions.addAll(parent.actions);
-                }
-            }
-        }
-        if (!menuElement.getAttribute("type").isEmpty())
-            type = menuElement.getAttribute("type");
-        if (!menuElement.getAttribute("target").isEmpty())
-            target = menuElement.getAttribute("target");
-        if (!menuElement.getAttribute("id").isEmpty())
-            id = menuElement.getAttribute("id");
-        if (!menuElement.getAttribute("title").isEmpty())
-            title = FlexibleStringExpander.getInstance(menuElement.getAttribute("title"));
-        if (!menuElement.getAttribute("tooltip").isEmpty())
-            tooltip = menuElement.getAttribute("tooltip");
-        if (!menuElement.getAttribute("default-entity-name").isEmpty())
-            defaultEntityName = menuElement.getAttribute("default-entity-name");
-        if (!menuElement.getAttribute("default-title-style").isEmpty())
-            defaultTitleStyle = menuElement.getAttribute("default-title-style");
-        if (!menuElement.getAttribute("default-selected-style").isEmpty())
-            defaultSelectedStyle = menuElement.getAttribute("default-selected-style");
-        if (!menuElement.getAttribute("default-widget-style").isEmpty())
-            defaultWidgetStyle = menuElement.getAttribute("default-widget-style");
-        if (!menuElement.getAttribute("default-tooltip-style").isEmpty())
-            defaultTooltipStyle = menuElement.getAttribute("default-tooltip-style");
-        if (!menuElement.getAttribute("default-menu-item-name").isEmpty())
-            defaultMenuItemName = menuElement.getAttribute("default-menu-item-name");
-        if (!menuElement.getAttribute("default-permission-operation").isEmpty())
-            defaultPermissionOperation = menuElement.getAttribute("default-permission-operation");
-        if (!menuElement.getAttribute("default-permission-entity-action").isEmpty())
-            defaultPermissionEntityAction = menuElement.getAttribute("default-permission-entity-action");
-        if (!menuElement.getAttribute("default-associated-content-id").isEmpty())
-            defaultAssociatedContentId = FlexibleStringExpander.getInstance(menuElement
-                    .getAttribute("default-associated-content-id"));
-        if (!menuElement.getAttribute("orientation").isEmpty())
-            orientation = menuElement.getAttribute("orientation");
-        if (!menuElement.getAttribute("menu-width").isEmpty())
-            menuWidth = menuElement.getAttribute("menu-width");
-        if (!menuElement.getAttribute("default-cell-width").isEmpty())
-            defaultCellWidth = menuElement.getAttribute("default-cell-width");
-        if (!menuElement.getAttribute("default-hide-if-selected").isEmpty())
-            defaultHideIfSelected = "true".equals(menuElement.getAttribute("default-hide-if-selected").isEmpty());
-        if (!menuElement.getAttribute("default-disabled-title-style").isEmpty())
-            defaultDisabledTitleStyle = menuElement.getAttribute("default-disabled-title-style");
-        if (!menuElement.getAttribute("selected-menuitem-context-field-name").isEmpty())
-            selectedMenuItemContextFieldName = FlexibleMapAccessor.getInstance(menuElement
-                    .getAttribute("selected-menuitem-context-field-name"));
-        if (!menuElement.getAttribute("menu-container-style").isEmpty())
-            menuContainerStyleExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("menu-container-style"));
-        if (!menuElement.getAttribute("default-align").isEmpty())
-            defaultAlign = menuElement.getAttribute("default-align");
-        if (!menuElement.getAttribute("default-align-style").isEmpty())
-            defaultAlignStyle = menuElement.getAttribute("default-align-style");
-        if (!menuElement.getAttribute("fill-style").isEmpty())
-            fillStyle = menuElement.getAttribute("fill-style");
-        if (!menuElement.getAttribute("extra-index").isEmpty())
-            extraIndex = FlexibleStringExpander.getInstance(menuElement.getAttribute("extra-index"));
-        // read all actions under the "actions" element
-        Element actionsElement = UtilXml.firstChildElement(menuElement, "actions");
-        if (actionsElement != null) {
-            actions.addAll(ModelMenuAction.readSubActions(this, actionsElement));
-        }
-        actions.trimToSize();
-        this.actions = Collections.unmodifiableList(actions);
-        this.defaultAlign = defaultAlign;
-        this.defaultAlignStyle = defaultAlignStyle;
-        this.defaultAssociatedContentId = defaultAssociatedContentId;
-        this.defaultCellWidth = defaultCellWidth;
-        this.defaultDisabledTitleStyle = defaultDisabledTitleStyle;
-        this.defaultEntityName = defaultEntityName;
-        this.defaultHideIfSelected = defaultHideIfSelected;
-        this.defaultMenuItemName = defaultMenuItemName;
-        this.defaultPermissionEntityAction = defaultPermissionEntityAction;
-        this.defaultPermissionOperation = defaultPermissionOperation;
-        this.defaultSelectedStyle = defaultSelectedStyle;
-        this.defaultTitleStyle = defaultTitleStyle;
-        this.defaultTooltipStyle = defaultTooltipStyle;
-        this.defaultWidgetStyle = defaultWidgetStyle;
-        this.extraIndex = extraIndex;
-        this.fillStyle = fillStyle;
-        this.id = id;
-        this.menuContainerStyleExdr = menuContainerStyleExdr;
-        List<? extends Element> itemElements = UtilXml.childElementList(menuElement, "menu-item");
-        for (Element itemElement : itemElements) {
-            ModelMenuItem modelMenuItem = new ModelMenuItem(itemElement, this);
-            addUpdateMenuItem(modelMenuItem, menuItemList, menuItemMap);
-        }
-        menuItemList.trimToSize();
-        this.menuItemList = Collections.unmodifiableList(menuItemList);
-        this.menuItemMap = Collections.unmodifiableMap(menuItemMap);
-        this.menuLocation = menuLocation;
-        this.menuWidth = menuWidth;
-        this.orientation = orientation;
-        this.parentMenu = parent;
-        this.selectedMenuItemContextFieldName = selectedMenuItemContextFieldName;
-        this.target = target;
-        this.title = title;
-        this.tooltip = tooltip;
-        this.type = type;
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
-    }
-
-    /**
-     * add/override modelMenuItem using the menuItemList and menuItemMap
-     *
-     */
-    private void addUpdateMenuItem(ModelMenuItem modelMenuItem, List<ModelMenuItem> menuItemList,
-            Map<String, ModelMenuItem> menuItemMap) {
-        ModelMenuItem existingMenuItem = menuItemMap.get(modelMenuItem.getName());
-        if (existingMenuItem != null) {
-            // does exist, update the item by doing a merge/override
-            ModelMenuItem mergedMenuItem = existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem);
-            int existingItemIndex = menuItemList.indexOf(existingMenuItem);
-            menuItemList.set(existingItemIndex, mergedMenuItem);
-            menuItemMap.put(modelMenuItem.getName(), mergedMenuItem);
-        } else {
-            // does not exist, add to Map
-            menuItemList.add(modelMenuItem);
-            menuItemMap.put(modelMenuItem.getName(), modelMenuItem);
-        }
-    }
-
-    public List<ModelAction> getActions() {
-        return actions;
-    }
-
-    @Override
-    public String getBoundaryCommentName() {
-        return menuLocation + "#" + getName();
-    }
-
-    public String getCurrentMenuName(Map<String, Object> context) {
-        return getName();
-    }
-
-    public String getDefaultAlign() {
-        return this.defaultAlign;
-    }
-
-    public String getDefaultAlignStyle() {
-        return this.defaultAlignStyle;
-    }
-
-    public FlexibleStringExpander getDefaultAssociatedContentId() {
-        return defaultAssociatedContentId;
-    }
-
-    public String getDefaultAssociatedContentId(Map<String, Object> context) {
-        return defaultAssociatedContentId.expandString(context);
-    }
-
-    public String getDefaultCellWidth() {
-        return this.defaultCellWidth;
-    }
-
-    public String getDefaultDisabledTitleStyle() {
-        return this.defaultDisabledTitleStyle;
-    }
-
-    public String getDefaultEntityName() {
-        return this.defaultEntityName;
-    }
-
-    public Boolean getDefaultHideIfSelected() {
-        return this.defaultHideIfSelected;
-    }
-
-    public String getDefaultMenuItemName() {
-        return this.defaultMenuItemName;
-    }
-
-    public String getDefaultPermissionEntityAction() {
-        return this.defaultPermissionEntityAction;
-    }
-
-    public String getDefaultPermissionOperation() {
-        return this.defaultPermissionOperation;
-    }
-
-    public String getDefaultSelectedStyle() {
-        return this.defaultSelectedStyle;
-    }
-
-    public String getDefaultTitleStyle() {
-        return this.defaultTitleStyle;
-    }
-
-    public String getDefaultTooltipStyle() {
-        return this.defaultTooltipStyle;
-    }
-
-    public String getDefaultWidgetStyle() {
-        return this.defaultWidgetStyle;
-    }
-
-    public FlexibleStringExpander getExtraIndex() {
-        return extraIndex;
-    }
-
-    public String getExtraIndex(Map<String, Object> context) {
-        try {
-            return extraIndex.expandString(context);
-        } catch (Exception ex) {
-            return "";
-        }
-    }
-
-    public String getFillStyle() {
-        return this.fillStyle;
-    }
-
-    public String getId() {
-        return this.id;
-    }
-
-    public String getMenuContainerStyle(Map<String, Object> context) {
-        return menuContainerStyleExdr.expandString(context);
-    }
-
-    public FlexibleStringExpander getMenuContainerStyleExdr() {
-        return menuContainerStyleExdr;
-    }
-
-    public List<ModelMenuItem> getMenuItemList() {
-        return menuItemList;
-    }
-
-    public Map<String, ModelMenuItem> getMenuItemMap() {
-        return menuItemMap;
-    }
-
-    public String getMenuLocation() {
-        return menuLocation;
-    }
-
-    public String getMenuWidth() {
-        return this.menuWidth;
-    }
-
-    public ModelMenuItem getModelMenuItemByName(String name) {
-        return this.menuItemMap.get(name);
-    }
-
-    public String getOrientation() {
-        return this.orientation;
-    }
-
-    public ModelMenu getParentMenu() {
-        return parentMenu;
-    }
-
-    public FlexibleMapAccessor<String> getSelectedMenuItemContextFieldName() {
-        return selectedMenuItemContextFieldName;
-    }
-
-    public String getSelectedMenuItemContextFieldName(Map<String, Object> context) {
-        String menuItemName = this.selectedMenuItemContextFieldName.get(context);
-        if (UtilValidate.isEmpty(menuItemName)) {
-            return this.defaultMenuItemName;
-        }
-        return menuItemName;
-    }
-
-    public String getTarget() {
-        return target;
-    }
-
-    public FlexibleStringExpander getTitle() {
-        return title;
-    }
-
-    public String getTitle(Map<String, Object> context) {
-        return title.expandString(context);
-    }
-
-    public String getTooltip() {
-        return this.tooltip;
-    }
-
-    public String getType() {
-        return this.type;
-    }
-
-    public int renderedMenuItemCount(Map<String, Object> context) {
-        int count = 0;
-        for (ModelMenuItem item : this.menuItemList) {
-            if (item.shouldBeRendered(context))
-                count++;
-        }
-        return count;
-    }
-
-    /**
-     * Renders this menu to a String, i.e. in a text format, as defined with the
-     * MenuStringRenderer implementation.
-     *
-     * @param writer The Writer that the menu text will be written to
-     * @param context Map containing the menu context; the following are
-     *   reserved words in this context: parameters (Map), isError (Boolean),
-     *   itemIndex (Integer, for lists only, otherwise null), bshInterpreter,
-     *   menuName (String, optional alternate name for menu, defaults to the
-     *   value of the name attribute)
-     * @param menuStringRenderer An implementation of the MenuStringRenderer
-     *   interface that is responsible for the actual text generation for
-     *   different menu elements; implementing you own makes it possible to
-     *   use the same menu definitions for many types of menu UIs
-     */
-    public void renderMenuString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
-            throws IOException {
-        AbstractModelAction.runSubActions(this.actions, context);
-        if ("simple".equals(this.type)) {
-            this.renderSimpleMenuString(writer, context, menuStringRenderer);
-        } else {
-            throw new IllegalArgumentException("The type " + this.getType() + " is not supported for menu with name "
-                    + this.getName());
-        }
-    }
-
-    public void renderSimpleMenuString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
-            throws IOException {
-        // render menu open
-        menuStringRenderer.renderMenuOpen(writer, context, this);
-
-        // render formatting wrapper open
-        menuStringRenderer.renderFormatSimpleWrapperOpen(writer, context, this);
-
-        // render each menuItem row, except hidden & ignored rows
-        for (ModelMenuItem item : this.menuItemList) {
-            item.renderMenuItemString(writer, context, menuStringRenderer);
-        }
-        // render formatting wrapper close
-        menuStringRenderer.renderFormatSimpleWrapperClose(writer, context, this);
-
-        // render menu close
-        menuStringRenderer.renderMenuClose(writer, context, this);
-    }
-
-    public void runActions(Map<String, Object> context) {
-        AbstractModelAction.runSubActions(this.actions, context);
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+import org.w3c.dom.Element;
+
+/**
+ * Models the &lt;menu&gt; element.
+ * 
+ * @see <code>widget-menu.xsd</code>
+ */
+@SuppressWarnings("serial")
+public class ModelMenu extends ModelWidget {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     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.
+     * 
+     * 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 = ModelMenu.class.getName();
+
+    private final List<ModelAction> actions;
+    private final String defaultAlign;
+    private final String defaultAlignStyle;
+    private final FlexibleStringExpander defaultAssociatedContentId;
+    private final String defaultCellWidth;
+    private final String defaultDisabledTitleStyle;
+    private final String defaultEntityName;
+    private final Boolean defaultHideIfSelected;
+    private final String defaultMenuItemName;
+    private final String defaultPermissionEntityAction;
+    private final String defaultPermissionOperation;
+    private final String defaultSelectedStyle;
+    private final String defaultTitleStyle;
+    private final String defaultTooltipStyle;
+    private final String defaultWidgetStyle;
+    private final FlexibleStringExpander extraIndex;
+    private final String fillStyle;
+    private final String id;
+    private final FlexibleStringExpander menuContainerStyleExdr;
+    /** This List will contain one copy of each item for each item name in the order
+     * they were encountered in the service, entity, or menu definition; item definitions
+     * with constraints will also be in this list but may appear multiple times for the same
+     * item name.
+     *
+     * When rendering the menu the order in this list should be following and it should not be
+     * necessary to use the Map. The Map is used when loading the menu definition to keep the
+     * list clean and implement the override features for item definitions.
+     */
+    private final List<ModelMenuItem> menuItemList;
+    /** This Map is keyed with the item name and has a ModelMenuItem for the value; items
+     * with conditions will not be put in this Map so item definition overrides for items
+     * with conditions is not possible.
+     */
+    private final Map<String, ModelMenuItem> menuItemMap;
+    private final String menuLocation;
+    private final String menuWidth;
+    private final String orientation;
+    private final ModelMenu parentMenu;
+    private final FlexibleMapAccessor<String> selectedMenuItemContextFieldName;
+    private final String target;
+    private final FlexibleStringExpander title;
+    private final String tooltip;
+    private final String type;
+
+    /** XML Constructor */
+    public ModelMenu(Element menuElement, String menuLocation) {
+        super(menuElement);
+        ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
+        String defaultAlign = "";
+        String defaultAlignStyle = "";
+        FlexibleStringExpander defaultAssociatedContentId = FlexibleStringExpander.getInstance("");
+        String defaultCellWidth = "";
+        String defaultDisabledTitleStyle = "";
+        String defaultEntityName = "";
+        Boolean defaultHideIfSelected = Boolean.FALSE;
+        String defaultMenuItemName = "";
+        String defaultPermissionEntityAction = "";
+        String defaultPermissionOperation = "";
+        String defaultSelectedStyle = "";
+        String defaultTitleStyle = "";
+        String defaultTooltipStyle = "";
+        String defaultWidgetStyle = "";
+        FlexibleStringExpander extraIndex = FlexibleStringExpander.getInstance("");
+        String fillStyle = "";
+        String id = "";
+        FlexibleStringExpander menuContainerStyleExdr = FlexibleStringExpander.getInstance("");
+        ArrayList<ModelMenuItem> menuItemList = new ArrayList<ModelMenuItem>();
+        Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>();
+        String menuWidth = "";
+        String orientation = "horizontal";
+        FlexibleMapAccessor<String> selectedMenuItemContextFieldName = FlexibleMapAccessor.getInstance("");
+        String target = "";
+        FlexibleStringExpander title = FlexibleStringExpander.getInstance("");
+        String tooltip = "";
+        String type = "";
+        // check if there is a parent menu to inherit from
+        ModelMenu parent = null;
+        String parentResource = menuElement.getAttribute("extends-resource");
+        String parentMenu = menuElement.getAttribute("extends");
+        if (!parentMenu.isEmpty()) {
+            if (!parentResource.isEmpty()) {
+                try {
+                    parent = MenuFactory.getMenuFromLocation(parentResource, parentMenu);
+                } catch (Exception e) {
+                    Debug.logError(e, "Failed to load parent menu definition '" + parentMenu + "' at resource '" + parentResource
+                            + "'", module);
+                }
+            } else {
+                parentResource = menuLocation;
+                // try to find a menu definition in the same file
+                Element rootElement = menuElement.getOwnerDocument().getDocumentElement();
+                List<? extends Element> menuElements = UtilXml.childElementList(rootElement, "menu");
+                for (Element menuElementEntry : menuElements) {
+                    if (menuElementEntry.getAttribute("name").equals(parentMenu)) {
+                        parent = new ModelMenu(menuElementEntry, parentResource);
+                        break;
+                    }
+                }
+                if (parent == null) {
+                    Debug.logError("Failed to find parent menu definition '" + parentMenu + "' in same document.", module);
+                }
+            }
+            if (parent != null) {
+                type = parent.type;
+                target = parent.target;
+                id = parent.id;
+                title = parent.title;
+                tooltip = parent.tooltip;
+                defaultEntityName = parent.defaultEntityName;
+                defaultTitleStyle = parent.defaultTitleStyle;
+                defaultSelectedStyle = parent.defaultSelectedStyle;
+                defaultWidgetStyle = parent.defaultWidgetStyle;
+                defaultTooltipStyle = parent.defaultTooltipStyle;
+                defaultMenuItemName = parent.defaultMenuItemName;
+                menuItemList.addAll(parent.menuItemList);
+                menuItemMap.putAll(parent.menuItemMap);
+                defaultPermissionOperation = parent.defaultPermissionOperation;
+                defaultPermissionEntityAction = parent.defaultPermissionEntityAction;
+                defaultAssociatedContentId = parent.defaultAssociatedContentId;
+                defaultHideIfSelected = parent.defaultHideIfSelected;
+                orientation = parent.orientation;
+                menuWidth = parent.menuWidth;
+                defaultCellWidth = parent.defaultCellWidth;
+                defaultDisabledTitleStyle = parent.defaultDisabledTitleStyle;
+                defaultAlign = parent.defaultAlign;
+                defaultAlignStyle = parent.defaultAlignStyle;
+                fillStyle = parent.fillStyle;
+                extraIndex = parent.extraIndex;
+                selectedMenuItemContextFieldName = parent.selectedMenuItemContextFieldName;
+                menuContainerStyleExdr = parent.menuContainerStyleExdr;
+                if (parent.actions != null) {
+                    actions.addAll(parent.actions);
+                }
+            }
+        }
+        if (!menuElement.getAttribute("type").isEmpty())
+            type = menuElement.getAttribute("type");
+        if (!menuElement.getAttribute("target").isEmpty())
+            target = menuElement.getAttribute("target");
+        if (!menuElement.getAttribute("id").isEmpty())
+            id = menuElement.getAttribute("id");
+        if (!menuElement.getAttribute("title").isEmpty())
+            title = FlexibleStringExpander.getInstance(menuElement.getAttribute("title"));
+        if (!menuElement.getAttribute("tooltip").isEmpty())
+            tooltip = menuElement.getAttribute("tooltip");
+        if (!menuElement.getAttribute("default-entity-name").isEmpty())
+            defaultEntityName = menuElement.getAttribute("default-entity-name");
+        if (!menuElement.getAttribute("default-title-style").isEmpty())
+            defaultTitleStyle = menuElement.getAttribute("default-title-style");
+        if (!menuElement.getAttribute("default-selected-style").isEmpty())
+            defaultSelectedStyle = menuElement.getAttribute("default-selected-style");
+        if (!menuElement.getAttribute("default-widget-style").isEmpty())
+            defaultWidgetStyle = menuElement.getAttribute("default-widget-style");
+        if (!menuElement.getAttribute("default-tooltip-style").isEmpty())
+            defaultTooltipStyle = menuElement.getAttribute("default-tooltip-style");
+        if (!menuElement.getAttribute("default-menu-item-name").isEmpty())
+            defaultMenuItemName = menuElement.getAttribute("default-menu-item-name");
+        if (!menuElement.getAttribute("default-permission-operation").isEmpty())
+            defaultPermissionOperation = menuElement.getAttribute("default-permission-operation");
+        if (!menuElement.getAttribute("default-permission-entity-action").isEmpty())
+            defaultPermissionEntityAction = menuElement.getAttribute("default-permission-entity-action");
+        if (!menuElement.getAttribute("default-associated-content-id").isEmpty())
+            defaultAssociatedContentId = FlexibleStringExpander.getInstance(menuElement
+                    .getAttribute("default-associated-content-id"));
+        if (!menuElement.getAttribute("orientation").isEmpty())
+            orientation = menuElement.getAttribute("orientation");
+        if (!menuElement.getAttribute("menu-width").isEmpty())
+            menuWidth = menuElement.getAttribute("menu-width");
+        if (!menuElement.getAttribute("default-cell-width").isEmpty())
+            defaultCellWidth = menuElement.getAttribute("default-cell-width");
+        if (!menuElement.getAttribute("default-hide-if-selected").isEmpty())
+            defaultHideIfSelected = "true".equals(menuElement.getAttribute("default-hide-if-selected").isEmpty());
+        if (!menuElement.getAttribute("default-disabled-title-style").isEmpty())
+            defaultDisabledTitleStyle = menuElement.getAttribute("default-disabled-title-style");
+        if (!menuElement.getAttribute("selected-menuitem-context-field-name").isEmpty())
+            selectedMenuItemContextFieldName = FlexibleMapAccessor.getInstance(menuElement
+                    .getAttribute("selected-menuitem-context-field-name"));
+        if (!menuElement.getAttribute("menu-container-style").isEmpty())
+            menuContainerStyleExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("menu-container-style"));
+        if (!menuElement.getAttribute("default-align").isEmpty())
+            defaultAlign = menuElement.getAttribute("default-align");
+        if (!menuElement.getAttribute("default-align-style").isEmpty())
+            defaultAlignStyle = menuElement.getAttribute("default-align-style");
+        if (!menuElement.getAttribute("fill-style").isEmpty())
+            fillStyle = menuElement.getAttribute("fill-style");
+        if (!menuElement.getAttribute("extra-index").isEmpty())
+            extraIndex = FlexibleStringExpander.getInstance(menuElement.getAttribute("extra-index"));
+        // read all actions under the "actions" element
+        Element actionsElement = UtilXml.firstChildElement(menuElement, "actions");
+        if (actionsElement != null) {
+            actions.addAll(ModelMenuAction.readSubActions(this, actionsElement));
+        }
+        actions.trimToSize();
+        this.actions = Collections.unmodifiableList(actions);
+        this.defaultAlign = defaultAlign;
+        this.defaultAlignStyle = defaultAlignStyle;
+        this.defaultAssociatedContentId = defaultAssociatedContentId;
+        this.defaultCellWidth = defaultCellWidth;
+        this.defaultDisabledTitleStyle = defaultDisabledTitleStyle;
+        this.defaultEntityName = defaultEntityName;
+        this.defaultHideIfSelected = defaultHideIfSelected;
+        this.defaultMenuItemName = defaultMenuItemName;
+        this.defaultPermissionEntityAction = defaultPermissionEntityAction;
+        this.defaultPermissionOperation = defaultPermissionOperation;
+        this.defaultSelectedStyle = defaultSelectedStyle;
+        this.defaultTitleStyle = defaultTitleStyle;
+        this.defaultTooltipStyle = defaultTooltipStyle;
+        this.defaultWidgetStyle = defaultWidgetStyle;
+        this.extraIndex = extraIndex;
+        this.fillStyle = fillStyle;
+        this.id = id;
+        this.menuContainerStyleExdr = menuContainerStyleExdr;
+        List<? extends Element> itemElements = UtilXml.childElementList(menuElement, "menu-item");
+        for (Element itemElement : itemElements) {
+            ModelMenuItem modelMenuItem = new ModelMenuItem(itemElement, this);
+            addUpdateMenuItem(modelMenuItem, menuItemList, menuItemMap);
+        }
+        menuItemList.trimToSize();
+        this.menuItemList = Collections.unmodifiableList(menuItemList);
+        this.menuItemMap = Collections.unmodifiableMap(menuItemMap);
+        this.menuLocation = menuLocation;
+        this.menuWidth = menuWidth;
+        this.orientation = orientation;
+        this.parentMenu = parent;
+        this.selectedMenuItemContextFieldName = selectedMenuItemContextFieldName;
+        this.target = target;
+        this.title = title;
+        this.tooltip = tooltip;
+        this.type = type;
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+
+    /**
+     * add/override modelMenuItem using the menuItemList and menuItemMap
+     *
+     */
+    private void addUpdateMenuItem(ModelMenuItem modelMenuItem, List<ModelMenuItem> menuItemList,
+            Map<String, ModelMenuItem> menuItemMap) {
+        ModelMenuItem existingMenuItem = menuItemMap.get(modelMenuItem.getName());
+        if (existingMenuItem != null) {
+            // does exist, update the item by doing a merge/override
+            ModelMenuItem mergedMenuItem = existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem);
+            int existingItemIndex = menuItemList.indexOf(existingMenuItem);
+            menuItemList.set(existingItemIndex, mergedMenuItem);
+            menuItemMap.put(modelMenuItem.getName(), mergedMenuItem);
+        } else {
+            // does not exist, add to Map
+            menuItemList.add(modelMenuItem);
+            menuItemMap.put(modelMenuItem.getName(), modelMenuItem);
+        }
+    }
+
+    public List<ModelAction> getActions() {
+        return actions;
+    }
+
+    @Override
+    public String getBoundaryCommentName() {
+        return menuLocation + "#" + getName();
+    }
+
+    public String getCurrentMenuName(Map<String, Object> context) {
+        return getName();
+    }
+
+    public String getDefaultAlign() {
+        return this.defaultAlign;
+    }
+
+    public String getDefaultAlignStyle() {
+        return this.defaultAlignStyle;
+    }
+
+    public FlexibleStringExpander getDefaultAssociatedContentId() {
+        return defaultAssociatedContentId;
+    }
+
+    public String getDefaultAssociatedContentId(Map<String, Object> context) {
+        return defaultAssociatedContentId.expandString(context);
+    }
+
+    public String getDefaultCellWidth() {
+        return this.defaultCellWidth;
+    }
+
+    public String getDefaultDisabledTitleStyle() {
+        return this.defaultDisabledTitleStyle;
+    }
+
+    public String getDefaultEntityName() {
+        return this.defaultEntityName;
+    }
+
+    public Boolean getDefaultHideIfSelected() {
+        return this.defaultHideIfSelected;
+    }
+
+    public String getDefaultMenuItemName() {
+        return this.defaultMenuItemName;
+    }
+
+    public String getDefaultPermissionEntityAction() {
+        return this.defaultPermissionEntityAction;
+    }
+
+    public String getDefaultPermissionOperation() {
+        return this.defaultPermissionOperation;
+    }
+
+    public String getDefaultSelectedStyle() {
+        return this.defaultSelectedStyle;
+    }
+
+    public String getDefaultTitleStyle() {
+        return this.defaultTitleStyle;
+    }
+
+    public String getDefaultTooltipStyle() {
+        return this.defaultTooltipStyle;
+    }
+
+    public String getDefaultWidgetStyle() {
+        return this.defaultWidgetStyle;
+    }
+
+    public FlexibleStringExpander getExtraIndex() {
+        return extraIndex;
+    }
+
+    public String getExtraIndex(Map<String, Object> context) {
+        try {
+            return extraIndex.expandString(context);
+        } catch (Exception ex) {
+            return "";
+        }
+    }
+
+    public String getFillStyle() {
+        return this.fillStyle;
+    }
+
+    public String getId() {
+        return this.id;
+    }
+
+    public String getMenuContainerStyle(Map<String, Object> context) {
+        return menuContainerStyleExdr.expandString(context);
+    }
+
+    public FlexibleStringExpander getMenuContainerStyleExdr() {
+        return menuContainerStyleExdr;
+    }
+
+    public List<ModelMenuItem> getMenuItemList() {
+        return menuItemList;
+    }
+
+    public Map<String, ModelMenuItem> getMenuItemMap() {
+        return menuItemMap;
+    }
+
+    public String getMenuLocation() {
+        return menuLocation;
+    }
+
+    public String getMenuWidth() {
+        return this.menuWidth;
+    }
+
+    public ModelMenuItem getModelMenuItemByName(String name) {
+        return this.menuItemMap.get(name);
+    }
+
+    public String getOrientation() {
+        return this.orientation;
+    }
+
+    public ModelMenu getParentMenu() {
+        return parentMenu;
+    }
+
+    public FlexibleMapAccessor<String> getSelectedMenuItemContextFieldName() {
+        return selectedMenuItemContextFieldName;
+    }
+
+    public String getSelectedMenuItemContextFieldName(Map<String, Object> context) {
+        String menuItemName = this.selectedMenuItemContextFieldName.get(context);
+        if (UtilValidate.isEmpty(menuItemName)) {
+            return this.defaultMenuItemName;
+        }
+        return menuItemName;
+    }
+
+    public String getTarget() {
+        return target;
+    }
+
+    public FlexibleStringExpander getTitle() {
+        return title;
+    }
+
+    public String getTitle(Map<String, Object> context) {
+        return title.expandString(context);
+    }
+
+    public String getTooltip() {
+        return this.tooltip;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public int renderedMenuItemCount(Map<String, Object> context) {
+        int count = 0;
+        for (ModelMenuItem item : this.menuItemList) {
+            if (item.shouldBeRendered(context))
+                count++;
+        }
+        return count;
+    }
+
+    /**
+     * Renders this menu to a String, i.e. in a text format, as defined with the
+     * MenuStringRenderer implementation.
+     *
+     * @param writer The Writer that the menu text will be written to
+     * @param context Map containing the menu context; the following are
+     *   reserved words in this context: parameters (Map), isError (Boolean),
+     *   itemIndex (Integer, for lists only, otherwise null), bshInterpreter,
+     *   menuName (String, optional alternate name for menu, defaults to the
+     *   value of the name attribute)
+     * @param menuStringRenderer An implementation of the MenuStringRenderer
+     *   interface that is responsible for the actual text generation for
+     *   different menu elements; implementing you own makes it possible to
+     *   use the same menu definitions for many types of menu UIs
+     */
+    public void renderMenuString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+            throws IOException {
+        AbstractModelAction.runSubActions(this.actions, context);
+        if ("simple".equals(this.type)) {
+            this.renderSimpleMenuString(writer, context, menuStringRenderer);
+        } else {
+            throw new IllegalArgumentException("The type " + this.getType() + " is not supported for menu with name "
+                    + this.getName());
+        }
+    }
+
+    public void renderSimpleMenuString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+            throws IOException {
+        // render menu open
+        menuStringRenderer.renderMenuOpen(writer, context, this);
+
+        // render formatting wrapper open
+        menuStringRenderer.renderFormatSimpleWrapperOpen(writer, context, this);
+
+        // render each menuItem row, except hidden & ignored rows
+        for (ModelMenuItem item : this.menuItemList) {
+            item.renderMenuItemString(writer, context, menuStringRenderer);
+        }
+        // render formatting wrapper close
+        menuStringRenderer.renderFormatSimpleWrapperClose(writer, context, this);
+
+        // render menu close
+        menuStringRenderer.renderMenuClose(writer, context, this);
+    }
+
+    public void runActions(Map<String, Object> context) {
+        AbstractModelAction.runSubActions(this.actions, context);
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java b/framework/widget/src/org/ofbiz/widget/model/ModelMenuAction.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelMenuAction.java
index 31e3ae4..7351724 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelMenuAction.java
@@ -1,234 +1,232 @@
-/*******************************************************************************
- * 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.ofbiz.widget.menu;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpSession;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.ObjectType;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.widget.ModelActionVisitor;
-import org.ofbiz.widget.*;
-import org.w3c.dom.Element;
-
-/**
- * Abstract menu action.
- */
-public abstract class ModelMenuAction {
-
-    public static final String module = ModelMenuAction.class.getName();
-
-    public static List<ModelAction> readSubActions(ModelMenu modelMenu, Element parentElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
-        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
-        for (Element actionElement : actionElementList) {
-            if ("set".equals(actionElement.getNodeName())) {
-                actions.add(new SetField(modelMenu, actionElement));
-            } else {
-                actions.add(AbstractModelAction.newInstance(modelMenu, actionElement));
-            }
-        }
-        return Collections.unmodifiableList(actions);
-    }
-
-    /**
-     * Models the &lt;set&gt; element.
-     * 
-     * @see <code>widget-common.xsd</code>
-     */
-    @SuppressWarnings("serial")
-    public static class SetField extends AbstractModelAction {
-        private final FlexibleMapAccessor<Object> field;
-        private final FlexibleMapAccessor<Object> fromField;
-        private final FlexibleStringExpander valueExdr;
-        private final FlexibleStringExpander defaultExdr;
-        private final FlexibleStringExpander globalExdr;
-        private final String type;
-        private final String toScope;
-        private final String fromScope;
-
-        public SetField(ModelMenu modelMenu, Element setElement) {
-            super (modelMenu, setElement);
-            this.field = FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
-            this.fromField = FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
-            this.valueExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
-            this.defaultExdr = UtilValidate.isNotEmpty(setElement.getAttribute("default-value")) ? FlexibleStringExpander.getInstance(setElement.getAttribute("default-value")) : null;
-            this.globalExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
-            this.type = setElement.getAttribute("type");
-            this.toScope = setElement.getAttribute("to-scope");
-            this.fromScope = setElement.getAttribute("from-scope");
-            if (!this.fromField.isEmpty() && !this.valueExdr.isEmpty()) {
-                throw new IllegalArgumentException("Cannot specify a from-field [" + setElement.getAttribute("from-field") + "] and a value [" + setElement.getAttribute("value") + "] on the set action in a screen widget");
-            }
-        }
-
-        @SuppressWarnings("rawtypes")
-        @Override
-        public void runAction(Map<String, Object> context) {
-            String globalStr = this.globalExdr.expandString(context);
-            // default to false
-            boolean global = "true".equals(globalStr);
-
-            Object newValue = null;
-            if (this.fromScope != null && this.fromScope.equals("user")) {
-                if (!this.fromField.isEmpty()) {
-                    String originalName = this.fromField.getOriginalName();
-                    String currentWidgetTrail = (String)context.get("_WIDGETTRAIL_");
-                    String newKey = currentWidgetTrail + "|" + originalName;
-                    HttpSession session = (HttpSession)context.get("session");
-                    newValue = session.getAttribute(newKey);
-                    if (Debug.verboseOn()) Debug.logVerbose("In user getting value for field from [" + this.fromField.getOriginalName() + "]: " + newValue, module);
-                } else if (!this.valueExdr.isEmpty()) {
-                    newValue = this.valueExdr.expandString(context);
-                }
-
-            } else if (this.fromScope != null && this.fromScope.equals("application")) {
-                if (!this.fromField.isEmpty()) {
-                    String originalName = this.fromField.getOriginalName();
-                    String currentWidgetTrail = (String)context.get("_WIDGETTRAIL_");
-                    String newKey = currentWidgetTrail + "|" + originalName;
-                    ServletContext servletContext = (ServletContext)context.get("application");
-                    newValue = servletContext.getAttribute(newKey);
-                    if (Debug.verboseOn()) Debug.logVerbose("In application getting value for field from [" + this.fromField.getOriginalName() + "]: " + newValue, module);
-                } else if (!this.valueExdr.isEmpty()) {
-                    newValue = this.valueExdr.expandString(context);
-                }
-
-            } else {
-                if (!this.fromField.isEmpty()) {
-                    newValue = this.fromField.get(context);
-                    if (Debug.verboseOn()) Debug.logVerbose("In screen getting value for field from [" + this.fromField.getOriginalName() + "]: " + newValue, module);
-                } else if (!this.valueExdr.isEmpty()) {
-                    newValue = this.valueExdr.expandString(context);
-                }
-            }
-
-            // If newValue is still empty, use the default value
-               if (this.defaultExdr != null) {
-                   if (ObjectType.isEmpty(newValue)) {
-                    newValue = this.defaultExdr.expandString(context);
-                   }
-            }
-
-            if (UtilValidate.isNotEmpty(this.type)) {
-                if ("NewMap".equals(this.type)) {
-                    newValue = new HashMap();
-                } else if ("NewList".equals(this.type)) {
-                    newValue = new LinkedList();
-                } else {
-                    try {
-                        newValue = ObjectType.simpleTypeConvert(newValue, this.type, null, (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
-                    } catch (GeneralException e) {
-                        String errMsg = "Could not convert field value for the field: [" + this.field.getOriginalName() + "] to the [" + this.type + "] type for the value [" + newValue + "]: " + e.toString();
-                        Debug.logError(e, errMsg, module);
-                        throw new IllegalArgumentException(errMsg);
-                    }
-                }
-            }
-            if (this.toScope != null && this.toScope.equals("user")) {
-                    String originalName = this.field.getOriginalName();
-                    String currentWidgetTrail = (String)context.get("_WIDGETTRAIL_");
-                    String newKey = currentWidgetTrail + "|" + originalName;
-                    HttpSession session = (HttpSession)context.get("session");
-                    session.setAttribute(newKey, newValue);
-                    if (Debug.verboseOn()) Debug.logVerbose("In user setting value for field from [" + this.field.getOriginalName() + "]: " + newValue, module);
-
-            } else if (this.toScope != null && this.toScope.equals("application")) {
-                    String originalName = this.field.getOriginalName();
-                    String currentWidgetTrail = (String)context.get("_WIDGETTRAIL_");
-                    String newKey = currentWidgetTrail + "|" + originalName;
-                    ServletContext servletContext = (ServletContext)context.get("application");
-                    servletContext.setAttribute(newKey, newValue);
-                    if (Debug.verboseOn()) Debug.logVerbose("In application setting value for field from [" + this.field.getOriginalName() + "]: " + newValue, module);
-
-            } else {
-                if (Debug.verboseOn()) Debug.logVerbose("In screen setting field [" + this.field.getOriginalName() + "] to value: " + newValue, module);
-                this.field.put(context, newValue);
-            }
-
-            if (global) {
-                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
-                if (globalCtx != null) {
-                    this.field.put(globalCtx, newValue);
-                }
-            }
-
-            // this is a hack for backward compatibility with the JPublish page object
-            Map<String, Object> page = UtilGenerics.checkMap(context.get("page"));
-            if (page != null) {
-                this.field.put(page, newValue);
-            }
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleMapAccessor<Object> getField() {
-            return field;
-        }
-
-        public FlexibleMapAccessor<Object> getFromField() {
-            return fromField;
-        }
-
-        public FlexibleStringExpander getValueExdr() {
-            return valueExdr;
-        }
-
-        public FlexibleStringExpander getDefaultExdr() {
-            return defaultExdr;
-        }
-
-        public FlexibleStringExpander getGlobalExdr() {
-            return globalExdr;
-        }
-
-        public String getType() {
-            return type;
-        }
-
-        public String getToScope() {
-            return toScope;
-        }
-
-        public String getFromScope() {
-            return fromScope;
-        }
-    }
-}
-
-
-
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.ObjectType;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.w3c.dom.Element;
+
+/**
+ * Abstract menu action.
+ */
+public abstract class ModelMenuAction {
+
+    public static final String module = ModelMenuAction.class.getName();
+
+    public static List<ModelAction> readSubActions(ModelMenu modelMenu, Element parentElement) {
+        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
+        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
+        for (Element actionElement : actionElementList) {
+            if ("set".equals(actionElement.getNodeName())) {
+                actions.add(new SetField(modelMenu, actionElement));
+            } else {
+                actions.add(AbstractModelAction.newInstance(modelMenu, actionElement));
+            }
+        }
+        return Collections.unmodifiableList(actions);
+    }
+
+    /**
+     * Models the &lt;set&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
+    @SuppressWarnings("serial")
+    public static class SetField extends AbstractModelAction {
+        private final FlexibleMapAccessor<Object> field;
+        private final FlexibleMapAccessor<Object> fromField;
+        private final FlexibleStringExpander valueExdr;
+        private final FlexibleStringExpander defaultExdr;
+        private final FlexibleStringExpander globalExdr;
+        private final String type;
+        private final String toScope;
+        private final String fromScope;
+
+        public SetField(ModelMenu modelMenu, Element setElement) {
+            super (modelMenu, setElement);
+            this.field = FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
+            this.fromField = FlexibleMapAccessor.getInstance(setElement.getAttribute("from-field"));
+            this.valueExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("value"));
+            this.defaultExdr = UtilValidate.isNotEmpty(setElement.getAttribute("default-value")) ? FlexibleStringExpander.getInstance(setElement.getAttribute("default-value")) : null;
+            this.globalExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
+            this.type = setElement.getAttribute("type");
+            this.toScope = setElement.getAttribute("to-scope");
+            this.fromScope = setElement.getAttribute("from-scope");
+            if (!this.fromField.isEmpty() && !this.valueExdr.isEmpty()) {
+                throw new IllegalArgumentException("Cannot specify a from-field [" + setElement.getAttribute("from-field") + "] and a value [" + setElement.getAttribute("value") + "] on the set action in a screen widget");
+            }
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Override
+        public void runAction(Map<String, Object> context) {
+            String globalStr = this.globalExdr.expandString(context);
+            // default to false
+            boolean global = "true".equals(globalStr);
+
+            Object newValue = null;
+            if (this.fromScope != null && this.fromScope.equals("user")) {
+                if (!this.fromField.isEmpty()) {
+                    String originalName = this.fromField.getOriginalName();
+                    String currentWidgetTrail = (String)context.get("_WIDGETTRAIL_");
+                    String newKey = currentWidgetTrail + "|" + originalName;
+                    HttpSession session = (HttpSession)context.get("session");
+                    newValue = session.getAttribute(newKey);
+                    if (Debug.verboseOn()) Debug.logVerbose("In user getting value for field from [" + this.fromField.getOriginalName() + "]: " + newValue, module);
+                } else if (!this.valueExdr.isEmpty()) {
+                    newValue = this.valueExdr.expandString(context);
+                }
+
+            } else if (this.fromScope != null && this.fromScope.equals("application")) {
+                if (!this.fromField.isEmpty()) {
+                    String originalName = this.fromField.getOriginalName();
+                    String currentWidgetTrail = (String)context.get("_WIDGETTRAIL_");
+                    String newKey = currentWidgetTrail + "|" + originalName;
+                    ServletContext servletContext = (ServletContext)context.get("application");
+                    newValue = servletContext.getAttribute(newKey);
+                    if (Debug.verboseOn()) Debug.logVerbose("In application getting value for field from [" + this.fromField.getOriginalName() + "]: " + newValue, module);
+                } else if (!this.valueExdr.isEmpty()) {
+                    newValue = this.valueExdr.expandString(context);
+                }
+
+            } else {
+                if (!this.fromField.isEmpty()) {
+                    newValue = this.fromField.get(context);
+                    if (Debug.verboseOn()) Debug.logVerbose("In screen getting value for field from [" + this.fromField.getOriginalName() + "]: " + newValue, module);
+                } else if (!this.valueExdr.isEmpty()) {
+                    newValue = this.valueExdr.expandString(context);
+                }
+            }
+
+            // If newValue is still empty, use the default value
+               if (this.defaultExdr != null) {
+                   if (ObjectType.isEmpty(newValue)) {
+                    newValue = this.defaultExdr.expandString(context);
+                   }
+            }
+
+            if (UtilValidate.isNotEmpty(this.type)) {
+                if ("NewMap".equals(this.type)) {
+                    newValue = new HashMap();
+                } else if ("NewList".equals(this.type)) {
+                    newValue = new LinkedList();
+                } else {
+                    try {
+                        newValue = ObjectType.simpleTypeConvert(newValue, this.type, null, (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true);
+                    } catch (GeneralException e) {
+                        String errMsg = "Could not convert field value for the field: [" + this.field.getOriginalName() + "] to the [" + this.type + "] type for the value [" + newValue + "]: " + e.toString();
+                        Debug.logError(e, errMsg, module);
+                        throw new IllegalArgumentException(errMsg);
+                    }
+                }
+            }
+            if (this.toScope != null && this.toScope.equals("user")) {
+                    String originalName = this.field.getOriginalName();
+                    String currentWidgetTrail = (String)context.get("_WIDGETTRAIL_");
+                    String newKey = currentWidgetTrail + "|" + originalName;
+                    HttpSession session = (HttpSession)context.get("session");
+                    session.setAttribute(newKey, newValue);
+                    if (Debug.verboseOn()) Debug.logVerbose("In user setting value for field from [" + this.field.getOriginalName() + "]: " + newValue, module);
+
+            } else if (this.toScope != null && this.toScope.equals("application")) {
+                    String originalName = this.field.getOriginalName();
+                    String currentWidgetTrail = (String)context.get("_WIDGETTRAIL_");
+                    String newKey = currentWidgetTrail + "|" + originalName;
+                    ServletContext servletContext = (ServletContext)context.get("application");
+                    servletContext.setAttribute(newKey, newValue);
+                    if (Debug.verboseOn()) Debug.logVerbose("In application setting value for field from [" + this.field.getOriginalName() + "]: " + newValue, module);
+
+            } else {
+                if (Debug.verboseOn()) Debug.logVerbose("In screen setting field [" + this.field.getOriginalName() + "] to value: " + newValue, module);
+                this.field.put(context, newValue);
+            }
+
+            if (global) {
+                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
+                if (globalCtx != null) {
+                    this.field.put(globalCtx, newValue);
+                }
+            }
+
+            // this is a hack for backward compatibility with the JPublish page object
+            Map<String, Object> page = UtilGenerics.checkMap(context.get("page"));
+            if (page != null) {
+                this.field.put(page, newValue);
+            }
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleMapAccessor<Object> getField() {
+            return field;
+        }
+
+        public FlexibleMapAccessor<Object> getFromField() {
+            return fromField;
+        }
+
+        public FlexibleStringExpander getValueExdr() {
+            return valueExdr;
+        }
+
+        public FlexibleStringExpander getDefaultExdr() {
+            return defaultExdr;
+        }
+
+        public FlexibleStringExpander getGlobalExdr() {
+            return globalExdr;
+        }
+
+        public String getType() {
+            return type;
+        }
+
+        public String getToScope() {
+            return toScope;
+        }
+
+        public String getFromScope() {
+            return fromScope;
+        }
+    }
+}
+
+
+
diff --git a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java b/framework/widget/src/org/ofbiz/widget/model/ModelMenuCondition.java
similarity index 95%
rename from framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelMenuCondition.java
index bd0e9f1..b9aec8c 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelMenuCondition.java
@@ -1,70 +1,68 @@
-/*******************************************************************************
- * 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.ofbiz.widget.menu;
-
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.widget.AbstractModelCondition;
-import org.ofbiz.widget.ModelCondition;
-import org.w3c.dom.Element;
-
-/**
- * Models the &lt;condition&gt; element.
- * 
- * @see <code>widget-menu.xsd</code>
- */
-public final class ModelMenuCondition {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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.
-     * 
-     * 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 = ModelMenuCondition.class.getName();
-
-    private final FlexibleStringExpander passStyleExdr;
-    private final FlexibleStringExpander failStyleExdr;
-    private final ModelCondition condition;
-
-    public ModelMenuCondition(ModelMenuItem modelMenuItem, Element conditionElement) {
-        this.passStyleExdr = FlexibleStringExpander.getInstance(conditionElement.getAttribute("pass-style"));
-        this.failStyleExdr = FlexibleStringExpander.getInstance(conditionElement.getAttribute("disabled-style"));
-        this.condition = AbstractModelCondition.DEFAULT_CONDITION_FACTORY.newInstance(modelMenuItem, conditionElement);
-    }
-
-    public ModelCondition getCondition() {
-        return condition;
-    }
-
-    public FlexibleStringExpander getFailStyleExdr() {
-        return failStyleExdr;
-    }
-
-    public FlexibleStringExpander getPassStyleExdr() {
-        return passStyleExdr;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.w3c.dom.Element;
+
+/**
+ * Models the &lt;condition&gt; element.
+ * 
+ * @see <code>widget-menu.xsd</code>
+ */
+public final class ModelMenuCondition {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     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.
+     * 
+     * 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 = ModelMenuCondition.class.getName();
+
+    private final FlexibleStringExpander passStyleExdr;
+    private final FlexibleStringExpander failStyleExdr;
+    private final ModelCondition condition;
+
+    public ModelMenuCondition(ModelMenuItem modelMenuItem, Element conditionElement) {
+        this.passStyleExdr = FlexibleStringExpander.getInstance(conditionElement.getAttribute("pass-style"));
+        this.failStyleExdr = FlexibleStringExpander.getInstance(conditionElement.getAttribute("disabled-style"));
+        this.condition = AbstractModelCondition.DEFAULT_CONDITION_FACTORY.newInstance(modelMenuItem, conditionElement);
+    }
+
+    public ModelCondition getCondition() {
+        return condition;
+    }
+
+    public FlexibleStringExpander getFailStyleExdr() {
+        return failStyleExdr;
+    }
+
+    public FlexibleStringExpander getPassStyleExdr() {
+        return passStyleExdr;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java b/framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java
index 2ddc1e4..2ee5b5a 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java
@@ -1,672 +1,669 @@
-/*******************************************************************************
- * 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.ofbiz.widget.menu;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.widget.AbstractModelAction;
-import org.ofbiz.widget.CommonWidgetModels.AutoEntityParameters;
-import org.ofbiz.widget.CommonWidgetModels.AutoServiceParameters;
-import org.ofbiz.widget.CommonWidgetModels.Image;
-import org.ofbiz.widget.CommonWidgetModels.Link;
-import org.ofbiz.widget.CommonWidgetModels.Parameter;
-import org.ofbiz.widget.ModelAction;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.PortalPageWorker;
-import org.w3c.dom.Element;
-
-/**
- * Models the &lt;menu-item&gt; element.
- * 
- * @see <code>widget-menu.xsd</code>
- */
-@SuppressWarnings("serial")
-public class ModelMenuItem extends ModelWidget {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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.
-     * 
-     * 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 = ModelMenuItem.class.getName();
-
-    private final List<ModelAction> actions;
-    private final String align;
-    private final String alignStyle;
-    private final FlexibleStringExpander associatedContentId;
-    private final String cellWidth;
-    private final ModelMenuCondition condition;
-    private final String disabledTitleStyle;
-    private final String disableIfEmpty;
-    private final String entityName;
-    private final Boolean hideIfSelected;
-    private final MenuLink link;
-    private final List<ModelMenuItem> menuItemList;
-    private final ModelMenu modelMenu;
-    private final String overrideName;
-    private final ModelMenuItem parentMenuItem;
-    private final FlexibleStringExpander parentPortalPageId;
-    private final Integer position;
-    private final String selectedStyle;
-    private final String subMenu;
-    private final FlexibleStringExpander title;
-    private final String titleStyle;
-    private final FlexibleStringExpander tooltip;
-    private final String tooltipStyle;
-    private final String widgetStyle;
-
-    // ===== CONSTRUCTORS =====
-
-    public ModelMenuItem(Element menuItemElement, ModelMenu modelMenu) {
-        this(menuItemElement, modelMenu, null);
-    }
-
-    private ModelMenuItem(Element menuItemElement, ModelMenu modelMenu, ModelMenuItem parentMenuItem) {
-        super(menuItemElement);
-        this.modelMenu = modelMenu;
-        this.parentMenuItem = parentMenuItem;
-        this.entityName = menuItemElement.getAttribute("entity-name");
-        this.title = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("title"));
-        this.tooltip = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("tooltip"));
-        this.parentPortalPageId = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("parent-portal-page-value"));
-        this.titleStyle = menuItemElement.getAttribute("title-style");
-        this.disabledTitleStyle = menuItemElement.getAttribute("disabled-title-style");
-        this.widgetStyle = menuItemElement.getAttribute("widget-style");
-        this.tooltipStyle = menuItemElement.getAttribute("tooltip-style");
-        this.selectedStyle = menuItemElement.getAttribute("selected-style");
-        String hideIfSelected = menuItemElement.getAttribute("hide-if-selected");
-        if (!hideIfSelected.isEmpty())
-            if (hideIfSelected.equalsIgnoreCase("true"))
-                this.hideIfSelected = Boolean.TRUE;
-            else
-                this.hideIfSelected = Boolean.FALSE;
-        else
-            this.hideIfSelected = null;
-        this.disableIfEmpty = menuItemElement.getAttribute("disable-if-empty");
-        this.align = menuItemElement.getAttribute("align");
-        this.alignStyle = menuItemElement.getAttribute("align-style");
-        Integer position = null;
-        String positionStr = menuItemElement.getAttribute("position");
-        if (!positionStr.isEmpty()) {
-            try {
-                position = Integer.valueOf(positionStr);
-            } catch (Exception e) {
-                Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr
-                        + "], using the default of the menu renderer", module);
-                position = null;
-            }
-        }
-        this.position = position;
-        this.associatedContentId = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("associated-content-id"));
-        this.cellWidth = menuItemElement.getAttribute("cell-width");
-        this.subMenu = menuItemElement.getAttribute("sub-menu");
-        Element linkElement = UtilXml.firstChildElement(menuItemElement, "link");
-        if (linkElement != null) {
-            this.link = new MenuLink(linkElement, this);
-        } else {
-            this.link = null;
-        }
-        // read in add item defs, add/override one by one using the menuItemList and menuItemMap
-        List<? extends Element> itemElements = UtilXml.childElementList(menuItemElement, "menu-item");
-        if (!itemElements.isEmpty()) {
-            ArrayList<ModelMenuItem> menuItemList = new ArrayList<ModelMenuItem>();
-            Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>();
-            for (Element itemElement : itemElements) {
-                ModelMenuItem modelMenuItem = new ModelMenuItem(itemElement, modelMenu, this);
-                addUpdateMenuItem(modelMenuItem, menuItemList, menuItemMap);
-            }
-            menuItemList.trimToSize();
-            this.menuItemList = Collections.unmodifiableList(menuItemList);
-        } else {
-            this.menuItemList = Collections.emptyList();
-        }
-        // read condition under the "condition" element
-        Element conditionElement = UtilXml.firstChildElement(menuItemElement, "condition");
-        if (conditionElement != null) {
-            conditionElement = UtilXml.firstChildElement(conditionElement);
-            this.condition = new ModelMenuCondition(this, conditionElement);
-        } else {
-            this.condition = null;
-        }
-        // read all actions under the "actions" element
-        Element actionsElement = UtilXml.firstChildElement(conditionElement, "actions");
-        if (actionsElement != null) {
-            this.actions = AbstractModelAction.readSubActions(this, actionsElement);
-        } else {
-            this.actions = Collections.emptyList();
-        }
-        this.overrideName = "";
-    }
-
-    // Portal constructor
-    private ModelMenuItem(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) {
-        super(portalPage.getString("portalPageId"));
-        this.actions = Collections.emptyList();
-        this.align = "";
-        this.alignStyle = "";
-        this.associatedContentId = FlexibleStringExpander.getInstance("");
-        this.cellWidth = "";
-        this.condition = null;
-        this.disabledTitleStyle = "";
-        this.disableIfEmpty = "";
-        this.entityName = "";
-        this.hideIfSelected = null;
-        this.menuItemList = Collections.emptyList();
-        this.overrideName = "";
-        this.parentMenuItem = null;
-        this.parentPortalPageId = FlexibleStringExpander.getInstance(portalPage.getString("parentPortalPageId"));
-        this.position = null;
-        this.selectedStyle = "";
-        this.subMenu = "";
-        this.title = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale));
-        this.titleStyle = "";
-        this.tooltip = FlexibleStringExpander.getInstance("");
-        this.tooltipStyle = "";
-        this.widgetStyle = "";
-        this.link = new MenuLink(portalPage, parentMenuItem, locale);
-        this.modelMenu = parentMenuItem.modelMenu;
-    }
-
-    // Merge constructor
-    private ModelMenuItem(ModelMenuItem existingMenuItem, ModelMenuItem overrideMenuItem) {
-        super(existingMenuItem.getName());
-        this.modelMenu = existingMenuItem.modelMenu;
-        if (UtilValidate.isNotEmpty(overrideMenuItem.getName())) {
-            this.overrideName = overrideMenuItem.getName();
-        } else {
-            this.overrideName = existingMenuItem.getName();
-        }
-        if (UtilValidate.isNotEmpty(overrideMenuItem.entityName)) {
-            this.entityName = overrideMenuItem.entityName;
-        } else {
-            this.entityName = existingMenuItem.entityName;
-        }
-        if (UtilValidate.isNotEmpty(overrideMenuItem.parentPortalPageId)) {
-            this.parentPortalPageId = overrideMenuItem.parentPortalPageId;
-        } else {
-            this.parentPortalPageId = existingMenuItem.parentPortalPageId;
-        }
-        if (UtilValidate.isNotEmpty(overrideMenuItem.title)) {
-            this.title = overrideMenuItem.title;
-        } else {
-            this.title = existingMenuItem.title;
-        }
-        if (UtilValidate.isNotEmpty(overrideMenuItem.tooltip)) {
-            this.tooltip = overrideMenuItem.tooltip;
-        } else {
-            this.tooltip = existingMenuItem.tooltip;
-        }
-        if (UtilValidate.isNotEmpty(overrideMenuItem.titleStyle)) {
-            this.titleStyle = overrideMenuItem.titleStyle;
-        } else {
-            this.titleStyle = existingMenuItem.titleStyle;
-        }
-        if (UtilValidate.isNotEmpty(overrideMenuItem.selectedStyle)) {
-            this.selectedStyle = overrideMenuItem.selectedStyle;
-        } else {
-            this.selectedStyle = existingMenuItem.selectedStyle;
-        }
-        if (UtilValidate.isNotEmpty(overrideMenuItem.widgetStyle)) {
-            this.widgetStyle = overrideMenuItem.widgetStyle;
-        } else {
-            this.widgetStyle = existingMenuItem.widgetStyle;
-        }
-        if (overrideMenuItem.position != null) {
-            this.position = overrideMenuItem.position;
-        } else {
-            this.position = existingMenuItem.position;
-        }
-        this.actions = existingMenuItem.actions;
-        this.align = existingMenuItem.align;
-        this.alignStyle = existingMenuItem.alignStyle;
-        this.associatedContentId = existingMenuItem.associatedContentId;
-        this.cellWidth = existingMenuItem.cellWidth;
-        this.condition = existingMenuItem.condition;
-        this.disabledTitleStyle = existingMenuItem.disabledTitleStyle;
-        this.disableIfEmpty = existingMenuItem.disableIfEmpty;
-        this.hideIfSelected = existingMenuItem.hideIfSelected;
-        this.menuItemList = existingMenuItem.menuItemList;
-        this.parentMenuItem = existingMenuItem.parentMenuItem;
-        this.subMenu = existingMenuItem.subMenu;
-        this.tooltipStyle = existingMenuItem.tooltipStyle;
-        this.link = existingMenuItem.link;
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
-    }
-
-    private void addUpdateMenuItem(ModelMenuItem modelMenuItem, List<ModelMenuItem> menuItemList,
-            Map<String, ModelMenuItem> menuItemMap) {
-        ModelMenuItem existingMenuItem = menuItemMap.get(modelMenuItem.getName());
-        if (existingMenuItem != null) {
-            // does exist, update the item by doing a merge/override
-            ModelMenuItem mergedMenuItem = existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem);
-            int existingItemIndex = menuItemList.indexOf(existingMenuItem);
-            menuItemList.set(existingItemIndex, mergedMenuItem);
-            menuItemMap.put(modelMenuItem.getName(), mergedMenuItem);
-        } else {
-            // does not exist, add to List and Map
-            menuItemList.add(modelMenuItem);
-            menuItemMap.put(modelMenuItem.getName(), modelMenuItem);
-        }
-    }
-
-    public List<ModelAction> getActions() {
-        return actions;
-    }
-
-    public String getAlign() {
-        if (!this.align.isEmpty()) {
-            return this.align;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getAlign();
-        } else {
-            return this.modelMenu.getDefaultAlign();
-        }
-    }
-
-    public String getAlignStyle() {
-        if (!this.alignStyle.isEmpty()) {
-            return this.alignStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getAlignStyle();
-        } else {
-            return this.modelMenu.getDefaultAlignStyle();
-        }
-    }
-
-    public FlexibleStringExpander getAssociatedContentId() {
-        return associatedContentId;
-    }
-
-    public String getAssociatedContentId(Map<String, Object> context) {
-        String retStr = null;
-        if (this.associatedContentId != null) {
-            retStr = associatedContentId.expandString(context);
-        }
-        if (retStr.isEmpty()) {
-            retStr = this.modelMenu.getDefaultAssociatedContentId(context);
-        }
-        return retStr;
-    }
-
-    public String getCellWidth() {
-        if (!this.cellWidth.isEmpty()) {
-            return this.cellWidth;
-        } else {
-            return this.modelMenu.getDefaultCellWidth();
-        }
-    }
-
-    public ModelMenuCondition getCondition() {
-        return condition;
-    }
-
-    public String getDisabledTitleStyle() {
-        if (!this.disabledTitleStyle.isEmpty()) {
-            return this.disabledTitleStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getDisabledTitleStyle();
-        } else {
-            return this.modelMenu.getDefaultDisabledTitleStyle();
-        }
-    }
-
-    public String getDisableIfEmpty() {
-        return this.disableIfEmpty;
-    }
-
-    public String getEntityName() {
-        if (!this.entityName.isEmpty()) {
-            return this.entityName;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getEntityName();
-        } else {
-            return this.modelMenu.getDefaultEntityName();
-        }
-    }
-
-    public Boolean getHideIfSelected() {
-        if (hideIfSelected != null) {
-            return this.hideIfSelected;
-        } else {
-            return this.modelMenu.getDefaultHideIfSelected();
-        }
-    }
-
-    public MenuLink getLink() {
-        return this.link;
-    }
-
-    public List<ModelMenuItem> getMenuItemList() {
-        return menuItemList;
-    }
-
-    public ModelMenu getModelMenu() {
-        return modelMenu;
-    }
-
-    @Override
-    public String getName() {
-        if (!this.overrideName.isEmpty()) {
-            return this.overrideName;
-        }
-        return super.getName();
-    }
-
-    public String getOverrideName() {
-        return overrideName;
-    }
-
-    public ModelMenuItem getParentMenuItem() {
-        return parentMenuItem;
-    }
-
-    public FlexibleStringExpander getParentPortalPageId() {
-        return parentPortalPageId;
-    }
-
-    public String getParentPortalPageId(Map<String, Object> context) {
-        return this.parentPortalPageId.expandString(context);
-    }
-
-    public int getPosition() {
-        if (this.position == null) {
-            return 1;
-        } else {
-            return position.intValue();
-        }
-    }
-
-    public String getSelectedStyle() {
-        if (!this.selectedStyle.isEmpty()) {
-            return this.selectedStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getSelectedStyle();
-        } else {
-            return this.modelMenu.getDefaultSelectedStyle();
-        }
-    }
-
-    public String getSubMenu() {
-        return subMenu;
-    }
-
-    public FlexibleStringExpander getTitle() {
-        return title;
-    }
-
-    public String getTitle(Map<String, Object> context) {
-        return title.expandString(context);
-    }
-
-    public String getTitleStyle() {
-        if (!this.titleStyle.isEmpty()) {
-            return this.titleStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getTitleStyle();
-        } else {
-            return this.modelMenu.getDefaultTitleStyle();
-        }
-    }
-
-    public FlexibleStringExpander getTooltip() {
-        return tooltip;
-    }
-
-    public String getTooltip(Map<String, Object> context) {
-        if (UtilValidate.isNotEmpty(tooltip)) {
-            return tooltip.expandString(context);
-        } else {
-            return "";
-        }
-    }
-
-    public String getTooltipStyle() {
-        if (!this.tooltipStyle.isEmpty()) {
-            return this.tooltipStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getTooltipStyle();
-        } else {
-            return this.modelMenu.getDefaultTooltipStyle();
-        }
-    }
-
-    public String getWidgetStyle() {
-        if (!this.widgetStyle.isEmpty()) {
-            return this.widgetStyle;
-        } else if (parentMenuItem != null) {
-            return parentMenuItem.getWidgetStyle();
-        } else {
-            return this.modelMenu.getDefaultWidgetStyle();
-        }
-    }
-
-    public boolean isSelected(Map<String, Object> context) {
-        return getName().equals(modelMenu.getSelectedMenuItemContextFieldName(context));
-    }
-
-    public ModelMenuItem mergeOverrideModelMenuItem(ModelMenuItem overrideMenuItem) {
-        return new ModelMenuItem(this, overrideMenuItem);
-    }
-
-    public void renderMenuItemString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
-            throws IOException {
-        if (shouldBeRendered(context)) {
-            AbstractModelAction.runSubActions(actions, context);
-            String parentPortalPageId = getParentPortalPageId(context);
-            if (UtilValidate.isNotEmpty(parentPortalPageId)) {
-                List<GenericValue> portalPages = PortalPageWorker.getPortalPages(parentPortalPageId, context);
-                if (UtilValidate.isNotEmpty(portalPages)) {
-                    Locale locale = (Locale) context.get("locale");
-                    for (GenericValue portalPage : portalPages) {
-                        if (UtilValidate.isNotEmpty(portalPage.getString("portalPageName"))) {
-                            ModelMenuItem localItem = new ModelMenuItem(portalPage, this, locale);
-                            menuStringRenderer.renderMenuItem(writer, context, localItem);
-                        }
-                    }
-                }
-            } else {
-                menuStringRenderer.renderMenuItem(writer, context, this);
-            }
-        }
-    }
-
-    public boolean shouldBeRendered(Map<String, Object> context) {
-        if (this.condition != null) {
-            return this.condition.getCondition().eval(context);
-        }
-        return true;
-    }
-
-    public static class MenuLink {
-        private final ModelMenuItem linkMenuItem;
-        private final Link link;
-
-        public MenuLink(Element linkElement, ModelMenuItem parentMenuItem) {
-            this.linkMenuItem = parentMenuItem;
-            if (linkElement.getAttribute("text").isEmpty()) {
-                linkElement.setAttribute("text", parentMenuItem.getTitle().getOriginal());
-            }
-            if (linkElement.getAttribute("style").isEmpty()) {
-                linkElement.setAttribute("style", parentMenuItem.getWidgetStyle());
-            }
-            this.link = new Link(linkElement);
-        }
-
-        public MenuLink(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) {
-            this.linkMenuItem = parentMenuItem;
-            ArrayList<Parameter> parameterList = new ArrayList<Parameter>();
-            if (parentMenuItem.link != null) {
-                parameterList.addAll(parentMenuItem.link.getParameterList());
-            }
-            parameterList.add(new Parameter("portalPageId", portalPage.getString("portalPageId"), false));
-            parameterList.add(new Parameter("parentPortalPageId", portalPage.getString("parentPortalPageId"), false));
-            String target = "showPortalPage";
-            if (parentMenuItem.link != null) {
-                target= "";
-            }
-            this.link = new Link(portalPage, parameterList, target, locale);
-        }
-
-        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) {
-            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 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 ModelMenuItem getLinkMenuItem() {
-            return linkMenuItem;
-        }
-
-        public Link getLink() {
-            return link;
-        }
-
-        public void renderLinkString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
-                throws IOException {
-            menuStringRenderer.renderLink(writer, context, this);
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.widget.model.CommonWidgetModels.AutoEntityParameters;
+import org.ofbiz.widget.model.CommonWidgetModels.AutoServiceParameters;
+import org.ofbiz.widget.model.CommonWidgetModels.Image;
+import org.ofbiz.widget.model.CommonWidgetModels.Link;
+import org.ofbiz.widget.model.CommonWidgetModels.Parameter;
+import org.ofbiz.widget.portal.PortalPageWorker;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+import org.w3c.dom.Element;
+
+/**
+ * Models the &lt;menu-item&gt; element.
+ * 
+ * @see <code>widget-menu.xsd</code>
+ */
+@SuppressWarnings("serial")
+public class ModelMenuItem extends ModelWidget {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     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.
+     * 
+     * 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 = ModelMenuItem.class.getName();
+
+    private final List<ModelAction> actions;
+    private final String align;
+    private final String alignStyle;
+    private final FlexibleStringExpander associatedContentId;
+    private final String cellWidth;
+    private final ModelMenuCondition condition;
+    private final String disabledTitleStyle;
+    private final String disableIfEmpty;
+    private final String entityName;
+    private final Boolean hideIfSelected;
+    private final MenuLink link;
+    private final List<ModelMenuItem> menuItemList;
+    private final ModelMenu modelMenu;
+    private final String overrideName;
+    private final ModelMenuItem parentMenuItem;
+    private final FlexibleStringExpander parentPortalPageId;
+    private final Integer position;
+    private final String selectedStyle;
+    private final String subMenu;
+    private final FlexibleStringExpander title;
+    private final String titleStyle;
+    private final FlexibleStringExpander tooltip;
+    private final String tooltipStyle;
+    private final String widgetStyle;
+
+    // ===== CONSTRUCTORS =====
+
+    public ModelMenuItem(Element menuItemElement, ModelMenu modelMenu) {
+        this(menuItemElement, modelMenu, null);
+    }
+
+    private ModelMenuItem(Element menuItemElement, ModelMenu modelMenu, ModelMenuItem parentMenuItem) {
+        super(menuItemElement);
+        this.modelMenu = modelMenu;
+        this.parentMenuItem = parentMenuItem;
+        this.entityName = menuItemElement.getAttribute("entity-name");
+        this.title = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("title"));
+        this.tooltip = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("tooltip"));
+        this.parentPortalPageId = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("parent-portal-page-value"));
+        this.titleStyle = menuItemElement.getAttribute("title-style");
+        this.disabledTitleStyle = menuItemElement.getAttribute("disabled-title-style");
+        this.widgetStyle = menuItemElement.getAttribute("widget-style");
+        this.tooltipStyle = menuItemElement.getAttribute("tooltip-style");
+        this.selectedStyle = menuItemElement.getAttribute("selected-style");
+        String hideIfSelected = menuItemElement.getAttribute("hide-if-selected");
+        if (!hideIfSelected.isEmpty())
+            if (hideIfSelected.equalsIgnoreCase("true"))
+                this.hideIfSelected = Boolean.TRUE;
+            else
+                this.hideIfSelected = Boolean.FALSE;
+        else
+            this.hideIfSelected = null;
+        this.disableIfEmpty = menuItemElement.getAttribute("disable-if-empty");
+        this.align = menuItemElement.getAttribute("align");
+        this.alignStyle = menuItemElement.getAttribute("align-style");
+        Integer position = null;
+        String positionStr = menuItemElement.getAttribute("position");
+        if (!positionStr.isEmpty()) {
+            try {
+                position = Integer.valueOf(positionStr);
+            } catch (Exception e) {
+                Debug.logError(e, "Could not convert position attribute of the field element to an integer: [" + positionStr
+                        + "], using the default of the menu renderer", module);
+                position = null;
+            }
+        }
+        this.position = position;
+        this.associatedContentId = FlexibleStringExpander.getInstance(menuItemElement.getAttribute("associated-content-id"));
+        this.cellWidth = menuItemElement.getAttribute("cell-width");
+        this.subMenu = menuItemElement.getAttribute("sub-menu");
+        Element linkElement = UtilXml.firstChildElement(menuItemElement, "link");
+        if (linkElement != null) {
+            this.link = new MenuLink(linkElement, this);
+        } else {
+            this.link = null;
+        }
+        // read in add item defs, add/override one by one using the menuItemList and menuItemMap
+        List<? extends Element> itemElements = UtilXml.childElementList(menuItemElement, "menu-item");
+        if (!itemElements.isEmpty()) {
+            ArrayList<ModelMenuItem> menuItemList = new ArrayList<ModelMenuItem>();
+            Map<String, ModelMenuItem> menuItemMap = new HashMap<String, ModelMenuItem>();
+            for (Element itemElement : itemElements) {
+                ModelMenuItem modelMenuItem = new ModelMenuItem(itemElement, modelMenu, this);
+                addUpdateMenuItem(modelMenuItem, menuItemList, menuItemMap);
+            }
+            menuItemList.trimToSize();
+            this.menuItemList = Collections.unmodifiableList(menuItemList);
+        } else {
+            this.menuItemList = Collections.emptyList();
+        }
+        // read condition under the "condition" element
+        Element conditionElement = UtilXml.firstChildElement(menuItemElement, "condition");
+        if (conditionElement != null) {
+            conditionElement = UtilXml.firstChildElement(conditionElement);
+            this.condition = new ModelMenuCondition(this, conditionElement);
+        } else {
+            this.condition = null;
+        }
+        // read all actions under the "actions" element
+        Element actionsElement = UtilXml.firstChildElement(conditionElement, "actions");
+        if (actionsElement != null) {
+            this.actions = AbstractModelAction.readSubActions(this, actionsElement);
+        } else {
+            this.actions = Collections.emptyList();
+        }
+        this.overrideName = "";
+    }
+
+    // Portal constructor
+    private ModelMenuItem(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) {
+        super(portalPage.getString("portalPageId"));
+        this.actions = Collections.emptyList();
+        this.align = "";
+        this.alignStyle = "";
+        this.associatedContentId = FlexibleStringExpander.getInstance("");
+        this.cellWidth = "";
+        this.condition = null;
+        this.disabledTitleStyle = "";
+        this.disableIfEmpty = "";
+        this.entityName = "";
+        this.hideIfSelected = null;
+        this.menuItemList = Collections.emptyList();
+        this.overrideName = "";
+        this.parentMenuItem = null;
+        this.parentPortalPageId = FlexibleStringExpander.getInstance(portalPage.getString("parentPortalPageId"));
+        this.position = null;
+        this.selectedStyle = "";
+        this.subMenu = "";
+        this.title = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale));
+        this.titleStyle = "";
+        this.tooltip = FlexibleStringExpander.getInstance("");
+        this.tooltipStyle = "";
+        this.widgetStyle = "";
+        this.link = new MenuLink(portalPage, parentMenuItem, locale);
+        this.modelMenu = parentMenuItem.modelMenu;
+    }
+
+    // Merge constructor
+    private ModelMenuItem(ModelMenuItem existingMenuItem, ModelMenuItem overrideMenuItem) {
+        super(existingMenuItem.getName());
+        this.modelMenu = existingMenuItem.modelMenu;
+        if (UtilValidate.isNotEmpty(overrideMenuItem.getName())) {
+            this.overrideName = overrideMenuItem.getName();
+        } else {
+            this.overrideName = existingMenuItem.getName();
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.entityName)) {
+            this.entityName = overrideMenuItem.entityName;
+        } else {
+            this.entityName = existingMenuItem.entityName;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.parentPortalPageId)) {
+            this.parentPortalPageId = overrideMenuItem.parentPortalPageId;
+        } else {
+            this.parentPortalPageId = existingMenuItem.parentPortalPageId;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.title)) {
+            this.title = overrideMenuItem.title;
+        } else {
+            this.title = existingMenuItem.title;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.tooltip)) {
+            this.tooltip = overrideMenuItem.tooltip;
+        } else {
+            this.tooltip = existingMenuItem.tooltip;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.titleStyle)) {
+            this.titleStyle = overrideMenuItem.titleStyle;
+        } else {
+            this.titleStyle = existingMenuItem.titleStyle;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.selectedStyle)) {
+            this.selectedStyle = overrideMenuItem.selectedStyle;
+        } else {
+            this.selectedStyle = existingMenuItem.selectedStyle;
+        }
+        if (UtilValidate.isNotEmpty(overrideMenuItem.widgetStyle)) {
+            this.widgetStyle = overrideMenuItem.widgetStyle;
+        } else {
+            this.widgetStyle = existingMenuItem.widgetStyle;
+        }
+        if (overrideMenuItem.position != null) {
+            this.position = overrideMenuItem.position;
+        } else {
+            this.position = existingMenuItem.position;
+        }
+        this.actions = existingMenuItem.actions;
+        this.align = existingMenuItem.align;
+        this.alignStyle = existingMenuItem.alignStyle;
+        this.associatedContentId = existingMenuItem.associatedContentId;
+        this.cellWidth = existingMenuItem.cellWidth;
+        this.condition = existingMenuItem.condition;
+        this.disabledTitleStyle = existingMenuItem.disabledTitleStyle;
+        this.disableIfEmpty = existingMenuItem.disableIfEmpty;
+        this.hideIfSelected = existingMenuItem.hideIfSelected;
+        this.menuItemList = existingMenuItem.menuItemList;
+        this.parentMenuItem = existingMenuItem.parentMenuItem;
+        this.subMenu = existingMenuItem.subMenu;
+        this.tooltipStyle = existingMenuItem.tooltipStyle;
+        this.link = existingMenuItem.link;
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+
+    private void addUpdateMenuItem(ModelMenuItem modelMenuItem, List<ModelMenuItem> menuItemList,
+            Map<String, ModelMenuItem> menuItemMap) {
+        ModelMenuItem existingMenuItem = menuItemMap.get(modelMenuItem.getName());
+        if (existingMenuItem != null) {
+            // does exist, update the item by doing a merge/override
+            ModelMenuItem mergedMenuItem = existingMenuItem.mergeOverrideModelMenuItem(modelMenuItem);
+            int existingItemIndex = menuItemList.indexOf(existingMenuItem);
+            menuItemList.set(existingItemIndex, mergedMenuItem);
+            menuItemMap.put(modelMenuItem.getName(), mergedMenuItem);
+        } else {
+            // does not exist, add to List and Map
+            menuItemList.add(modelMenuItem);
+            menuItemMap.put(modelMenuItem.getName(), modelMenuItem);
+        }
+    }
+
+    public List<ModelAction> getActions() {
+        return actions;
+    }
+
+    public String getAlign() {
+        if (!this.align.isEmpty()) {
+            return this.align;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getAlign();
+        } else {
+            return this.modelMenu.getDefaultAlign();
+        }
+    }
+
+    public String getAlignStyle() {
+        if (!this.alignStyle.isEmpty()) {
+            return this.alignStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getAlignStyle();
+        } else {
+            return this.modelMenu.getDefaultAlignStyle();
+        }
+    }
+
+    public FlexibleStringExpander getAssociatedContentId() {
+        return associatedContentId;
+    }
+
+    public String getAssociatedContentId(Map<String, Object> context) {
+        String retStr = null;
+        if (this.associatedContentId != null) {
+            retStr = associatedContentId.expandString(context);
+        }
+        if (retStr.isEmpty()) {
+            retStr = this.modelMenu.getDefaultAssociatedContentId(context);
+        }
+        return retStr;
+    }
+
+    public String getCellWidth() {
+        if (!this.cellWidth.isEmpty()) {
+            return this.cellWidth;
+        } else {
+            return this.modelMenu.getDefaultCellWidth();
+        }
+    }
+
+    public ModelMenuCondition getCondition() {
+        return condition;
+    }
+
+    public String getDisabledTitleStyle() {
+        if (!this.disabledTitleStyle.isEmpty()) {
+            return this.disabledTitleStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getDisabledTitleStyle();
+        } else {
+            return this.modelMenu.getDefaultDisabledTitleStyle();
+        }
+    }
+
+    public String getDisableIfEmpty() {
+        return this.disableIfEmpty;
+    }
+
+    public String getEntityName() {
+        if (!this.entityName.isEmpty()) {
+            return this.entityName;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getEntityName();
+        } else {
+            return this.modelMenu.getDefaultEntityName();
+        }
+    }
+
+    public Boolean getHideIfSelected() {
+        if (hideIfSelected != null) {
+            return this.hideIfSelected;
+        } else {
+            return this.modelMenu.getDefaultHideIfSelected();
+        }
+    }
+
+    public MenuLink getLink() {
+        return this.link;
+    }
+
+    public List<ModelMenuItem> getMenuItemList() {
+        return menuItemList;
+    }
+
+    public ModelMenu getModelMenu() {
+        return modelMenu;
+    }
+
+    @Override
+    public String getName() {
+        if (!this.overrideName.isEmpty()) {
+            return this.overrideName;
+        }
+        return super.getName();
+    }
+
+    public String getOverrideName() {
+        return overrideName;
+    }
+
+    public ModelMenuItem getParentMenuItem() {
+        return parentMenuItem;
+    }
+
+    public FlexibleStringExpander getParentPortalPageId() {
+        return parentPortalPageId;
+    }
+
+    public String getParentPortalPageId(Map<String, Object> context) {
+        return this.parentPortalPageId.expandString(context);
+    }
+
+    public int getPosition() {
+        if (this.position == null) {
+            return 1;
+        } else {
+            return position.intValue();
+        }
+    }
+
+    public String getSelectedStyle() {
+        if (!this.selectedStyle.isEmpty()) {
+            return this.selectedStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getSelectedStyle();
+        } else {
+            return this.modelMenu.getDefaultSelectedStyle();
+        }
+    }
+
+    public String getSubMenu() {
+        return subMenu;
+    }
+
+    public FlexibleStringExpander getTitle() {
+        return title;
+    }
+
+    public String getTitle(Map<String, Object> context) {
+        return title.expandString(context);
+    }
+
+    public String getTitleStyle() {
+        if (!this.titleStyle.isEmpty()) {
+            return this.titleStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getTitleStyle();
+        } else {
+            return this.modelMenu.getDefaultTitleStyle();
+        }
+    }
+
+    public FlexibleStringExpander getTooltip() {
+        return tooltip;
+    }
+
+    public String getTooltip(Map<String, Object> context) {
+        if (UtilValidate.isNotEmpty(tooltip)) {
+            return tooltip.expandString(context);
+        } else {
+            return "";
+        }
+    }
+
+    public String getTooltipStyle() {
+        if (!this.tooltipStyle.isEmpty()) {
+            return this.tooltipStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getTooltipStyle();
+        } else {
+            return this.modelMenu.getDefaultTooltipStyle();
+        }
+    }
+
+    public String getWidgetStyle() {
+        if (!this.widgetStyle.isEmpty()) {
+            return this.widgetStyle;
+        } else if (parentMenuItem != null) {
+            return parentMenuItem.getWidgetStyle();
+        } else {
+            return this.modelMenu.getDefaultWidgetStyle();
+        }
+    }
+
+    public boolean isSelected(Map<String, Object> context) {
+        return getName().equals(modelMenu.getSelectedMenuItemContextFieldName(context));
+    }
+
+    public ModelMenuItem mergeOverrideModelMenuItem(ModelMenuItem overrideMenuItem) {
+        return new ModelMenuItem(this, overrideMenuItem);
+    }
+
+    public void renderMenuItemString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+            throws IOException {
+        if (shouldBeRendered(context)) {
+            AbstractModelAction.runSubActions(actions, context);
+            String parentPortalPageId = getParentPortalPageId(context);
+            if (UtilValidate.isNotEmpty(parentPortalPageId)) {
+                List<GenericValue> portalPages = PortalPageWorker.getPortalPages(parentPortalPageId, context);
+                if (UtilValidate.isNotEmpty(portalPages)) {
+                    Locale locale = (Locale) context.get("locale");
+                    for (GenericValue portalPage : portalPages) {
+                        if (UtilValidate.isNotEmpty(portalPage.getString("portalPageName"))) {
+                            ModelMenuItem localItem = new ModelMenuItem(portalPage, this, locale);
+                            menuStringRenderer.renderMenuItem(writer, context, localItem);
+                        }
+                    }
+                }
+            } else {
+                menuStringRenderer.renderMenuItem(writer, context, this);
+            }
+        }
+    }
+
+    public boolean shouldBeRendered(Map<String, Object> context) {
+        if (this.condition != null) {
+            return this.condition.getCondition().eval(context);
+        }
+        return true;
+    }
+
+    public static class MenuLink {
+        private final ModelMenuItem linkMenuItem;
+        private final Link link;
+
+        public MenuLink(Element linkElement, ModelMenuItem parentMenuItem) {
+            this.linkMenuItem = parentMenuItem;
+            if (linkElement.getAttribute("text").isEmpty()) {
+                linkElement.setAttribute("text", parentMenuItem.getTitle().getOriginal());
+            }
+            if (linkElement.getAttribute("style").isEmpty()) {
+                linkElement.setAttribute("style", parentMenuItem.getWidgetStyle());
+            }
+            this.link = new Link(linkElement);
+        }
+
+        public MenuLink(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) {
+            this.linkMenuItem = parentMenuItem;
+            ArrayList<Parameter> parameterList = new ArrayList<Parameter>();
+            if (parentMenuItem.link != null) {
+                parameterList.addAll(parentMenuItem.link.getParameterList());
+            }
+            parameterList.add(new Parameter("portalPageId", portalPage.getString("portalPageId"), false));
+            parameterList.add(new Parameter("parentPortalPageId", portalPage.getString("parentPortalPageId"), false));
+            String target = "showPortalPage";
+            if (parentMenuItem.link != null) {
+                target= "";
+            }
+            this.link = new Link(portalPage, parameterList, target, locale);
+        }
+
+        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) {
+            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 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 ModelMenuItem getLinkMenuItem() {
+            return linkMenuItem;
+        }
+
+        public Link getLink() {
+            return link;
+        }
+
+        public void renderLinkString(Appendable writer, Map<String, Object> context, MenuStringRenderer menuStringRenderer)
+                throws IOException {
+            menuStringRenderer.renderLink(writer, context, this);
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ModelScreen.java b/framework/widget/src/org/ofbiz/widget/model/ModelScreen.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/screen/ModelScreen.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelScreen.java
index ba51445..0058a3c 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ModelScreen.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelScreen.java
@@ -1,194 +1,194 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.util.Map;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntity;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.transaction.TransactionUtil;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.w3c.dom.Element;
-
-/**
- * Widget Library - Screen model class
- */
-@SuppressWarnings("serial")
-public class ModelScreen extends ModelWidget {
-
-    public static final String module = ModelScreen.class.getName();
-
-    private final String sourceLocation;
-    private final FlexibleStringExpander transactionTimeoutExdr;
-    private final Map<String, ModelScreen> modelScreenMap;
-    private final boolean useTransaction;
-    private final boolean useCache;
-    private final ModelScreenWidget.Section section;
-
-    /** XML Constructor */
-    public ModelScreen(Element screenElement, Map<String, ModelScreen> modelScreenMap, String sourceLocation) {
-        super(screenElement);
-        this.sourceLocation = sourceLocation;
-        this.transactionTimeoutExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("transaction-timeout"));
-        this.modelScreenMap = modelScreenMap;
-        this.useTransaction = "true".equals(screenElement.getAttribute("use-transaction"));
-        this.useCache = "true".equals(screenElement.getAttribute("use-cache"));
-
-        // read in the section, which will read all sub-widgets too
-        Element sectionElement = UtilXml.firstChildElement(screenElement, "section");
-        if (sectionElement == null) {
-            throw new IllegalArgumentException("No section found for the screen definition with name: " + getName());
-        }
-        this.section = new ModelScreenWidget.Section(this, sectionElement, true);
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
-    }
-
-    public String getTransactionTimeout() {
-        return transactionTimeoutExdr.getOriginal();
-    }
-
-    public Map<String, ModelScreen> getModelScreenMap() {
-        return modelScreenMap;
-    }
-
-    public boolean getUseTransaction() {
-        return useTransaction;
-    }
-
-    public boolean getUseCache() {
-        return useCache;
-    }
-
-    public ModelScreenWidget.Section getSection() {
-        return section;
-    }
-
-    public String getSourceLocation() {
-        return sourceLocation;
-    }
-
-    /**
-     * Renders this screen to a String, i.e. in a text format, as defined with the
-     * ScreenStringRenderer implementation.
-     *
-     * @param writer The Writer that the screen text will be written to
-     * @param context Map containing the screen context; the following are
-     *   reserved words in this context:
-     *    - parameters (contains any special initial parameters coming in)
-     *    - userLogin (if a user is logged in)
-     *    - autoUserLogin (if a user is automatically logged in, ie no password has been entered)
-     *    - formStringRenderer
-     *    - request, response, session, application (special case, only in HTML contexts, etc)
-     *    - delegator, dispatcher, security
-     *    - null (represents a null field value for entity operations)
-     *    - sections (used for decorators to reference the sections to be decorated and render them)
-     * @param screenStringRenderer An implementation of the ScreenStringRenderer
-     *   interface that is responsible for the actual text generation for
-     *   different screen elements; implementing your own makes it possible to
-     *   use the same screen definitions for many types of screen UIs
-     */
-    public void renderScreenString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws ScreenRenderException {
-        // make sure the "nullField" object is in there for entity ops
-        context.put("nullField", GenericEntity.NULL_FIELD);
-
-        // wrap the whole screen rendering in a transaction, should improve performance in querying and such
-        Map<String, String> parameters = UtilGenerics.cast(context.get("parameters"));
-        boolean beganTransaction = false;
-        int transactionTimeout = -1;
-        if (parameters != null) {
-            String transactionTimeoutPar = parameters.get("TRANSACTION_TIMEOUT");
-            if (transactionTimeoutPar != null) {
-                try {
-                    transactionTimeout = Integer.parseInt(transactionTimeoutPar);
-                } catch (NumberFormatException nfe) {
-                    String msg = "TRANSACTION_TIMEOUT parameter for screen [" + this.sourceLocation + "#" + getName() + "] is invalid and it will be ignored: " + nfe.toString();
-                    Debug.logWarning(msg, module);
-                }
-            }
-        }
-
-        if (transactionTimeout < 0 && !transactionTimeoutExdr.isEmpty()) {
-            // no TRANSACTION_TIMEOUT parameter, check screen attribute
-            String transactionTimeoutStr = transactionTimeoutExdr.expandString(context);
-            if (UtilValidate.isNotEmpty(transactionTimeoutStr)) {
-                try {
-                    transactionTimeout = Integer.parseInt(transactionTimeoutStr);
-                } catch (NumberFormatException e) {
-                    Debug.logWarning(e, "Could not parse transaction-timeout value, original=[" + transactionTimeoutExdr + "], expanded=[" + transactionTimeoutStr + "]", module);
-                }
-            }
-        }
-
-        try {
-            // If transaction timeout is not present (i.e. is equal to -1), the default transaction timeout is used
-            // If transaction timeout is present, use it to start the transaction
-            // If transaction timeout is set to zero, no transaction is started
-            if (useTransaction) {
-                if (transactionTimeout < 0) {
-                    beganTransaction = TransactionUtil.begin();
-                }
-                if (transactionTimeout > 0) {
-                    beganTransaction = TransactionUtil.begin(transactionTimeout);
-                }
-            }
-
-            // render the screen, starting with the top-level section
-            this.section.renderWidgetString(writer, context, screenStringRenderer);
-            TransactionUtil.commit(beganTransaction);
-        } catch (Exception e) {
-            String errMsg = "Error rendering screen [" + this.sourceLocation + "#" + getName() + "]: " + e.toString();
-            Debug.logError(errMsg + ". Rolling back transaction.", module);
-            try {
-                // only rollback the transaction if we started one...
-                TransactionUtil.rollback(beganTransaction, errMsg, e);
-            } catch (GenericEntityException e2) {
-                Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module);
-            }
-
-            // throw nested exception, don't need to log details here: Debug.logError(e, errMsg, module);
-
-            // after rolling back, rethrow the exception
-            throw new ScreenRenderException(errMsg, e);
-        }
-    }
-
-    public LocalDispatcher getDispatcher(Map<String, Object> context) {
-        LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
-        return dispatcher;
-    }
-
-    public Delegator getDelegator(Map<String, Object> context) {
-        Delegator delegator = (Delegator) context.get("delegator");
-        return delegator;
-    }
-}
-
-
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.util.Map;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntity;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.transaction.TransactionUtil;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.widget.renderer.ScreenRenderException;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.w3c.dom.Element;
+
+/**
+ * Widget Library - Screen model class
+ */
+@SuppressWarnings("serial")
+public class ModelScreen extends ModelWidget {
+
+    public static final String module = ModelScreen.class.getName();
+
+    private final String sourceLocation;
+    private final FlexibleStringExpander transactionTimeoutExdr;
+    private final Map<String, ModelScreen> modelScreenMap;
+    private final boolean useTransaction;
+    private final boolean useCache;
+    private final ModelScreenWidget.Section section;
+
+    /** XML Constructor */
+    public ModelScreen(Element screenElement, Map<String, ModelScreen> modelScreenMap, String sourceLocation) {
+        super(screenElement);
+        this.sourceLocation = sourceLocation;
+        this.transactionTimeoutExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("transaction-timeout"));
+        this.modelScreenMap = modelScreenMap;
+        this.useTransaction = "true".equals(screenElement.getAttribute("use-transaction"));
+        this.useCache = "true".equals(screenElement.getAttribute("use-cache"));
+
+        // read in the section, which will read all sub-widgets too
+        Element sectionElement = UtilXml.firstChildElement(screenElement, "section");
+        if (sectionElement == null) {
+            throw new IllegalArgumentException("No section found for the screen definition with name: " + getName());
+        }
+        this.section = new ModelScreenWidget.Section(this, sectionElement, true);
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+
+    public String getTransactionTimeout() {
+        return transactionTimeoutExdr.getOriginal();
+    }
+
+    public Map<String, ModelScreen> getModelScreenMap() {
+        return modelScreenMap;
+    }
+
+    public boolean getUseTransaction() {
+        return useTransaction;
+    }
+
+    public boolean getUseCache() {
+        return useCache;
+    }
+
+    public ModelScreenWidget.Section getSection() {
+        return section;
+    }
+
+    public String getSourceLocation() {
+        return sourceLocation;
+    }
+
+    /**
+     * Renders this screen to a String, i.e. in a text format, as defined with the
+     * ScreenStringRenderer implementation.
+     *
+     * @param writer The Writer that the screen text will be written to
+     * @param context Map containing the screen context; the following are
+     *   reserved words in this context:
+     *    - parameters (contains any special initial parameters coming in)
+     *    - userLogin (if a user is logged in)
+     *    - autoUserLogin (if a user is automatically logged in, ie no password has been entered)
+     *    - formStringRenderer
+     *    - request, response, session, application (special case, only in HTML contexts, etc)
+     *    - delegator, dispatcher, security
+     *    - null (represents a null field value for entity operations)
+     *    - sections (used for decorators to reference the sections to be decorated and render them)
+     * @param screenStringRenderer An implementation of the ScreenStringRenderer
+     *   interface that is responsible for the actual text generation for
+     *   different screen elements; implementing your own makes it possible to
+     *   use the same screen definitions for many types of screen UIs
+     */
+    public void renderScreenString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws ScreenRenderException {
+        // make sure the "nullField" object is in there for entity ops
+        context.put("nullField", GenericEntity.NULL_FIELD);
+
+        // wrap the whole screen rendering in a transaction, should improve performance in querying and such
+        Map<String, String> parameters = UtilGenerics.cast(context.get("parameters"));
+        boolean beganTransaction = false;
+        int transactionTimeout = -1;
+        if (parameters != null) {
+            String transactionTimeoutPar = parameters.get("TRANSACTION_TIMEOUT");
+            if (transactionTimeoutPar != null) {
+                try {
+                    transactionTimeout = Integer.parseInt(transactionTimeoutPar);
+                } catch (NumberFormatException nfe) {
+                    String msg = "TRANSACTION_TIMEOUT parameter for screen [" + this.sourceLocation + "#" + getName() + "] is invalid and it will be ignored: " + nfe.toString();
+                    Debug.logWarning(msg, module);
+                }
+            }
+        }
+
+        if (transactionTimeout < 0 && !transactionTimeoutExdr.isEmpty()) {
+            // no TRANSACTION_TIMEOUT parameter, check screen attribute
+            String transactionTimeoutStr = transactionTimeoutExdr.expandString(context);
+            if (UtilValidate.isNotEmpty(transactionTimeoutStr)) {
+                try {
+                    transactionTimeout = Integer.parseInt(transactionTimeoutStr);
+                } catch (NumberFormatException e) {
+                    Debug.logWarning(e, "Could not parse transaction-timeout value, original=[" + transactionTimeoutExdr + "], expanded=[" + transactionTimeoutStr + "]", module);
+                }
+            }
+        }
+
+        try {
+            // If transaction timeout is not present (i.e. is equal to -1), the default transaction timeout is used
+            // If transaction timeout is present, use it to start the transaction
+            // If transaction timeout is set to zero, no transaction is started
+            if (useTransaction) {
+                if (transactionTimeout < 0) {
+                    beganTransaction = TransactionUtil.begin();
+                }
+                if (transactionTimeout > 0) {
+                    beganTransaction = TransactionUtil.begin(transactionTimeout);
+                }
+            }
+
+            // render the screen, starting with the top-level section
+            this.section.renderWidgetString(writer, context, screenStringRenderer);
+            TransactionUtil.commit(beganTransaction);
+        } catch (Exception e) {
+            String errMsg = "Error rendering screen [" + this.sourceLocation + "#" + getName() + "]: " + e.toString();
+            Debug.logError(errMsg + ". Rolling back transaction.", module);
+            try {
+                // only rollback the transaction if we started one...
+                TransactionUtil.rollback(beganTransaction, errMsg, e);
+            } catch (GenericEntityException e2) {
+                Debug.logError(e2, "Could not rollback transaction: " + e2.toString(), module);
+            }
+
+            // throw nested exception, don't need to log details here: Debug.logError(e, errMsg, module);
+
+            // after rolling back, rethrow the exception
+            throw new ScreenRenderException(errMsg, e);
+        }
+    }
+
+    public LocalDispatcher getDispatcher(Map<String, Object> context) {
+        LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+        return dispatcher;
+    }
+
+    public Delegator getDelegator(Map<String, Object> context) {
+        Delegator delegator = (Delegator) context.get("delegator");
+        return delegator;
+    }
+}
+
+
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java b/framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java
similarity index 90%
rename from framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java
index fb1227a..8926f98 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java
@@ -1,96 +1,96 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.util.Map;
-
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.widget.AbstractModelCondition;
-import org.ofbiz.widget.AbstractModelCondition.DefaultConditionFactory;
-import org.ofbiz.widget.ModelCondition;
-import org.ofbiz.widget.ModelConditionFactory;
-import org.ofbiz.widget.ModelConditionVisitor;
-import org.ofbiz.widget.ModelWidget;
-import org.w3c.dom.Element;
-
-/**
- * Models the &lt;condition&gt; element.
- * 
- * @see <code>widget-screen.xsd</code>
- */
-@SuppressWarnings("serial")
-public final class ModelScreenCondition {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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.
-     * 
-     * 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 = ModelScreenCondition.class.getName();
-    public static final ModelConditionFactory SCREEN_CONDITION_FACTORY = new ScreenConditionFactory();
-
-    public static class IfEmptySection extends AbstractModelCondition {
-        private final FlexibleStringExpander sectionExdr;
-
-        private IfEmptySection(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
-            super (factory, modelWidget, condElement);
-            this.sectionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("section-name"));
-        }
-
-        @Override
-        public void accept(ModelConditionVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        @Override
-        public boolean eval(Map<String, Object> context) {
-            Map<String, Object> sectionsMap = UtilGenerics.toMap(context.get("sections"));
-            return !sectionsMap.containsKey(this.sectionExdr.expandString(context));
-        }
-
-        public FlexibleStringExpander getSectionExdr() {
-            return sectionExdr;
-        }
-    }
-
-    private static class ScreenConditionFactory extends DefaultConditionFactory {
-
-        @Override
-        public ModelCondition newInstance(ModelWidget modelWidget, Element conditionElement) {
-            if (conditionElement == null) {
-                return DefaultConditionFactory.TRUE;
-            }
-            if ("if-empty-section".equals(conditionElement.getNodeName())) {
-                return new IfEmptySection(this, modelWidget, conditionElement);
-            } else {
-                return super.newInstance(this, modelWidget,conditionElement);
-            }
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.util.Map;
+
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.widget.model.AbstractModelCondition;
+import org.ofbiz.widget.model.AbstractModelCondition.DefaultConditionFactory;
+import org.ofbiz.widget.model.ModelCondition;
+import org.ofbiz.widget.model.ModelConditionFactory;
+import org.ofbiz.widget.model.ModelConditionVisitor;
+import org.ofbiz.widget.model.ModelWidget;
+import org.w3c.dom.Element;
+
+/**
+ * Models the &lt;condition&gt; element.
+ * 
+ * @see <code>widget-screen.xsd</code>
+ */
+@SuppressWarnings("serial")
+public final class ModelScreenCondition {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     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.
+     * 
+     * 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 = ModelScreenCondition.class.getName();
+    public static final ModelConditionFactory SCREEN_CONDITION_FACTORY = new ScreenConditionFactory();
+
+    public static class IfEmptySection extends AbstractModelCondition {
+        private final FlexibleStringExpander sectionExdr;
+
+        private IfEmptySection(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+            super (factory, modelWidget, condElement);
+            this.sectionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("section-name"));
+        }
+
+        @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
+        public boolean eval(Map<String, Object> context) {
+            Map<String, Object> sectionsMap = UtilGenerics.toMap(context.get("sections"));
+            return !sectionsMap.containsKey(this.sectionExdr.expandString(context));
+        }
+
+        public FlexibleStringExpander getSectionExdr() {
+            return sectionExdr;
+        }
+    }
+
+    private static class ScreenConditionFactory extends DefaultConditionFactory {
+
+        @Override
+        public ModelCondition newInstance(ModelWidget modelWidget, Element conditionElement) {
+            if (conditionElement == null) {
+                return DefaultConditionFactory.TRUE;
+            }
+            if ("if-empty-section".equals(conditionElement.getNodeName())) {
+                return new IfEmptySection(this, modelWidget, conditionElement);
+            } else {
+                return super.newInstance(this, modelWidget,conditionElement);
+            }
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java b/framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java
index 4214aea..f5d1949 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java
@@ -1,1966 +1,1957 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.MapStack;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.util.EntityQuery;
-import org.ofbiz.widget.AbstractModelAction;
-import org.ofbiz.widget.CommonWidgetModels.*;
-import org.ofbiz.widget.CommonWidgetModels.AutoEntityParameters;
-import org.ofbiz.widget.CommonWidgetModels.AutoServiceParameters;
-import org.ofbiz.widget.CommonWidgetModels.Image;
-import org.ofbiz.widget.CommonWidgetModels.Parameter;
-import org.ofbiz.widget.ModelAction;
-import org.ofbiz.widget.ModelCondition;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.PortalPageWorker;
-import org.ofbiz.widget.WidgetFactory;
-import org.ofbiz.widget.form.FormFactory;
-import org.ofbiz.widget.form.FormRenderer;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.menu.MenuFactory;
-import org.ofbiz.widget.menu.MenuStringRenderer;
-import org.ofbiz.widget.menu.ModelMenu;
-import org.ofbiz.widget.tree.ModelTree;
-import org.ofbiz.widget.tree.TreeFactory;
-import org.ofbiz.widget.tree.TreeStringRenderer;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-
-/**
- * Widget Library - Screen model class
- */
-@SuppressWarnings("serial")
-public abstract class ModelScreenWidget extends ModelWidget {
-    public static final String module = ModelScreenWidget.class.getName();
-
-    private final ModelScreen modelScreen;
-
-    public ModelScreenWidget(ModelScreen modelScreen, Element widgetElement) {
-        super(widgetElement);
-        this.modelScreen = modelScreen;
-        if (Debug.verboseOn()) Debug.logVerbose("Reading Screen sub-widget with name: " + widgetElement.getNodeName(), module);
-    }
-
-    public abstract void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException;
-
-    protected static List<ModelScreenWidget> readSubWidgets(ModelScreen modelScreen, List<? extends Element> subElementList) {
-        if (subElementList.isEmpty()) {
-            return Collections.emptyList();
-        }
-        List<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(subElementList.size());
-        for (Element subElement: subElementList) {
-            subWidgets.add(WidgetFactory.getModelScreenWidget(modelScreen, subElement));
-        }
-        return Collections.unmodifiableList(subWidgets);
-    }
-
-    protected static void renderSubWidgetsString(List<ModelScreenWidget> subWidgets, Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-        if (subWidgets == null) {
-            return;
-        }
-        for (ModelScreenWidget subWidget: subWidgets) {
-            if (Debug.verboseOn()) Debug.logVerbose("Rendering screen " + subWidget.getModelScreen().getName() + "; widget class is " + subWidget.getClass().getName(), module);
-
-            // render the sub-widget itself
-            subWidget.renderWidgetString(writer, context, screenStringRenderer);
-        }
-    }
-
-    public ModelScreen getModelScreen() {
-        return this.modelScreen;
-    }
-
-    public static final class SectionsRenderer implements Map<String, ModelScreenWidget> {
-        private final Map<String, ModelScreenWidget> sectionMap;
-        private final ScreenStringRenderer screenStringRenderer;
-        private final Map<String, Object> context;
-        private final Appendable writer;
-
-        public SectionsRenderer(Map<String, ModelScreenWidget> sectionMap, Map<String, Object> context, Appendable writer,
-                ScreenStringRenderer screenStringRenderer) {
-            Map<String, ModelScreenWidget> localMap = new HashMap<String, ModelScreenWidget>();
-            localMap.putAll(sectionMap);
-            this.sectionMap = Collections.unmodifiableMap(localMap);
-            this.context = context;
-            this.writer = writer;
-            this.screenStringRenderer = screenStringRenderer;
-        }
-
-        /** This is a lot like the ScreenRenderer class and returns an empty String so it can be used more easily with FreeMarker */
-        public String render(String sectionName) throws GeneralException, IOException {
-            ModelScreenWidget section = sectionMap.get(sectionName);
-            // if no section by that name, write nothing
-            if (section != null) {
-                section.renderWidgetString(this.writer, this.context, this.screenStringRenderer);
-            }
-            return "";
-        }
-
-        @Override
-        public int size() {
-            return sectionMap.size();
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return sectionMap.isEmpty();
-        }
-
-        @Override
-        public boolean containsKey(Object key) {
-            return sectionMap.containsKey(key);
-        }
-
-        @Override
-        public boolean containsValue(Object value) {
-            return sectionMap.containsValue(value);
-        }
-
-        @Override
-        public ModelScreenWidget get(Object key) {
-            return sectionMap.get(key);
-        }
-
-        @Override
-        public ModelScreenWidget put(String key, ModelScreenWidget value) {
-            return sectionMap.put(key, value);
-        }
-
-        @Override
-        public ModelScreenWidget remove(Object key) {
-            return sectionMap.remove(key);
-        }
-
-        @Override
-        public void clear() {
-            sectionMap.clear();
-        }
-
-        @Override
-        public Set<String> keySet() {
-            return sectionMap.keySet();
-        }
-
-        @Override
-        public Collection<ModelScreenWidget> values() {
-            return sectionMap.values();
-        }
-
-        @Override
-        public Set<java.util.Map.Entry<String, ModelScreenWidget>> entrySet() {
-            return sectionMap.entrySet();
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            return sectionMap.equals(o);
-        }
-
-        @Override
-        public int hashCode() {
-            return sectionMap.hashCode();
-        }
-
-        @Override
-        public void putAll(Map<? extends String, ? extends ModelScreenWidget> m) {
-            sectionMap.putAll(m);
-        }
-    }
-
-    public static final class Section extends ModelScreenWidget {
-        public static final String TAG_NAME = "section";
-        private final ModelCondition condition;
-        private final List<ModelAction> actions;
-        private final List<ModelScreenWidget> subWidgets;
-        private final List<ModelScreenWidget> failWidgets;
-        private final boolean isMainSection;
-
-        public Section(ModelScreen modelScreen, Element sectionElement) {
-            this(modelScreen, sectionElement, false);
-        }
-
-        public Section(ModelScreen modelScreen, Element sectionElement, boolean isMainSection) {
-            super(modelScreen, sectionElement);
-
-            // read condition under the "condition" element
-            Element conditionElement = UtilXml.firstChildElement(sectionElement, "condition");
-            if (conditionElement != null) {
-                conditionElement = UtilXml.firstChildElement(conditionElement);
-                this.condition = ModelScreenCondition.SCREEN_CONDITION_FACTORY.newInstance(modelScreen, conditionElement);
-            } else {
-                this.condition = null;
-            }
-
-            // read all actions under the "actions" element
-            Element actionsElement = UtilXml.firstChildElement(sectionElement, "actions");
-            if (actionsElement != null) {
-                this.actions = AbstractModelAction.readSubActions(modelScreen, actionsElement);
-            } else {
-                this.actions = Collections.emptyList();
-            }
-
-            // read sub-widgets
-            Element widgetsElement = UtilXml.firstChildElement(sectionElement, "widgets");
-            if (widgetsElement != null) {
-                List<? extends Element> subElementList = UtilXml.childElementList(widgetsElement);
-                this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList);
-            } else {
-                this.subWidgets = Collections.emptyList();
-            }
-
-            // read fail-widgets
-            Element failWidgetsElement = UtilXml.firstChildElement(sectionElement, "fail-widgets");
-            if (failWidgetsElement != null) {
-                List<? extends Element> failElementList = UtilXml.childElementList(failWidgetsElement);
-                this.failWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), failElementList);
-            } else {
-                this.failWidgets = Collections.emptyList();
-            }
-            this.isMainSection = isMainSection;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            // check the condition, if there is one
-            boolean condTrue = true;
-            if (this.condition != null) {
-                if (!this.condition.eval(context)) {
-                    condTrue = false;
-                }
-            }
-
-            // if condition does not exist or evals to true run actions and render widgets, otherwise render fail-widgets
-            if (condTrue) {
-                // run the actions only if true
-                AbstractModelAction.runSubActions(this.actions, context);
-
-                try {
-                    // section by definition do not themselves do anything, so this method will generally do nothing, but we'll call it anyway
-                    screenStringRenderer.renderSectionBegin(writer, context, this);
-
-                    // render sub-widgets
-                    renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
-
-                    screenStringRenderer.renderSectionEnd(writer, context, this);
-                } catch (IOException e) {
-                    String errMsg = "Error rendering widgets section [" + getName() + "] in screen named [" + getModelScreen().getName() + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            } else {
-                try {
-                    // section by definition do not themselves do anything, so this method will generally do nothing, but we'll call it anyway
-                    screenStringRenderer.renderSectionBegin(writer, context, this);
-
-                    // render sub-widgets
-                    renderSubWidgetsString(this.failWidgets, writer, context, screenStringRenderer);
-
-                    screenStringRenderer.renderSectionEnd(writer, context, this);
-                } catch (IOException e) {
-                    String errMsg = "Error rendering fail-widgets section [" + this.getName() + "] in screen named [" + getModelScreen().getName() + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            }
-
-        }
-
-        @Override
-        public String getBoundaryCommentName() {
-            if (isMainSection) {
-                return getModelScreen().getSourceLocation() + "#" + getModelScreen().getName();
-            } else {
-                return getName();
-            }
-        }
-
-        public List<ModelAction> getActions() {
-            return actions;
-        }
-
-        public List<ModelScreenWidget> getSubWidgets() {
-            return subWidgets;
-        }
-
-        public List<ModelScreenWidget> getFailWidgets() {
-            return failWidgets;
-        }
-
-        public boolean isMainSection() {
-            return isMainSection;
-        }
-
-        public ModelCondition getCondition() {
-            return condition;
-        }
-    }
-
-    public static final class ColumnContainer extends ModelScreenWidget {
-        public static final String TAG_NAME = "column-container";
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander styleExdr;
-        private final List<Column> columns;
-
-        public ColumnContainer(ModelScreen modelScreen, Element containerElement) {
-            super(modelScreen, containerElement);
-            this.idExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("id"));
-            this.styleExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("style"));
-            List<? extends Element> subElementList = UtilXml.childElementList(containerElement, "column");
-            List<Column> columns = new ArrayList<Column>(subElementList.size());
-            for (Element element : subElementList) {
-                columns.add(new Column(modelScreen, element));
-            }
-            this.columns = Collections.unmodifiableList(columns);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            try {
-                screenStringRenderer.renderColumnContainer(writer, context, this);
-            } catch (IOException e) {
-                String errMsg = "Error rendering container in screen named [" + getModelScreen().getName() + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-
-        public List<Column> getColumns() {
-            return this.columns;
-        }
-
-        public String getId(Map<String, Object> context) {
-            return this.idExdr.expandString(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return this.styleExdr.expandString(context);
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return idExdr;
-        }
-
-        public FlexibleStringExpander getStyleExdr() {
-            return styleExdr;
-        }
-    }
-
-    public static final class Column extends ModelWidget {
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander styleExdr;
-        private final List<ModelScreenWidget> subWidgets;
-
-        public Column(ModelScreen modelScreen, Element columnElement) {
-            super(columnElement);
-            this.idExdr = FlexibleStringExpander.getInstance(columnElement.getAttribute("id"));
-            this.styleExdr = FlexibleStringExpander.getInstance(columnElement.getAttribute("style"));
-            List<? extends Element> subElementList = UtilXml.childElementList(columnElement);
-            this.subWidgets = Collections.unmodifiableList(readSubWidgets(modelScreen, subElementList));
-        }
-
-        public List<ModelScreenWidget> getSubWidgets() {
-            return this.subWidgets;
-        }
-
-        public String getId(Map<String, Object> context) {
-            return this.idExdr.expandString(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return this.styleExdr.expandString(context);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return idExdr;
-        }
-
-        public FlexibleStringExpander getStyleExdr() {
-            return styleExdr;
-        }
-    }
-
-    public static final class Container extends ModelScreenWidget {
-        public static final String TAG_NAME = "container";
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander styleExdr;
-        private final FlexibleStringExpander autoUpdateTargetExdr;
-        private final FlexibleStringExpander autoUpdateInterval;
-        private final List<ModelScreenWidget> subWidgets;
-
-        public Container(ModelScreen modelScreen, Element containerElement) {
-            super(modelScreen, containerElement);
-            this.idExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("id"));
-            this.styleExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("style"));
-            this.autoUpdateTargetExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("auto-update-target"));
-            String autoUpdateInterval = containerElement.getAttribute("auto-update-interval");
-            if (autoUpdateInterval.isEmpty()) {
-                autoUpdateInterval = "2";
-            }
-            this.autoUpdateInterval = FlexibleStringExpander.getInstance(autoUpdateInterval);
-            // read sub-widgets
-            List<? extends Element> subElementList = UtilXml.childElementList(containerElement);
-            this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            try {
-                screenStringRenderer.renderContainerBegin(writer, context, this);
-
-                // render sub-widgets
-                renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
-
-                screenStringRenderer.renderContainerEnd(writer, context, this);
-            } catch (IOException e) {
-                String errMsg = "Error rendering container in screen named [" + getModelScreen().getName() + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-
-        public String getId(Map<String, Object> context) {
-            return this.idExdr.expandString(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return this.styleExdr.expandString(context);
-        }
-
-        public String getAutoUpdateTargetExdr(Map<String, Object> context) {
-            return this.autoUpdateTargetExdr.expandString(context);
-        }
-
-        public String getAutoUpdateInterval(Map<String, Object> context) {
-            return this.autoUpdateInterval.expandString(context);
-        }
-
-        public List<ModelScreenWidget> getSubWidgets() {
-            return subWidgets;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return idExdr;
-        }
-
-        public FlexibleStringExpander getStyleExdr() {
-            return styleExdr;
-        }
-
-        public FlexibleStringExpander getAutoUpdateTargetExdr() {
-            return autoUpdateTargetExdr;
-        }
-
-        public FlexibleStringExpander getAutoUpdateInterval() {
-            return autoUpdateInterval;
-        }
-    }
-
-    public static final class Screenlet extends ModelScreenWidget {
-        public static final String TAG_NAME = "screenlet";
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander titleExdr;
-        private final Menu navigationMenu;
-        private final Menu tabMenu;
-        private final Form navigationForm;
-        private final boolean collapsible;
-        private final FlexibleStringExpander initiallyCollapsed;
-        private final boolean saveCollapsed;
-        private final boolean padded;
-        private final List<ModelScreenWidget> subWidgets;
-
-        public Screenlet(ModelScreen modelScreen, Element screenletElement) {
-            super(modelScreen, screenletElement);
-            this.idExdr = FlexibleStringExpander.getInstance(screenletElement.getAttribute("id"));
-            boolean collapsible = "true".equals(screenletElement.getAttribute("collapsible"));
-            this.initiallyCollapsed = FlexibleStringExpander.getInstance(screenletElement.getAttribute("initially-collapsed"));
-            if ("true".equals(this.initiallyCollapsed.getOriginal())) {
-                collapsible = true;
-            }
-            this.collapsible = collapsible;
-            // By default, for a collapsible screenlet, the collapsed/expanded status must be saved
-            this.saveCollapsed = !("false".equals(screenletElement.getAttribute("save-collapsed")));
-
-            boolean padded = !"false".equals(screenletElement.getAttribute("padded"));
-            if (this.collapsible && getName().isEmpty() && idExdr.isEmpty()) {
-                throw new IllegalArgumentException("Collapsible screenlets must have a name or id [" + getModelScreen().getName() + "]");
-            }
-            this.titleExdr = FlexibleStringExpander.getInstance(screenletElement.getAttribute("title"));
-            List<? extends Element> subElementList = UtilXml.childElementList(screenletElement);
-            // Make a copy of the unmodifiable List so we can modify it.
-            ArrayList<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList));
-            Menu navigationMenu = null;
-            String navMenuName = screenletElement.getAttribute("navigation-menu-name");
-            if (!navMenuName.isEmpty()) {
-                for (ModelWidget subWidget : subWidgets) {
-                    if (navMenuName.equals(subWidget.getName()) && subWidget instanceof Menu) {
-                        navigationMenu = (Menu) subWidget;
-                        subWidgets.remove(subWidget);
-                        break;
-                    }
-                }
-            }
-            this.navigationMenu = navigationMenu;
-            Menu tabMenu = null;
-            String tabMenuName = screenletElement.getAttribute("tab-menu-name");
-            if (!tabMenuName.isEmpty()) {
-                for (ModelWidget subWidget : subWidgets) {
-                    if (tabMenuName.equals(subWidget.getName()) && subWidget instanceof Menu) {
-                        tabMenu = (Menu) subWidget;
-                        subWidgets.remove(subWidget);
-                        break;
-                    }
-                }
-            }
-            this.tabMenu = tabMenu;
-            Form navigationForm = null;
-            String formName = screenletElement.getAttribute("navigation-form-name");
-            if (!formName.isEmpty() && this.navigationMenu == null) {
-                for (ModelWidget subWidget : subWidgets) {
-                    if (formName.equals(subWidget.getName()) && subWidget instanceof Form) {
-                        navigationForm = (Form) subWidget;
-                        padded = false;
-                        break;
-                    }
-                }
-            }
-            this.subWidgets = Collections.unmodifiableList(subWidgets);
-            this.navigationForm = navigationForm;
-            this.padded = padded;
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            boolean collapsed = getInitiallyCollapsed(context);
-            if (this.collapsible) {
-                String preferenceKey = getPreferenceKey(context) + "_collapsed";
-                Map<String, Object> requestParameters = UtilGenerics.checkMap(context.get("requestParameters"));
-                if (requestParameters != null) {
-                    String collapsedParam = (String) requestParameters.get(preferenceKey);
-                    collapsed = "true".equals(collapsedParam);
-                }
-            }
-            try {
-                screenStringRenderer.renderScreenletBegin(writer, context, collapsed, this);
-                for (ModelScreenWidget subWidget : this.subWidgets) {
-                    screenStringRenderer.renderScreenletSubWidget(writer, context, subWidget, this);
-                }
-                screenStringRenderer.renderScreenletEnd(writer, context, this);
-            } catch (IOException e) {
-                String errMsg = "Error rendering screenlet in screen named [" + getModelScreen().getName() + "]: ";
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg + e);
-            }
-        }
-
-        public boolean collapsible() {
-            return this.collapsible;
-        }
-
-        //initially-collapsed status, which may be overriden by user preference
-        public boolean getInitiallyCollapsed(Map<String, Object> context) {
-            String screenletId = this.getId(context) + "_collapsed";
-            Map<String, ? extends Object> userPreferences = UtilGenerics.checkMap(context.get("userPreferences"));
-            if (userPreferences != null && userPreferences.containsKey(screenletId)) {
-                return Boolean.valueOf((String)userPreferences.get(screenletId)).booleanValue() ;
-            }
-
-            return "true".equals(this.initiallyCollapsed.expand(context));
-        }
-
-        public boolean saveCollapsed() {
-            return this.saveCollapsed;
-        }
-        public boolean padded() {
-            return this.padded;
-        }
-
-        public String getPreferenceKey(Map<String, Object> context) {
-            String name = this.idExdr.expandString(context);
-            if (name.isEmpty()) {
-                name = "screenlet" + "_" + Integer.toHexString(hashCode());
-            }
-            return name;
-        }
-
-        public String getId(Map<String, Object> context) {
-            return this.idExdr.expandString(context);
-        }
-
-        public List<ModelScreenWidget> getSubWidgets() {
-            return subWidgets;
-        }
-
-        public String getTitle(Map<String, Object> context) {
-            String title = this.titleExdr.expandString(context);
-            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-            if (simpleEncoder != null) {
-                title = simpleEncoder.encode(title);
-            }
-            return title;
-        }
-
-        public Menu getNavigationMenu() {
-            return this.navigationMenu;
-        }
-
-        public Form getNavigationForm() {
-            return this.navigationForm;
-        }
-
-        public Menu getTabMenu() {
-            return this.tabMenu;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return idExdr;
-        }
-
-        public FlexibleStringExpander getTitleExdr() {
-            return titleExdr;
-        }
-
-        public boolean getCollapsible() {
-            return collapsible;
-        }
-
-        public FlexibleStringExpander getInitiallyCollapsed() {
-            return initiallyCollapsed;
-        }
-
-        public boolean getSaveCollapsed() {
-            return saveCollapsed;
-        }
-
-        public boolean getPadded() {
-            return padded;
-        }
-    }
-
-    public static final class HorizontalSeparator extends ModelScreenWidget {
-        public static final String TAG_NAME = "horizontal-separator";
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander styleExdr;
-
-        public HorizontalSeparator(ModelScreen modelScreen, Element separatorElement) {
-            super(modelScreen, separatorElement);
-            this.idExdr = FlexibleStringExpander.getInstance(separatorElement.getAttribute("id"));
-            this.styleExdr = FlexibleStringExpander.getInstance(separatorElement.getAttribute("style"));
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            screenStringRenderer.renderHorizontalSeparator(writer, context, this);
-        }
-
-        public String getId(Map<String, Object> context) {
-            return this.idExdr.expandString(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return this.styleExdr.expandString(context);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return idExdr;
-        }
-
-        public FlexibleStringExpander getStyleExdr() {
-            return styleExdr;
-        }
-    }
-
-    public static final class IncludeScreen extends ModelScreenWidget {
-        public static final String TAG_NAME = "include-screen";
-        private final FlexibleStringExpander nameExdr;
-        private final FlexibleStringExpander locationExdr;
-        private final FlexibleStringExpander shareScopeExdr;
-
-        public IncludeScreen(ModelScreen modelScreen, Element includeScreenElement) {
-            super(modelScreen, includeScreenElement);
-            this.nameExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("name"));
-            this.locationExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("location"));
-            this.shareScopeExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("share-scope"));
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            // if we are not sharing the scope, protect it using the MapStack
-            boolean protectScope = !shareScope(context);
-            if (protectScope) {
-                if (!(context instanceof MapStack<?>)) {
-                    context = MapStack.create(context);
-                }
-
-                UtilGenerics.<MapStack<String>>cast(context).push();
-
-                // build the widgetpath
-                List<String> widgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
-                if (widgetTrail == null) {
-                    widgetTrail = new LinkedList<String>();
-                }
-
-                String thisName = nameExdr.expandString(context);
-                widgetTrail.add(thisName);
-                context.put("_WIDGETTRAIL_", widgetTrail);
-            }
-
-            // don't need the renderer here, will just pass this on down to another screen call; screenStringRenderer.renderContainerBegin(writer, context, this);
-            String name = this.getName(context);
-            String location = this.getLocation(context);
-
-            if (name.isEmpty()) {
-                if (Debug.verboseOn()) Debug.logVerbose("In the include-screen tag the screen name was empty, ignoring include; in screen [" + getModelScreen().getName() + "]", module);
-                return;
-            }
-
-            ScreenFactory.renderReferencedScreen(name, location, this, writer, context, screenStringRenderer);
-
-            if (protectScope) {
-                UtilGenerics.<MapStack<String>>cast(context).pop();
-            }
-        }
-
-        public String getName(Map<String, Object> context) {
-            return this.nameExdr.expandString(context);
-        }
-
-        public String getLocation(Map<String, Object> context) {
-            return this.locationExdr.expandString(context);
-        }
-
-        public boolean shareScope(Map<String, Object> context) {
-            String shareScopeString = this.shareScopeExdr.expandString(context);
-            // defaults to false, so anything but true is false
-            return "true".equals(shareScopeString);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getNameExdr() {
-            return nameExdr;
-        }
-
-        public FlexibleStringExpander getLocationExdr() {
-            return locationExdr;
-        }
-
-        public FlexibleStringExpander getShareScopeExdr() {
-            return shareScopeExdr;
-        }
-    }
-
-    public static final class DecoratorScreen extends ModelScreenWidget {
-        public static final String TAG_NAME = "decorator-screen";
-        private final FlexibleStringExpander nameExdr;
-        private final FlexibleStringExpander locationExdr;
-        private final Map<String, ModelScreenWidget> sectionMap;
-
-        public DecoratorScreen(ModelScreen modelScreen, Element decoratorScreenElement) {
-            super(modelScreen, decoratorScreenElement);
-            this.nameExdr = FlexibleStringExpander.getInstance(decoratorScreenElement.getAttribute("name"));
-            this.locationExdr = FlexibleStringExpander.getInstance(decoratorScreenElement.getAttribute("location"));
-            Map<String, ModelScreenWidget> sectionMap = new HashMap<String, ModelScreenWidget>();
-            List<? extends Element> decoratorSectionElementList = UtilXml.childElementList(decoratorScreenElement, "decorator-section");
-            for (Element decoratorSectionElement: decoratorSectionElementList) {
-                DecoratorSection decoratorSection = new DecoratorSection(modelScreen, decoratorSectionElement);
-                sectionMap.put(decoratorSection.getName(), decoratorSection);
-            }
-            this.sectionMap = Collections.unmodifiableMap(sectionMap);
-        }
-
-        @Override
-        @SuppressWarnings("unchecked")
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            // isolate the scope
-            if (!(context instanceof MapStack)) {
-                context = MapStack.create(context);
-            }
-
-            MapStack contextMs = (MapStack) context;
-
-            // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down
-            MapStack standAloneStack = contextMs.standAloneChildStack();
-            standAloneStack.put("screens", new ScreenRenderer(writer, standAloneStack, screenStringRenderer));
-            SectionsRenderer sections = new SectionsRenderer(this.sectionMap, standAloneStack, writer, screenStringRenderer);
-
-            // put the sectionMap in the context, make sure it is in the sub-scope, ie after calling push on the MapStack
-            contextMs.push();
-            context.put("sections", sections);
-
-            String name = this.getName(context);
-            String location = this.getLocation(context);
-
-            ScreenFactory.renderReferencedScreen(name, location, this, writer, context, screenStringRenderer);
-
-            contextMs.pop();
-        }
-
-        public String getName(Map<String, Object> context) {
-            return this.nameExdr.expandString(context);
-        }
-
-        public String getLocation(Map<String, Object> context) {
-            return this.locationExdr.expandString(context);
-        }
-
-        public Map<String, ModelScreenWidget> getSectionMap() {
-            return sectionMap;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getNameExdr() {
-            return nameExdr;
-        }
-
-        public FlexibleStringExpander getLocationExdr() {
-            return locationExdr;
-        }
-
-    }
-
-    public static final class DecoratorSection extends ModelScreenWidget {
-        public static final String TAG_NAME = "decorator-section";
-        private final List<ModelScreenWidget> subWidgets;
-
-        public DecoratorSection(ModelScreen modelScreen, Element decoratorSectionElement) {
-            super(modelScreen, decoratorSectionElement);
-            // read sub-widgets
-            List<? extends Element> subElementList = UtilXml.childElementList(decoratorSectionElement);
-            this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            // render sub-widgets
-            renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
-        }
-
-        public List<ModelScreenWidget> getSubWidgets() {
-            return subWidgets;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-    }
-
-    public static final class DecoratorSectionInclude extends ModelScreenWidget {
-        public static final String TAG_NAME = "decorator-section-include";
-
-        public DecoratorSectionInclude(ModelScreen modelScreen, Element decoratorSectionElement) {
-            super(modelScreen, decoratorSectionElement);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            Map<String, ? extends Object> preRenderedContent = UtilGenerics.checkMap(context.get("preRenderedContent"));
-            if (preRenderedContent != null && preRenderedContent.containsKey(getName())) {
-                try {
-                    writer.append((String) preRenderedContent.get(getName()));
-                } catch (IOException e) {
-                    String errMsg = "Error rendering pre-rendered content in screen named [" + getModelScreen().getName() + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            } else {
-                SectionsRenderer sections = (SectionsRenderer) context.get("sections");
-                // for now if sections is null, just log a warning; may be permissible to make the screen for flexible
-                if (sections == null) {
-                    Debug.logWarning("In decorator-section-include could not find sections object in the context, not rendering section with name [" + getName() + "]", module);
-                } else {
-                    sections.render(getName());
-                }
-            }
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-    }
-
-    public static final class Label extends ModelScreenWidget {
-        public static final String TAG_NAME = "label";
-        private final FlexibleStringExpander textExdr;
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander styleExdr;
-
-        public Label(ModelScreen modelScreen, Element labelElement) {
-            super(modelScreen, labelElement);
-
-            // put the text attribute first, then the pcdata under the element, if both are there of course
-            String textAttr = labelElement.getAttribute("text");
-            String pcdata = UtilXml.elementValue(labelElement);
-            if (pcdata == null) {
-                pcdata = "";
-            }
-            this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata);
-
-            this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id"));
-            this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style"));
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            try {
-                screenStringRenderer.renderLabel(writer, context, this);
-            } catch (IOException e) {
-                String errMsg = "Error rendering label in screen named [" + getModelScreen().getName() + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-
-        public String getText(Map<String, Object> context) {
-            String text = this.textExdr.expandString(context);
-            // FIXME: Encoding should be done by the renderer, not by the model.
-            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-            if (simpleEncoder != null) {
-                text = simpleEncoder.encode(text);
-            }
-            return text;
-        }
-
-        public String getId(Map<String, Object> context) {
-            return this.idExdr.expandString(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return this.styleExdr.expandString(context);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getTextExdr() {
-            return textExdr;
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return idExdr;
-        }
-
-        public FlexibleStringExpander getStyleExdr() {
-            return styleExdr;
-        }
-    }
-
-    public static final class Form extends ModelScreenWidget {
-        public static final String TAG_NAME = "include-form";
-        private final FlexibleStringExpander nameExdr;
-        private final FlexibleStringExpander locationExdr;
-        private final FlexibleStringExpander shareScopeExdr;
-
-        public Form(ModelScreen modelScreen, Element formElement) {
-            super(modelScreen, formElement);
-            this.nameExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("name"));
-            this.locationExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("location"));
-            this.shareScopeExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("share-scope"));
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            // Output format might not support forms, so make form rendering optional.
-            FormStringRenderer formStringRenderer = (FormStringRenderer) context.get("formStringRenderer");
-            if (formStringRenderer == null) {
-                Debug.logVerbose("FormStringRenderer instance not found in rendering context, form not rendered.", module);
-                return;
-            }
-            boolean protectScope = !shareScope(context);
-            if (protectScope) {
-                if (!(context instanceof MapStack<?>)) {
-                    context = MapStack.create(context);
-                }
-                UtilGenerics.<MapStack<String>>cast(context).push();
-            }
-            ModelForm modelForm = getModelForm(context);
-            FormRenderer renderer = new FormRenderer(modelForm, formStringRenderer);
-            try {
-                renderer.render(writer, context);
-            } catch (Exception e) {
-                String errMsg = "Error rendering included form named [" + getName() + "] at location [" + this.getLocation(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg + e);
-            }
-
-            if (protectScope) {
-                UtilGenerics.<MapStack<String>>cast(context).pop();
-            }
-        }
-
-        public ModelForm getModelForm(Map<String, Object> context) {
-            ModelForm modelForm = null;
-            String name = this.getName(context);
-            String location = this.getLocation(context);
-            try {
-                modelForm = FormFactory.getFormFromLocation(location, name, getModelScreen().getDelegator(context).getModelReader(), getModelScreen().getDispatcher(context).getDispatchContext());
-            } catch (Exception e) {
-                String errMsg = "Error rendering included form named [" + name + "] at location [" + location + "]: ";
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg + e);
-            }
-            return modelForm;
-        }
-
-        public String getName(Map<String, Object> context) {
-            return this.nameExdr.expandString(context);
-        }
-
-        public String getLocation() {
-            return locationExdr.getOriginal();
-        }
-
-        public String getLocation(Map<String, Object> context) {
-            return this.locationExdr.expandString(context);
-        }
-
-        public boolean shareScope(Map<String, Object> context) {
-            String shareScopeString = this.shareScopeExdr.expandString(context);
-            // defaults to false, so anything but true is false
-            return "true".equals(shareScopeString);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getNameExdr() {
-            return nameExdr;
-        }
-
-        public FlexibleStringExpander getLocationExdr() {
-            return locationExdr;
-        }
-
-        public FlexibleStringExpander getShareScopeExdr() {
-            return shareScopeExdr;
-        }
-
-    }
-
-    public static final class Tree extends ModelScreenWidget {
-        public static final String TAG_NAME = "include-tree";
-        private final FlexibleStringExpander nameExdr;
-        private final FlexibleStringExpander locationExdr;
-        private final FlexibleStringExpander shareScopeExdr;
-
-        public Tree(ModelScreen modelScreen, Element treeElement) {
-            super(modelScreen, treeElement);
-            this.nameExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("name"));
-            this.locationExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("location"));
-            this.shareScopeExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("share-scope"));
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            // Output format might not support trees, so make tree rendering optional.
-            TreeStringRenderer treeStringRenderer = (TreeStringRenderer) context.get("treeStringRenderer");
-            if (treeStringRenderer == null) {
-                Debug.logVerbose("TreeStringRenderer instance not found in rendering context, tree not rendered.", module);
-                return;
-            }
-            boolean protectScope = !shareScope(context);
-            if (protectScope) {
-                if (!(context instanceof MapStack<?>)) {
-                    context = MapStack.create(context);
-                }
-                UtilGenerics.<MapStack<String>>cast(context).push();
-            }
-
-            String name = this.getName(context);
-            String location = this.getLocation(context);
-            ModelTree modelTree = null;
-            try {
-                modelTree = TreeFactory.getTreeFromLocation(this.getLocation(context), this.getName(context), getModelScreen().getDelegator(context), getModelScreen().getDispatcher(context));
-            } catch (IOException e) {
-                String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (SAXException e) {
-                String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (ParserConfigurationException e) {
-                String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-            modelTree.renderTreeString(writer, context, treeStringRenderer);
-            if (protectScope) {
-                UtilGenerics.<MapStack<String>>cast(context).pop();
-            }
-        }
-
-        public String getName(Map<String, Object> context) {
-            return this.nameExdr.expandString(context);
-        }
-
-        public String getLocation(Map<String, Object> context) {
-            return this.locationExdr.expandString(context);
-        }
-
-        public boolean shareScope(Map<String, Object> context) {
-            String shareScopeString = this.shareScopeExdr.expandString(context);
-            // defaults to false, so anything but true is false
-            return "true".equals(shareScopeString);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getLocationExdr() {
-            return locationExdr;
-        }
-
-        public FlexibleStringExpander getShareScopeExdr() {
-            return shareScopeExdr;
-        }
-    }
-
-    public static final class PlatformSpecific extends ModelScreenWidget {
-        public static final String TAG_NAME = "platform-specific";
-        private final Map<String, ModelScreenWidget> subWidgets;
-
-        public PlatformSpecific(ModelScreen modelScreen, Element platformSpecificElement) {
-            super(modelScreen, platformSpecificElement);
-            Map<String, ModelScreenWidget> subWidgets = new HashMap<String, ModelScreenWidget>();
-            List<? extends Element> childElements = UtilXml.childElementList(platformSpecificElement);
-            if (childElements != null) {
-                for (Element childElement: childElements) {
-                    if ("html".equals(childElement.getNodeName())) {
-                        subWidgets.put("html", new HtmlWidget(modelScreen, childElement));
-                    } else if ("xsl-fo".equals(childElement.getNodeName())) {
-                        subWidgets.put("xsl-fo", new HtmlWidget(modelScreen, childElement));
-                    } else if ("xml".equals(childElement.getNodeName())) {
-                        subWidgets.put("xml", new HtmlWidget(modelScreen, childElement));
-                    } else {
-                        throw new IllegalArgumentException("Tag not supported under the platform-specific tag with name: " + childElement.getNodeName());
-                    }
-                }
-            }
-            this.subWidgets = Collections.unmodifiableMap(subWidgets);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            ModelScreenWidget subWidget = null;
-            subWidget = subWidgets.get(screenStringRenderer.getRendererName());
-            if (subWidget == null) {
-                // This is here for backward compatibility
-                Debug.logWarning("In platform-dependent could not find template for " + screenStringRenderer.getRendererName() + ", using the one for html.", module);
-                subWidget = subWidgets.get("html");
-            }
-            if (subWidget != null) {
-                subWidget.renderWidgetString(writer, context, screenStringRenderer);
-            }
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public Map<String, ModelScreenWidget> getSubWidgets() {
-            return subWidgets;
-        }
-    }
-
-    public static final class Content extends ModelScreenWidget {
-        public static final String TAG_NAME = "content";
-
-        private final FlexibleStringExpander contentId;
-        private final FlexibleStringExpander editRequest;
-        private final FlexibleStringExpander editContainerStyle;
-        private final FlexibleStringExpander enableEditName;
-        private final boolean xmlEscape;
-        private final FlexibleStringExpander dataResourceId;
-        private final String width;
-        private final String height;
-        private final String border;
-
-        public Content(ModelScreen modelScreen, Element subContentElement) {
-            super(modelScreen, subContentElement);
-            this.contentId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("content-id"));
-            this.dataResourceId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("dataresource-id"));
-            this.editRequest = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-request"));
-            this.editContainerStyle = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-container-style"));
-            this.enableEditName = FlexibleStringExpander.getInstance(subContentElement.getAttribute("enable-edit-name"));
-            this.xmlEscape = "true".equals(subContentElement.getAttribute("xml-escape"));
-            String width = subContentElement.getAttribute("width");
-            if (width.isEmpty())
-                width = "60%";
-            this.height = subContentElement.getAttribute("height");
-            if (this.height.isEmpty())
-                width = "400px";
-            this.width = width;
-            this.border = subContentElement.getAttribute("border");
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            try {
-                // pushing the contentId on the context as "contentId" is done
-                // because many times there will be embedded "subcontent" elements
-                // that use the syntax: <subcontent content-id="${contentId}"...
-                // and this is a step to make sure that it is there.
-                Delegator delegator = (Delegator) context.get("delegator");
-                GenericValue content = null;
-                String expandedDataResourceId = getDataResourceId(context);
-                String expandedContentId = getContentId(context);
-                if (!(context instanceof MapStack<?>)) {
-                    context = MapStack.create(context);
-                }
-
-                // This is an important step to make sure that the current contentId is in the context
-                // as templates that contain "subcontent" elements will expect to find the master
-                // contentId in the context as "contentId".
-                UtilGenerics.<MapStack<String>>cast(context).push();
-                context.put("contentId", expandedContentId);
-
-                if (expandedDataResourceId.isEmpty()) {
-                    if (!expandedContentId.isEmpty()) {
-                        content = EntityQuery.use(delegator).from("Content").where("contentId", expandedContentId).cache().queryOne();
-                    } else {
-                        String errMsg = "contentId is empty.";
-                        Debug.logError(errMsg, module);
-                        return;
-                    }
-                    if (content != null) {
-                        expandedDataResourceId = content.getString("dataResourceId");
-                    } else {
-                        String errMsg = "Could not find content with contentId [" + expandedContentId + "] ";
-                        Debug.logError(errMsg, module);
-                        throw new RuntimeException(errMsg);
-                    }
-                }
-
-                GenericValue dataResource = null;
-                if (!expandedDataResourceId.isEmpty()) {
-                    dataResource = EntityQuery.use(delegator).from("DataResource").where("dataResourceId", expandedDataResourceId).cache().queryOne();
-                }
-
-                String mimeTypeId = null;
-                if (dataResource != null) {
-                    mimeTypeId = dataResource.getString("mimeTypeId");
-                }
-                if (content != null) {
-                    mimeTypeId = content.getString("mimeTypeId");
-                }
-
-                if (!(mimeTypeId != null
-                        && ((mimeTypeId.indexOf("application") >= 0) || (mimeTypeId.indexOf("image")) >= 0))) {
-                    screenStringRenderer.renderContentBegin(writer, context, this);
-                    screenStringRenderer.renderContentBody(writer, context, this);
-                    screenStringRenderer.renderContentEnd(writer, context, this);
-                }
-                UtilGenerics.<MapStack<String>>cast(context).pop();
-            } catch (IOException e) {
-                String errMsg = "Error rendering content with contentId [" + getContentId(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (GenericEntityException e) {
-                String errMsg = "Error obtaining content with contentId [" + getContentId(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-
-        }
-
-        public String getContentId(Map<String, Object> context) {
-            return this.contentId.expandString(context);
-        }
-
-        public String getDataResourceId() {
-            return this.dataResourceId.getOriginal();
-        }
-
-        public String getDataResourceId(Map<String, Object> context) {
-            return this.dataResourceId.expandString(context);
-        }
-
-        public String getEditRequest(Map<String, Object> context) {
-            return this.editRequest.expandString(context);
-        }
-
-        public String getEditContainerStyle(Map<String, Object> context) {
-            return this.editContainerStyle.expandString(context);
-        }
-
-        public String getEnableEditName(Map<String, Object> context) {
-            return this.enableEditName.expandString(context);
-        }
-
-        public boolean xmlEscape() {
-            return this.xmlEscape;
-        }
-
-        public String getWidth() {
-            return this.width;
-        }
-
-        public String getHeight() {
-            return this.height;
-        }
-
-        public String getBorder() {
-            return this.border;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getContentId() {
-            return contentId;
-        }
-
-        public FlexibleStringExpander getEditRequest() {
-            return editRequest;
-        }
-
-        public FlexibleStringExpander getEditContainerStyle() {
-            return editContainerStyle;
-        }
-
-        public FlexibleStringExpander getEnableEditName() {
-            return enableEditName;
-        }
-    }
-
-    public static final class SubContent extends ModelScreenWidget {
-        public static final String TAG_NAME = "sub-content";
-        private final FlexibleStringExpander contentId;
-        private final FlexibleStringExpander mapKey;
-        private final FlexibleStringExpander editRequest;
-        private final FlexibleStringExpander editContainerStyle;
-        private final FlexibleStringExpander enableEditName;
-        private final boolean xmlEscape;
-
-        public SubContent(ModelScreen modelScreen, Element subContentElement) {
-            super(modelScreen, subContentElement);
-            this.contentId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("content-id"));
-            String mapKey = subContentElement.getAttribute("map-key");
-            if (mapKey.isEmpty()) {
-                mapKey = subContentElement.getAttribute("assoc-name");
-            }
-            this.mapKey = FlexibleStringExpander.getInstance(mapKey);
-            this.editRequest = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-request"));
-            this.editContainerStyle = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-container-style"));
-            this.enableEditName = FlexibleStringExpander.getInstance(subContentElement.getAttribute("enable-edit-name"));
-            this.xmlEscape = "true".equals(subContentElement.getAttribute("xml-escape"));
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            try {
-                screenStringRenderer.renderSubContentBegin(writer, context, this);
-                screenStringRenderer.renderSubContentBody(writer, context, this);
-                screenStringRenderer.renderSubContentEnd(writer, context, this);
-            } catch (IOException e) {
-                String errMsg = "Error rendering subContent with contentId [" + getContentId(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-
-        public String getContentId(Map<String, Object> context) {
-            return this.contentId.expandString(context);
-        }
-
-        public String getMapKey(Map<String, Object> context) {
-            return this.mapKey.expandString(context);
-        }
-
-        public String getEditRequest(Map<String, Object> context) {
-            return this.editRequest.expandString(context);
-        }
-
-        public String getEditContainerStyle(Map<String, Object> context) {
-            return this.editContainerStyle.expandString(context);
-        }
-
-        public String getEnableEditName(Map<String, Object> context) {
-            return this.enableEditName.expandString(context);
-        }
-
-        public boolean xmlEscape() {
-            return this.xmlEscape;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            // TODO Auto-generated method stub
-            
-        }
-    }
-
-    public static final class Menu extends ModelScreenWidget {
-        public static final String TAG_NAME = "include-menu";
-        private final FlexibleStringExpander nameExdr;
-        private final FlexibleStringExpander locationExdr;
-
-        public Menu(ModelScreen modelScreen, Element menuElement) {
-            super(modelScreen, menuElement);
-            this.nameExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("name"));
-            this.locationExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("location"));
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) 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.getName(context);
-            String location = this.getLocation(context);
-            ModelMenu modelMenu = null;
-            try {
-                modelMenu = MenuFactory.getMenuFromLocation(location, name);
-            } catch (Exception e) {
-                String errMsg = "Error rendering included menu named [" + name + "] at location [" + location + "]: ";
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg + e);
-            }
-            return modelMenu;
-        }
-
-        public String getName(Map<String, Object> context) {
-            return this.nameExdr.expandString(context);
-        }
-
-        public String getLocation(Map<String, Object> context) {
-            return this.locationExdr.expandString(context);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getLocationExdr() {
-            return locationExdr;
-        }
-    }
-
-    public static final class ScreenLink extends ModelScreenWidget {
-        public static final String TAG_NAME = "link";
-        private final Link link;
-        private final ScreenImage image;
-
-        public ScreenLink(ModelScreen modelScreen, Element linkElement) {
-            super(modelScreen, linkElement);
-            this.link = new Link(linkElement);
-            Element imageElement = UtilXml.firstChildElement(linkElement, "image");
-            if (imageElement != null) {
-                this.image = new ScreenImage(modelScreen, imageElement);
-            } else {
-                this.image = null;
-            }
-        }
-
-        public String getName() {
-            return link.getName();
-        }
-
-        public String getText(Map<String, Object> context) {
-            return link.getText(context);
-        }
-
-        public String getId(Map<String, Object> context) {
-            return link.getId(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return link.getStyle(context);
-        }
-
-        public String getTarget(Map<String, Object> context) {
-            return link.getTarget(context);
-        }
-
-        public String getName(Map<String, Object> context) {
-            return link.getName(context);
-        }
-
-        public String getTargetWindow(Map<String, Object> context) {
-            return link.getTargetWindow(context);
-        }
-
-        public String getUrlMode() {
-            return link.getUrlMode();
-        }
-
-        public String getPrefix(Map<String, Object> context) {
-            return link.getPrefix(context);
-        }
-
-        public boolean getFullPath() {
-            return link.getFullPath();
-        }
-
-        public boolean getSecure() {
-            return link.getSecure();
-        }
-
-        public boolean getEncode() {
-            return link.getEncode();
-        }
-
-        public ScreenImage getImage() {
-            return image;
-        }
-
-        public String getLinkType() {
-            return link.getLinkType();
-        }
-
-        public String getWidth() {
-            return link.getWidth();
-        }
-
-        public String getHeight() {
-            return link.getHeight();
-        }
-
-        public Map<String, String> getParameterMap(Map<String, Object> context) {
-            return link.getParameterMap(context);
-        }
-
-        public FlexibleStringExpander getTextExdr() {
-            return link.getTextExdr();
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return link.getIdExdr();
-        }
-
-        public FlexibleStringExpander getStyleExdr() {
-            return link.getStyleExdr();
-        }
-
-        public FlexibleStringExpander getTargetExdr() {
-            return link.getTargetExdr();
-        }
-
-        public FlexibleStringExpander getTargetWindowExdr() {
-            return link.getTargetWindowExdr();
-        }
-
-        public FlexibleStringExpander getPrefixExdr() {
-            return link.getPrefixExdr();
-        }
-
-        public FlexibleStringExpander getNameExdr() {
-            return link.getNameExdr();
-        }
-
-        public List<Parameter> getParameterList() {
-            return link.getParameterList();
-        }
-
-        public AutoServiceParameters getAutoServiceParameters() {
-            return link.getAutoServiceParameters();
-        }
-
-        public AutoEntityParameters getAutoEntityParameters() {
-            return link.getAutoEntityParameters();
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            try {
-                screenStringRenderer.renderLink(writer, context, this);
-            } catch (IOException e) {
-                String errMsg = "Error rendering link with id [" + link.getId(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public Link getLink() {
-            return link;
-        }
-    }
-
-    public static final class ScreenImage extends ModelScreenWidget {
-        public static final String TAG_NAME = "image";
-        private final Image image;
-
-        public String getName() {
-            return image.getName();
-        }
-
-        public String getSrc(Map<String, Object> context) {
-            return image.getSrc(context);
-        }
-
-        public String getId(Map<String, Object> context) {
-            return image.getId(context);
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            return image.getStyle(context);
-        }
-
-        public String getWidth(Map<String, Object> context) {
-            return image.getWidth(context);
-        }
-
-        public String getHeight(Map<String, Object> context) {
-            return image.getHeight(context);
-        }
-
-        public String getBorder(Map<String, Object> context) {
-            return image.getBorder(context);
-        }
-
-        public String getAlt(Map<String, Object> context) {
-            return image.getAlt(context);
-        }
-
-        public String getUrlMode() {
-            return image.getUrlMode();
-        }
-
-        public FlexibleStringExpander getSrcExdr() {
-            return image.getSrcExdr();
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return image.getIdExdr();
-        }
-
-        public FlexibleStringExpander getStyleExdr() {
-            return image.getStyleExdr();
-        }
-
-        public FlexibleStringExpander getWidthExdr() {
-            return image.getWidthExdr();
-        }
-
-        public FlexibleStringExpander getHeightExdr() {
-            return image.getHeightExdr();
-        }
-
-        public FlexibleStringExpander getBorderExdr() {
-            return image.getBorderExdr();
-        }
-
-        public FlexibleStringExpander getAlt() {
-            return image.getAlt();
-        }
-
-        public ScreenImage(ModelScreen modelScreen, Element imageElement) {
-            super(modelScreen, imageElement);
-            this.image = new Image(imageElement);
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
-            try {
-                screenStringRenderer.renderImage(writer, context, this);
-            } catch (IOException e) {
-                String errMsg = "Error rendering image with id [" + image.getId(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public Image getImage() {
-            return image;
-        }
-    }
-
-    public static final class PortalPage extends ModelScreenWidget {
-        public static final String TAG_NAME = "include-portal-page";
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander confModeExdr;
-        private final Boolean usePrivate;
-
-        public PortalPage(ModelScreen modelScreen, Element portalPageElement) {
-            super(modelScreen, portalPageElement);
-            this.idExdr = FlexibleStringExpander.getInstance(portalPageElement.getAttribute("id"));
-            this.confModeExdr = FlexibleStringExpander.getInstance(portalPageElement.getAttribute("conf-mode"));
-            this.usePrivate = !("false".equals(portalPageElement.getAttribute("use-private")));
-        }
-
-        private GenericValue getPortalPageValue(Map<String, Object> context) {
-            Delegator delegator = (Delegator) context.get("delegator");
-            String expandedPortalPageId = getId(context);
-            GenericValue portalPage = null;
-            if (!expandedPortalPageId.isEmpty()) {
-                if (usePrivate) {
-                    portalPage = PortalPageWorker.getPortalPage(expandedPortalPageId, context);
-                } else {
-                    try {
-                        portalPage = EntityQuery.use(delegator)
-                                                .from("PortalPage")
-                                                .where("portalPageId", expandedPortalPageId)
-                                                .cache().queryOne();
-                    } catch (GenericEntityException e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            }
-            if (portalPage == null) {
-                String errMsg = "Could not find PortalPage with portalPageId [" + expandedPortalPageId + "] ";
-                Debug.logError(errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-            return portalPage;
-        }
-
-        @Override
-        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-            try {
-                Delegator delegator = (Delegator) context.get("delegator");
-                List<GenericValue> portalPageColumns = null;
-                List<GenericValue> portalPagePortlets = null;
-                List<GenericValue> portletAttributes = null;
-                GenericValue portalPage = getPortalPageValue(context);
-                String actualPortalPageId = portalPage.getString("portalPageId");
-                portalPageColumns = EntityQuery.use(delegator)
-                                               .from("PortalPageColumn")
-                                               .where("portalPageId", actualPortalPageId)
-                                               .orderBy("columnSeqId")
-                                               .cache(true)
-                                               .queryList();
-                
-                // Renders the portalPage header
-                screenStringRenderer.renderPortalPageBegin(writer, context, this);
-                
-                // First column has no previous column
-                String prevColumnSeqId = "";
-                
-                // Iterates through the PortalPage columns
-                ListIterator <GenericValue>columnsIterator = portalPageColumns.listIterator();
-                while(columnsIterator.hasNext()) {
-                    GenericValue columnValue = columnsIterator.next();
-                    String columnSeqId = columnValue.getString("columnSeqId");
-                    
-                    // Renders the portalPageColumn header
-                    screenStringRenderer.renderPortalPageColumnBegin(writer, context, this, columnValue);
-
-                    // Get the Portlets located in the current column
-                    portalPagePortlets = EntityQuery.use(delegator)
-                                                    .from("PortalPagePortletView")
-                                                    .where("portalPageId", portalPage.getString("portalPageId"), "columnSeqId", columnSeqId)
-                                                    .orderBy("sequenceNum")
-                                                    .queryList();
-                    // First Portlet in a Column has no previous Portlet
-                    String prevPortletId = "";
-                    String prevPortletSeqId = "";
-
-                    // If this is not the last column, get the next columnSeqId
-                    String nextColumnSeqId = "";
-                    if (columnsIterator.hasNext()) {
-                        nextColumnSeqId = portalPageColumns.get(columnsIterator.nextIndex()).getString("columnSeqId");
-                    }
-                    
-                    // Iterates through the Portlets in the Column
-                    ListIterator <GenericValue>portletsIterator = portalPagePortlets.listIterator();
-                    while(portletsIterator.hasNext()) {
-                        GenericValue portletValue = portletsIterator.next();
-
-                        // If not the last portlet in the column, get the next nextPortletId and nextPortletSeqId
-                        String nextPortletId = "";
-                        String nextPortletSeqId = "";
-                        if (portletsIterator.hasNext()) {
-                            nextPortletId = portalPagePortlets.get(portletsIterator.nextIndex()).getString("portalPortletId");
-                            nextPortletSeqId = portalPagePortlets.get(portletsIterator.nextIndex()).getString("portletSeqId");
-                        }
-
-                        // Set info to allow portlet movement in the page
-                        context.put("prevPortletId", prevPortletId);
-                        context.put("prevPortletSeqId", prevPortletSeqId);
-                        context.put("nextPortletId", nextPortletId);
-                        context.put("nextPortletSeqId", nextPortletSeqId);
-                        context.put("prevColumnSeqId", prevColumnSeqId);
-                        context.put("nextColumnSeqId", nextColumnSeqId);
-                       
-                        // Get portlet's attributes
-                        portletAttributes = EntityQuery.use(delegator)
-                                                       .from("PortletAttribute")
-                                                       .where("portalPageId", portletValue.get("portalPageId"), "portalPortletId", portletValue.get("portalPortletId"), "portletSeqId", portletValue.get("portletSeqId"))
-                                                       .queryList();
-                        
-                        ListIterator <GenericValue>attributesIterator = portletAttributes.listIterator();
-                        while (attributesIterator.hasNext()) {
-                            GenericValue attribute = attributesIterator.next();
-                            context.put(attribute.getString("attrName"), attribute.getString("attrValue"));
-                        }
-                        
-                        // Renders the portalPagePortlet
-                        screenStringRenderer.renderPortalPagePortletBegin(writer, context, this, portletValue);
-                        screenStringRenderer.renderPortalPagePortletBody(writer, context, this, portletValue);
-                        screenStringRenderer.renderPortalPagePortletEnd(writer, context, this, portletValue);
-
-                        // Remove the portlet's attributes so that these are not available for other portlets
-                        while (attributesIterator.hasPrevious()) {
-                            GenericValue attribute = attributesIterator.previous();
-                            context.remove(attribute.getString("attrName"));
-                        }
-                        
-                        // Uses the actual portlet as prevPortlet for next iteration
-                        prevPortletId = (String) portletValue.get("portalPortletId");
-                        prevPortletSeqId = (String) portletValue.get("portletSeqId");
-                    }
-                    // Renders the portalPageColumn footer
-                    screenStringRenderer.renderPortalPageColumnEnd(writer, context, this, columnValue);
-
-                    // Uses the actual columnSeqId as prevColumnSeqId for next iteration
-                    prevColumnSeqId = columnSeqId;
-                }
-                // Renders the portalPage footer
-                screenStringRenderer.renderPortalPageEnd(writer, context, this);
-            } catch (IOException e) {
-                String errMsg = "Error rendering PortalPage with portalPageId [" + getId(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (GenericEntityException e) {
-                String errMsg = "Error obtaining PortalPage with portalPageId [" + getId(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-
-        public String getId(Map<String, Object> context) {
-            return this.idExdr.expandString(context);
-        }
-
-        public String getOriginalPortalPageId(Map<String, Object> context) {
-            GenericValue portalPage = getPortalPageValue(context);
-            return portalPage.getString("originalPortalPageId");
-        }
-        
-        public String getActualPortalPageId(Map<String, Object> context) {
-            GenericValue portalPage = getPortalPageValue(context);
-            return portalPage.getString("portalPageId");
-        }
-
-        public String getConfMode(Map<String, Object> context) {
-            return this.confModeExdr.expandString(context);
-        }
-
-        public String getUsePrivate() {
-            return Boolean.toString(this.usePrivate);
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getIdExdr() {
-            return idExdr;
-        }
-
-        public FlexibleStringExpander getConfModeExdr() {
-            return confModeExdr;
-        }
-    }
-
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
+import org.ofbiz.widget.WidgetFactory;
+import org.ofbiz.widget.model.CommonWidgetModels.AutoEntityParameters;
+import org.ofbiz.widget.model.CommonWidgetModels.AutoServiceParameters;
+import org.ofbiz.widget.model.CommonWidgetModels.Image;
+import org.ofbiz.widget.model.CommonWidgetModels.Link;
+import org.ofbiz.widget.model.CommonWidgetModels.Parameter;
+import org.ofbiz.widget.portal.PortalPageWorker;
+import org.ofbiz.widget.renderer.FormRenderer;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.TreeStringRenderer;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Widget Library - Screen model class
+ */
+@SuppressWarnings("serial")
+public abstract class ModelScreenWidget extends ModelWidget {
+    public static final String module = ModelScreenWidget.class.getName();
+
+    private final ModelScreen modelScreen;
+
+    public ModelScreenWidget(ModelScreen modelScreen, Element widgetElement) {
+        super(widgetElement);
+        this.modelScreen = modelScreen;
+        if (Debug.verboseOn()) Debug.logVerbose("Reading Screen sub-widget with name: " + widgetElement.getNodeName(), module);
+    }
+
+    public abstract void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException;
+
+    protected static List<ModelScreenWidget> readSubWidgets(ModelScreen modelScreen, List<? extends Element> subElementList) {
+        if (subElementList.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(subElementList.size());
+        for (Element subElement: subElementList) {
+            subWidgets.add(WidgetFactory.getModelScreenWidget(modelScreen, subElement));
+        }
+        return Collections.unmodifiableList(subWidgets);
+    }
+
+    protected static void renderSubWidgetsString(List<ModelScreenWidget> subWidgets, Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+        if (subWidgets == null) {
+            return;
+        }
+        for (ModelScreenWidget subWidget: subWidgets) {
+            if (Debug.verboseOn()) Debug.logVerbose("Rendering screen " + subWidget.getModelScreen().getName() + "; widget class is " + subWidget.getClass().getName(), module);
+
+            // render the sub-widget itself
+            subWidget.renderWidgetString(writer, context, screenStringRenderer);
+        }
+    }
+
+    public ModelScreen getModelScreen() {
+        return this.modelScreen;
+    }
+
+    public static final class SectionsRenderer implements Map<String, ModelScreenWidget> {
+        private final Map<String, ModelScreenWidget> sectionMap;
+        private final ScreenStringRenderer screenStringRenderer;
+        private final Map<String, Object> context;
+        private final Appendable writer;
+
+        public SectionsRenderer(Map<String, ModelScreenWidget> sectionMap, Map<String, Object> context, Appendable writer,
+                ScreenStringRenderer screenStringRenderer) {
+            Map<String, ModelScreenWidget> localMap = new HashMap<String, ModelScreenWidget>();
+            localMap.putAll(sectionMap);
+            this.sectionMap = Collections.unmodifiableMap(localMap);
+            this.context = context;
+            this.writer = writer;
+            this.screenStringRenderer = screenStringRenderer;
+        }
+
+        /** This is a lot like the ScreenRenderer class and returns an empty String so it can be used more easily with FreeMarker */
+        public String render(String sectionName) throws GeneralException, IOException {
+            ModelScreenWidget section = sectionMap.get(sectionName);
+            // if no section by that name, write nothing
+            if (section != null) {
+                section.renderWidgetString(this.writer, this.context, this.screenStringRenderer);
+            }
+            return "";
+        }
+
+        @Override
+        public int size() {
+            return sectionMap.size();
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return sectionMap.isEmpty();
+        }
+
+        @Override
+        public boolean containsKey(Object key) {
+            return sectionMap.containsKey(key);
+        }
+
+        @Override
+        public boolean containsValue(Object value) {
+            return sectionMap.containsValue(value);
+        }
+
+        @Override
+        public ModelScreenWidget get(Object key) {
+            return sectionMap.get(key);
+        }
+
+        @Override
+        public ModelScreenWidget put(String key, ModelScreenWidget value) {
+            return sectionMap.put(key, value);
+        }
+
+        @Override
+        public ModelScreenWidget remove(Object key) {
+            return sectionMap.remove(key);
+        }
+
+        @Override
+        public void clear() {
+            sectionMap.clear();
+        }
+
+        @Override
+        public Set<String> keySet() {
+            return sectionMap.keySet();
+        }
+
+        @Override
+        public Collection<ModelScreenWidget> values() {
+            return sectionMap.values();
+        }
+
+        @Override
+        public Set<java.util.Map.Entry<String, ModelScreenWidget>> entrySet() {
+            return sectionMap.entrySet();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return sectionMap.equals(o);
+        }
+
+        @Override
+        public int hashCode() {
+            return sectionMap.hashCode();
+        }
+
+        @Override
+        public void putAll(Map<? extends String, ? extends ModelScreenWidget> m) {
+            sectionMap.putAll(m);
+        }
+    }
+
+    public static final class Section extends ModelScreenWidget {
+        public static final String TAG_NAME = "section";
+        private final ModelCondition condition;
+        private final List<ModelAction> actions;
+        private final List<ModelScreenWidget> subWidgets;
+        private final List<ModelScreenWidget> failWidgets;
+        private final boolean isMainSection;
+
+        public Section(ModelScreen modelScreen, Element sectionElement) {
+            this(modelScreen, sectionElement, false);
+        }
+
+        public Section(ModelScreen modelScreen, Element sectionElement, boolean isMainSection) {
+            super(modelScreen, sectionElement);
+
+            // read condition under the "condition" element
+            Element conditionElement = UtilXml.firstChildElement(sectionElement, "condition");
+            if (conditionElement != null) {
+                conditionElement = UtilXml.firstChildElement(conditionElement);
+                this.condition = ModelScreenCondition.SCREEN_CONDITION_FACTORY.newInstance(modelScreen, conditionElement);
+            } else {
+                this.condition = null;
+            }
+
+            // read all actions under the "actions" element
+            Element actionsElement = UtilXml.firstChildElement(sectionElement, "actions");
+            if (actionsElement != null) {
+                this.actions = AbstractModelAction.readSubActions(modelScreen, actionsElement);
+            } else {
+                this.actions = Collections.emptyList();
+            }
+
+            // read sub-widgets
+            Element widgetsElement = UtilXml.firstChildElement(sectionElement, "widgets");
+            if (widgetsElement != null) {
+                List<? extends Element> subElementList = UtilXml.childElementList(widgetsElement);
+                this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList);
+            } else {
+                this.subWidgets = Collections.emptyList();
+            }
+
+            // read fail-widgets
+            Element failWidgetsElement = UtilXml.firstChildElement(sectionElement, "fail-widgets");
+            if (failWidgetsElement != null) {
+                List<? extends Element> failElementList = UtilXml.childElementList(failWidgetsElement);
+                this.failWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), failElementList);
+            } else {
+                this.failWidgets = Collections.emptyList();
+            }
+            this.isMainSection = isMainSection;
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            // check the condition, if there is one
+            boolean condTrue = true;
+            if (this.condition != null) {
+                if (!this.condition.eval(context)) {
+                    condTrue = false;
+                }
+            }
+
+            // if condition does not exist or evals to true run actions and render widgets, otherwise render fail-widgets
+            if (condTrue) {
+                // run the actions only if true
+                AbstractModelAction.runSubActions(this.actions, context);
+
+                try {
+                    // section by definition do not themselves do anything, so this method will generally do nothing, but we'll call it anyway
+                    screenStringRenderer.renderSectionBegin(writer, context, this);
+
+                    // render sub-widgets
+                    renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
+
+                    screenStringRenderer.renderSectionEnd(writer, context, this);
+                } catch (IOException e) {
+                    String errMsg = "Error rendering widgets section [" + getName() + "] in screen named [" + getModelScreen().getName() + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
+            } else {
+                try {
+                    // section by definition do not themselves do anything, so this method will generally do nothing, but we'll call it anyway
+                    screenStringRenderer.renderSectionBegin(writer, context, this);
+
+                    // render sub-widgets
+                    renderSubWidgetsString(this.failWidgets, writer, context, screenStringRenderer);
+
+                    screenStringRenderer.renderSectionEnd(writer, context, this);
+                } catch (IOException e) {
+                    String errMsg = "Error rendering fail-widgets section [" + this.getName() + "] in screen named [" + getModelScreen().getName() + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
+            }
+
+        }
+
+        @Override
+        public String getBoundaryCommentName() {
+            if (isMainSection) {
+                return getModelScreen().getSourceLocation() + "#" + getModelScreen().getName();
+            } else {
+                return getName();
+            }
+        }
+
+        public List<ModelAction> getActions() {
+            return actions;
+        }
+
+        public List<ModelScreenWidget> getSubWidgets() {
+            return subWidgets;
+        }
+
+        public List<ModelScreenWidget> getFailWidgets() {
+            return failWidgets;
+        }
+
+        public boolean isMainSection() {
+            return isMainSection;
+        }
+
+        public ModelCondition getCondition() {
+            return condition;
+        }
+    }
+
+    public static final class ColumnContainer extends ModelScreenWidget {
+        public static final String TAG_NAME = "column-container";
+        private final FlexibleStringExpander idExdr;
+        private final FlexibleStringExpander styleExdr;
+        private final List<Column> columns;
+
+        public ColumnContainer(ModelScreen modelScreen, Element containerElement) {
+            super(modelScreen, containerElement);
+            this.idExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("id"));
+            this.styleExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("style"));
+            List<? extends Element> subElementList = UtilXml.childElementList(containerElement, "column");
+            List<Column> columns = new ArrayList<Column>(subElementList.size());
+            for (Element element : subElementList) {
+                columns.add(new Column(modelScreen, element));
+            }
+            this.columns = Collections.unmodifiableList(columns);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            try {
+                screenStringRenderer.renderColumnContainer(writer, context, this);
+            } catch (IOException e) {
+                String errMsg = "Error rendering container in screen named [" + getModelScreen().getName() + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        }
+
+        public List<Column> getColumns() {
+            return this.columns;
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.styleExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return styleExdr;
+        }
+    }
+
+    public static final class Column extends ModelWidget {
+        private final FlexibleStringExpander idExdr;
+        private final FlexibleStringExpander styleExdr;
+        private final List<ModelScreenWidget> subWidgets;
+
+        public Column(ModelScreen modelScreen, Element columnElement) {
+            super(columnElement);
+            this.idExdr = FlexibleStringExpander.getInstance(columnElement.getAttribute("id"));
+            this.styleExdr = FlexibleStringExpander.getInstance(columnElement.getAttribute("style"));
+            List<? extends Element> subElementList = UtilXml.childElementList(columnElement);
+            this.subWidgets = Collections.unmodifiableList(readSubWidgets(modelScreen, subElementList));
+        }
+
+        public List<ModelScreenWidget> getSubWidgets() {
+            return this.subWidgets;
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.styleExdr.expandString(context);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return styleExdr;
+        }
+    }
+
+    public static final class Container extends ModelScreenWidget {
+        public static final String TAG_NAME = "container";
+        private final FlexibleStringExpander idExdr;
+        private final FlexibleStringExpander styleExdr;
+        private final FlexibleStringExpander autoUpdateTargetExdr;
+        private final FlexibleStringExpander autoUpdateInterval;
+        private final List<ModelScreenWidget> subWidgets;
+
+        public Container(ModelScreen modelScreen, Element containerElement) {
+            super(modelScreen, containerElement);
+            this.idExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("id"));
+            this.styleExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("style"));
+            this.autoUpdateTargetExdr = FlexibleStringExpander.getInstance(containerElement.getAttribute("auto-update-target"));
+            String autoUpdateInterval = containerElement.getAttribute("auto-update-interval");
+            if (autoUpdateInterval.isEmpty()) {
+                autoUpdateInterval = "2";
+            }
+            this.autoUpdateInterval = FlexibleStringExpander.getInstance(autoUpdateInterval);
+            // read sub-widgets
+            List<? extends Element> subElementList = UtilXml.childElementList(containerElement);
+            this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            try {
+                screenStringRenderer.renderContainerBegin(writer, context, this);
+
+                // render sub-widgets
+                renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
+
+                screenStringRenderer.renderContainerEnd(writer, context, this);
+            } catch (IOException e) {
+                String errMsg = "Error rendering container in screen named [" + getModelScreen().getName() + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.styleExdr.expandString(context);
+        }
+
+        public String getAutoUpdateTargetExdr(Map<String, Object> context) {
+            return this.autoUpdateTargetExdr.expandString(context);
+        }
+
+        public String getAutoUpdateInterval(Map<String, Object> context) {
+            return this.autoUpdateInterval.expandString(context);
+        }
+
+        public List<ModelScreenWidget> getSubWidgets() {
+            return subWidgets;
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return styleExdr;
+        }
+
+        public FlexibleStringExpander getAutoUpdateTargetExdr() {
+            return autoUpdateTargetExdr;
+        }
+
+        public FlexibleStringExpander getAutoUpdateInterval() {
+            return autoUpdateInterval;
+        }
+    }
+
+    public static final class Screenlet extends ModelScreenWidget {
+        public static final String TAG_NAME = "screenlet";
+        private final FlexibleStringExpander idExdr;
+        private final FlexibleStringExpander titleExdr;
+        private final Menu navigationMenu;
+        private final Menu tabMenu;
+        private final Form navigationForm;
+        private final boolean collapsible;
+        private final FlexibleStringExpander initiallyCollapsed;
+        private final boolean saveCollapsed;
+        private final boolean padded;
+        private final List<ModelScreenWidget> subWidgets;
+
+        public Screenlet(ModelScreen modelScreen, Element screenletElement) {
+            super(modelScreen, screenletElement);
+            this.idExdr = FlexibleStringExpander.getInstance(screenletElement.getAttribute("id"));
+            boolean collapsible = "true".equals(screenletElement.getAttribute("collapsible"));
+            this.initiallyCollapsed = FlexibleStringExpander.getInstance(screenletElement.getAttribute("initially-collapsed"));
+            if ("true".equals(this.initiallyCollapsed.getOriginal())) {
+                collapsible = true;
+            }
+            this.collapsible = collapsible;
+            // By default, for a collapsible screenlet, the collapsed/expanded status must be saved
+            this.saveCollapsed = !("false".equals(screenletElement.getAttribute("save-collapsed")));
+
+            boolean padded = !"false".equals(screenletElement.getAttribute("padded"));
+            if (this.collapsible && getName().isEmpty() && idExdr.isEmpty()) {
+                throw new IllegalArgumentException("Collapsible screenlets must have a name or id [" + getModelScreen().getName() + "]");
+            }
+            this.titleExdr = FlexibleStringExpander.getInstance(screenletElement.getAttribute("title"));
+            List<? extends Element> subElementList = UtilXml.childElementList(screenletElement);
+            // Make a copy of the unmodifiable List so we can modify it.
+            ArrayList<ModelScreenWidget> subWidgets = new ArrayList<ModelScreenWidget>(ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList));
+            Menu navigationMenu = null;
+            String navMenuName = screenletElement.getAttribute("navigation-menu-name");
+            if (!navMenuName.isEmpty()) {
+                for (ModelWidget subWidget : subWidgets) {
+                    if (navMenuName.equals(subWidget.getName()) && subWidget instanceof Menu) {
+                        navigationMenu = (Menu) subWidget;
+                        subWidgets.remove(subWidget);
+                        break;
+                    }
+                }
+            }
+            this.navigationMenu = navigationMenu;
+            Menu tabMenu = null;
+            String tabMenuName = screenletElement.getAttribute("tab-menu-name");
+            if (!tabMenuName.isEmpty()) {
+                for (ModelWidget subWidget : subWidgets) {
+                    if (tabMenuName.equals(subWidget.getName()) && subWidget instanceof Menu) {
+                        tabMenu = (Menu) subWidget;
+                        subWidgets.remove(subWidget);
+                        break;
+                    }
+                }
+            }
+            this.tabMenu = tabMenu;
+            Form navigationForm = null;
+            String formName = screenletElement.getAttribute("navigation-form-name");
+            if (!formName.isEmpty() && this.navigationMenu == null) {
+                for (ModelWidget subWidget : subWidgets) {
+                    if (formName.equals(subWidget.getName()) && subWidget instanceof Form) {
+                        navigationForm = (Form) subWidget;
+                        padded = false;
+                        break;
+                    }
+                }
+            }
+            this.subWidgets = Collections.unmodifiableList(subWidgets);
+            this.navigationForm = navigationForm;
+            this.padded = padded;
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            boolean collapsed = getInitiallyCollapsed(context);
+            if (this.collapsible) {
+                String preferenceKey = getPreferenceKey(context) + "_collapsed";
+                Map<String, Object> requestParameters = UtilGenerics.checkMap(context.get("requestParameters"));
+                if (requestParameters != null) {
+                    String collapsedParam = (String) requestParameters.get(preferenceKey);
+                    collapsed = "true".equals(collapsedParam);
+                }
+            }
+            try {
+                screenStringRenderer.renderScreenletBegin(writer, context, collapsed, this);
+                for (ModelScreenWidget subWidget : this.subWidgets) {
+                    screenStringRenderer.renderScreenletSubWidget(writer, context, subWidget, this);
+                }
+                screenStringRenderer.renderScreenletEnd(writer, context, this);
+            } catch (IOException e) {
+                String errMsg = "Error rendering screenlet in screen named [" + getModelScreen().getName() + "]: ";
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg + e);
+            }
+        }
+
+        public boolean collapsible() {
+            return this.collapsible;
+        }
+
+        //initially-collapsed status, which may be overriden by user preference
+        public boolean getInitiallyCollapsed(Map<String, Object> context) {
+            String screenletId = this.getId(context) + "_collapsed";
+            Map<String, ? extends Object> userPreferences = UtilGenerics.checkMap(context.get("userPreferences"));
+            if (userPreferences != null && userPreferences.containsKey(screenletId)) {
+                return Boolean.valueOf((String)userPreferences.get(screenletId)).booleanValue() ;
+            }
+
+            return "true".equals(this.initiallyCollapsed.expand(context));
+        }
+
+        public boolean saveCollapsed() {
+            return this.saveCollapsed;
+        }
+        public boolean padded() {
+            return this.padded;
+        }
+
+        public String getPreferenceKey(Map<String, Object> context) {
+            String name = this.idExdr.expandString(context);
+            if (name.isEmpty()) {
+                name = "screenlet" + "_" + Integer.toHexString(hashCode());
+            }
+            return name;
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public List<ModelScreenWidget> getSubWidgets() {
+            return subWidgets;
+        }
+
+        public String getTitle(Map<String, Object> context) {
+            String title = this.titleExdr.expandString(context);
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+            if (simpleEncoder != null) {
+                title = simpleEncoder.encode(title);
+            }
+            return title;
+        }
+
+        public Menu getNavigationMenu() {
+            return this.navigationMenu;
+        }
+
+        public Form getNavigationForm() {
+            return this.navigationForm;
+        }
+
+        public Menu getTabMenu() {
+            return this.tabMenu;
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public FlexibleStringExpander getTitleExdr() {
+            return titleExdr;
+        }
+
+        public boolean getCollapsible() {
+            return collapsible;
+        }
+
+        public FlexibleStringExpander getInitiallyCollapsed() {
+            return initiallyCollapsed;
+        }
+
+        public boolean getSaveCollapsed() {
+            return saveCollapsed;
+        }
+
+        public boolean getPadded() {
+            return padded;
+        }
+    }
+
+    public static final class HorizontalSeparator extends ModelScreenWidget {
+        public static final String TAG_NAME = "horizontal-separator";
+        private final FlexibleStringExpander idExdr;
+        private final FlexibleStringExpander styleExdr;
+
+        public HorizontalSeparator(ModelScreen modelScreen, Element separatorElement) {
+            super(modelScreen, separatorElement);
+            this.idExdr = FlexibleStringExpander.getInstance(separatorElement.getAttribute("id"));
+            this.styleExdr = FlexibleStringExpander.getInstance(separatorElement.getAttribute("style"));
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            screenStringRenderer.renderHorizontalSeparator(writer, context, this);
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.styleExdr.expandString(context);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return styleExdr;
+        }
+    }
+
+    public static final class IncludeScreen extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-screen";
+        private final FlexibleStringExpander nameExdr;
+        private final FlexibleStringExpander locationExdr;
+        private final FlexibleStringExpander shareScopeExdr;
+
+        public IncludeScreen(ModelScreen modelScreen, Element includeScreenElement) {
+            super(modelScreen, includeScreenElement);
+            this.nameExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("name"));
+            this.locationExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("location"));
+            this.shareScopeExdr = FlexibleStringExpander.getInstance(includeScreenElement.getAttribute("share-scope"));
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            // if we are not sharing the scope, protect it using the MapStack
+            boolean protectScope = !shareScope(context);
+            if (protectScope) {
+                if (!(context instanceof MapStack<?>)) {
+                    context = MapStack.create(context);
+                }
+
+                UtilGenerics.<MapStack<String>>cast(context).push();
+
+                // build the widgetpath
+                List<String> widgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
+                if (widgetTrail == null) {
+                    widgetTrail = new LinkedList<String>();
+                }
+
+                String thisName = nameExdr.expandString(context);
+                widgetTrail.add(thisName);
+                context.put("_WIDGETTRAIL_", widgetTrail);
+            }
+
+            // don't need the renderer here, will just pass this on down to another screen call; screenStringRenderer.renderContainerBegin(writer, context, this);
+            String name = this.getName(context);
+            String location = this.getLocation(context);
+
+            if (name.isEmpty()) {
+                if (Debug.verboseOn()) Debug.logVerbose("In the include-screen tag the screen name was empty, ignoring include; in screen [" + getModelScreen().getName() + "]", module);
+                return;
+            }
+
+            ScreenFactory.renderReferencedScreen(name, location, this, writer, context, screenStringRenderer);
+
+            if (protectScope) {
+                UtilGenerics.<MapStack<String>>cast(context).pop();
+            }
+        }
+
+        public String getName(Map<String, Object> context) {
+            return this.nameExdr.expandString(context);
+        }
+
+        public String getLocation(Map<String, Object> context) {
+            return this.locationExdr.expandString(context);
+        }
+
+        public boolean shareScope(Map<String, Object> context) {
+            String shareScopeString = this.shareScopeExdr.expandString(context);
+            // defaults to false, so anything but true is false
+            return "true".equals(shareScopeString);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getNameExdr() {
+            return nameExdr;
+        }
+
+        public FlexibleStringExpander getLocationExdr() {
+            return locationExdr;
+        }
+
+        public FlexibleStringExpander getShareScopeExdr() {
+            return shareScopeExdr;
+        }
+    }
+
+    public static final class DecoratorScreen extends ModelScreenWidget {
+        public static final String TAG_NAME = "decorator-screen";
+        private final FlexibleStringExpander nameExdr;
+        private final FlexibleStringExpander locationExdr;
+        private final Map<String, ModelScreenWidget> sectionMap;
+
+        public DecoratorScreen(ModelScreen modelScreen, Element decoratorScreenElement) {
+            super(modelScreen, decoratorScreenElement);
+            this.nameExdr = FlexibleStringExpander.getInstance(decoratorScreenElement.getAttribute("name"));
+            this.locationExdr = FlexibleStringExpander.getInstance(decoratorScreenElement.getAttribute("location"));
+            Map<String, ModelScreenWidget> sectionMap = new HashMap<String, ModelScreenWidget>();
+            List<? extends Element> decoratorSectionElementList = UtilXml.childElementList(decoratorScreenElement, "decorator-section");
+            for (Element decoratorSectionElement: decoratorSectionElementList) {
+                DecoratorSection decoratorSection = new DecoratorSection(modelScreen, decoratorSectionElement);
+                sectionMap.put(decoratorSection.getName(), decoratorSection);
+            }
+            this.sectionMap = Collections.unmodifiableMap(sectionMap);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            // isolate the scope
+            if (!(context instanceof MapStack)) {
+                context = MapStack.create(context);
+            }
+
+            MapStack contextMs = (MapStack) context;
+
+            // create a standAloneStack, basically a "save point" for this SectionsRenderer, and make a new "screens" object just for it so it is isolated and doesn't follow the stack down
+            MapStack standAloneStack = contextMs.standAloneChildStack();
+            standAloneStack.put("screens", new ScreenRenderer(writer, standAloneStack, screenStringRenderer));
+            SectionsRenderer sections = new SectionsRenderer(this.sectionMap, standAloneStack, writer, screenStringRenderer);
+
+            // put the sectionMap in the context, make sure it is in the sub-scope, ie after calling push on the MapStack
+            contextMs.push();
+            context.put("sections", sections);
+
+            String name = this.getName(context);
+            String location = this.getLocation(context);
+
+            ScreenFactory.renderReferencedScreen(name, location, this, writer, context, screenStringRenderer);
+
+            contextMs.pop();
+        }
+
+        public String getName(Map<String, Object> context) {
+            return this.nameExdr.expandString(context);
+        }
+
+        public String getLocation(Map<String, Object> context) {
+            return this.locationExdr.expandString(context);
+        }
+
+        public Map<String, ModelScreenWidget> getSectionMap() {
+            return sectionMap;
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getNameExdr() {
+            return nameExdr;
+        }
+
+        public FlexibleStringExpander getLocationExdr() {
+            return locationExdr;
+        }
+
+    }
+
+    public static final class DecoratorSection extends ModelScreenWidget {
+        public static final String TAG_NAME = "decorator-section";
+        private final List<ModelScreenWidget> subWidgets;
+
+        public DecoratorSection(ModelScreen modelScreen, Element decoratorSectionElement) {
+            super(modelScreen, decoratorSectionElement);
+            // read sub-widgets
+            List<? extends Element> subElementList = UtilXml.childElementList(decoratorSectionElement);
+            this.subWidgets = ModelScreenWidget.readSubWidgets(getModelScreen(), subElementList);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            // render sub-widgets
+            renderSubWidgetsString(this.subWidgets, writer, context, screenStringRenderer);
+        }
+
+        public List<ModelScreenWidget> getSubWidgets() {
+            return subWidgets;
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+    }
+
+    public static final class DecoratorSectionInclude extends ModelScreenWidget {
+        public static final String TAG_NAME = "decorator-section-include";
+
+        public DecoratorSectionInclude(ModelScreen modelScreen, Element decoratorSectionElement) {
+            super(modelScreen, decoratorSectionElement);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            Map<String, ? extends Object> preRenderedContent = UtilGenerics.checkMap(context.get("preRenderedContent"));
+            if (preRenderedContent != null && preRenderedContent.containsKey(getName())) {
+                try {
+                    writer.append((String) preRenderedContent.get(getName()));
+                } catch (IOException e) {
+                    String errMsg = "Error rendering pre-rendered content in screen named [" + getModelScreen().getName() + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
+            } else {
+                SectionsRenderer sections = (SectionsRenderer) context.get("sections");
+                // for now if sections is null, just log a warning; may be permissible to make the screen for flexible
+                if (sections == null) {
+                    Debug.logWarning("In decorator-section-include could not find sections object in the context, not rendering section with name [" + getName() + "]", module);
+                } else {
+                    sections.render(getName());
+                }
+            }
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+    }
+
+    public static final class Label extends ModelScreenWidget {
+        public static final String TAG_NAME = "label";
+        private final FlexibleStringExpander textExdr;
+        private final FlexibleStringExpander idExdr;
+        private final FlexibleStringExpander styleExdr;
+
+        public Label(ModelScreen modelScreen, Element labelElement) {
+            super(modelScreen, labelElement);
+
+            // put the text attribute first, then the pcdata under the element, if both are there of course
+            String textAttr = labelElement.getAttribute("text");
+            String pcdata = UtilXml.elementValue(labelElement);
+            if (pcdata == null) {
+                pcdata = "";
+            }
+            this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata);
+
+            this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id"));
+            this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style"));
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            try {
+                screenStringRenderer.renderLabel(writer, context, this);
+            } catch (IOException e) {
+                String errMsg = "Error rendering label in screen named [" + getModelScreen().getName() + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        }
+
+        public String getText(Map<String, Object> context) {
+            String text = this.textExdr.expandString(context);
+            // FIXME: Encoding should be done by the renderer, not by the model.
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+            if (simpleEncoder != null) {
+                text = simpleEncoder.encode(text);
+            }
+            return text;
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.styleExdr.expandString(context);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getTextExdr() {
+            return textExdr;
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return styleExdr;
+        }
+    }
+
+    public static final class Form extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-form";
+        private final FlexibleStringExpander nameExdr;
+        private final FlexibleStringExpander locationExdr;
+        private final FlexibleStringExpander shareScopeExdr;
+
+        public Form(ModelScreen modelScreen, Element formElement) {
+            super(modelScreen, formElement);
+            this.nameExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("name"));
+            this.locationExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("location"));
+            this.shareScopeExdr = FlexibleStringExpander.getInstance(formElement.getAttribute("share-scope"));
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            // Output format might not support forms, so make form rendering optional.
+            FormStringRenderer formStringRenderer = (FormStringRenderer) context.get("formStringRenderer");
+            if (formStringRenderer == null) {
+                Debug.logVerbose("FormStringRenderer instance not found in rendering context, form not rendered.", module);
+                return;
+            }
+            boolean protectScope = !shareScope(context);
+            if (protectScope) {
+                if (!(context instanceof MapStack<?>)) {
+                    context = MapStack.create(context);
+                }
+                UtilGenerics.<MapStack<String>>cast(context).push();
+            }
+            ModelForm modelForm = getModelForm(context);
+            FormRenderer renderer = new FormRenderer(modelForm, formStringRenderer);
+            try {
+                renderer.render(writer, context);
+            } catch (Exception e) {
+                String errMsg = "Error rendering included form named [" + getName() + "] at location [" + this.getLocation(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg + e);
+            }
+
+            if (protectScope) {
+                UtilGenerics.<MapStack<String>>cast(context).pop();
+            }
+        }
+
+        public ModelForm getModelForm(Map<String, Object> context) {
+            ModelForm modelForm = null;
+            String name = this.getName(context);
+            String location = this.getLocation(context);
+            try {
+                modelForm = FormFactory.getFormFromLocation(location, name, getModelScreen().getDelegator(context).getModelReader(), getModelScreen().getDispatcher(context).getDispatchContext());
+            } catch (Exception e) {
+                String errMsg = "Error rendering included form named [" + name + "] at location [" + location + "]: ";
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg + e);
+            }
+            return modelForm;
+        }
+
+        public String getName(Map<String, Object> context) {
+            return this.nameExdr.expandString(context);
+        }
+
+        public String getLocation() {
+            return locationExdr.getOriginal();
+        }
+
+        public String getLocation(Map<String, Object> context) {
+            return this.locationExdr.expandString(context);
+        }
+
+        public boolean shareScope(Map<String, Object> context) {
+            String shareScopeString = this.shareScopeExdr.expandString(context);
+            // defaults to false, so anything but true is false
+            return "true".equals(shareScopeString);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getNameExdr() {
+            return nameExdr;
+        }
+
+        public FlexibleStringExpander getLocationExdr() {
+            return locationExdr;
+        }
+
+        public FlexibleStringExpander getShareScopeExdr() {
+            return shareScopeExdr;
+        }
+
+    }
+
+    public static final class Tree extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-tree";
+        private final FlexibleStringExpander nameExdr;
+        private final FlexibleStringExpander locationExdr;
+        private final FlexibleStringExpander shareScopeExdr;
+
+        public Tree(ModelScreen modelScreen, Element treeElement) {
+            super(modelScreen, treeElement);
+            this.nameExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("name"));
+            this.locationExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("location"));
+            this.shareScopeExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("share-scope"));
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            // Output format might not support trees, so make tree rendering optional.
+            TreeStringRenderer treeStringRenderer = (TreeStringRenderer) context.get("treeStringRenderer");
+            if (treeStringRenderer == null) {
+                Debug.logVerbose("TreeStringRenderer instance not found in rendering context, tree not rendered.", module);
+                return;
+            }
+            boolean protectScope = !shareScope(context);
+            if (protectScope) {
+                if (!(context instanceof MapStack<?>)) {
+                    context = MapStack.create(context);
+                }
+                UtilGenerics.<MapStack<String>>cast(context).push();
+            }
+
+            String name = this.getName(context);
+            String location = this.getLocation(context);
+            ModelTree modelTree = null;
+            try {
+                modelTree = TreeFactory.getTreeFromLocation(this.getLocation(context), this.getName(context), getModelScreen().getDelegator(context), getModelScreen().getDispatcher(context));
+            } catch (IOException e) {
+                String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            } catch (SAXException e) {
+                String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            } catch (ParserConfigurationException e) {
+                String errMsg = "Error rendering included tree named [" + name + "] at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+            modelTree.renderTreeString(writer, context, treeStringRenderer);
+            if (protectScope) {
+                UtilGenerics.<MapStack<String>>cast(context).pop();
+            }
+        }
+
+        public String getName(Map<String, Object> context) {
+            return this.nameExdr.expandString(context);
+        }
+
+        public String getLocation(Map<String, Object> context) {
+            return this.locationExdr.expandString(context);
+        }
+
+        public boolean shareScope(Map<String, Object> context) {
+            String shareScopeString = this.shareScopeExdr.expandString(context);
+            // defaults to false, so anything but true is false
+            return "true".equals(shareScopeString);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getLocationExdr() {
+            return locationExdr;
+        }
+
+        public FlexibleStringExpander getShareScopeExdr() {
+            return shareScopeExdr;
+        }
+    }
+
+    public static final class PlatformSpecific extends ModelScreenWidget {
+        public static final String TAG_NAME = "platform-specific";
+        private final Map<String, ModelScreenWidget> subWidgets;
+
+        public PlatformSpecific(ModelScreen modelScreen, Element platformSpecificElement) {
+            super(modelScreen, platformSpecificElement);
+            Map<String, ModelScreenWidget> subWidgets = new HashMap<String, ModelScreenWidget>();
+            List<? extends Element> childElements = UtilXml.childElementList(platformSpecificElement);
+            if (childElements != null) {
+                for (Element childElement: childElements) {
+                    if ("html".equals(childElement.getNodeName())) {
+                        subWidgets.put("html", new HtmlWidget(modelScreen, childElement));
+                    } else if ("xsl-fo".equals(childElement.getNodeName())) {
+                        subWidgets.put("xsl-fo", new HtmlWidget(modelScreen, childElement));
+                    } else if ("xml".equals(childElement.getNodeName())) {
+                        subWidgets.put("xml", new HtmlWidget(modelScreen, childElement));
+                    } else {
+                        throw new IllegalArgumentException("Tag not supported under the platform-specific tag with name: " + childElement.getNodeName());
+                    }
+                }
+            }
+            this.subWidgets = Collections.unmodifiableMap(subWidgets);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            ModelScreenWidget subWidget = null;
+            subWidget = subWidgets.get(screenStringRenderer.getRendererName());
+            if (subWidget == null) {
+                // This is here for backward compatibility
+                Debug.logWarning("In platform-dependent could not find template for " + screenStringRenderer.getRendererName() + ", using the one for html.", module);
+                subWidget = subWidgets.get("html");
+            }
+            if (subWidget != null) {
+                subWidget.renderWidgetString(writer, context, screenStringRenderer);
+            }
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public Map<String, ModelScreenWidget> getSubWidgets() {
+            return subWidgets;
+        }
+    }
+
+    public static final class Content extends ModelScreenWidget {
+        public static final String TAG_NAME = "content";
+
+        private final FlexibleStringExpander contentId;
+        private final FlexibleStringExpander editRequest;
+        private final FlexibleStringExpander editContainerStyle;
+        private final FlexibleStringExpander enableEditName;
+        private final boolean xmlEscape;
+        private final FlexibleStringExpander dataResourceId;
+        private final String width;
+        private final String height;
+        private final String border;
+
+        public Content(ModelScreen modelScreen, Element subContentElement) {
+            super(modelScreen, subContentElement);
+            this.contentId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("content-id"));
+            this.dataResourceId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("dataresource-id"));
+            this.editRequest = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-request"));
+            this.editContainerStyle = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-container-style"));
+            this.enableEditName = FlexibleStringExpander.getInstance(subContentElement.getAttribute("enable-edit-name"));
+            this.xmlEscape = "true".equals(subContentElement.getAttribute("xml-escape"));
+            String width = subContentElement.getAttribute("width");
+            if (width.isEmpty())
+                width = "60%";
+            this.height = subContentElement.getAttribute("height");
+            if (this.height.isEmpty())
+                width = "400px";
+            this.width = width;
+            this.border = subContentElement.getAttribute("border");
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            try {
+                // pushing the contentId on the context as "contentId" is done
+                // because many times there will be embedded "subcontent" elements
+                // that use the syntax: <subcontent content-id="${contentId}"...
+                // and this is a step to make sure that it is there.
+                Delegator delegator = (Delegator) context.get("delegator");
+                GenericValue content = null;
+                String expandedDataResourceId = getDataResourceId(context);
+                String expandedContentId = getContentId(context);
+                if (!(context instanceof MapStack<?>)) {
+                    context = MapStack.create(context);
+                }
+
+                // This is an important step to make sure that the current contentId is in the context
+                // as templates that contain "subcontent" elements will expect to find the master
+                // contentId in the context as "contentId".
+                UtilGenerics.<MapStack<String>>cast(context).push();
+                context.put("contentId", expandedContentId);
+
+                if (expandedDataResourceId.isEmpty()) {
+                    if (!expandedContentId.isEmpty()) {
+                        content = EntityQuery.use(delegator).from("Content").where("contentId", expandedContentId).cache().queryOne();
+                    } else {
+                        String errMsg = "contentId is empty.";
+                        Debug.logError(errMsg, module);
+                        return;
+                    }
+                    if (content != null) {
+                        expandedDataResourceId = content.getString("dataResourceId");
+                    } else {
+                        String errMsg = "Could not find content with contentId [" + expandedContentId + "] ";
+                        Debug.logError(errMsg, module);
+                        throw new RuntimeException(errMsg);
+                    }
+                }
+
+                GenericValue dataResource = null;
+                if (!expandedDataResourceId.isEmpty()) {
+                    dataResource = EntityQuery.use(delegator).from("DataResource").where("dataResourceId", expandedDataResourceId).cache().queryOne();
+                }
+
+                String mimeTypeId = null;
+                if (dataResource != null) {
+                    mimeTypeId = dataResource.getString("mimeTypeId");
+                }
+                if (content != null) {
+                    mimeTypeId = content.getString("mimeTypeId");
+                }
+
+                if (!(mimeTypeId != null
+                        && ((mimeTypeId.indexOf("application") >= 0) || (mimeTypeId.indexOf("image")) >= 0))) {
+                    screenStringRenderer.renderContentBegin(writer, context, this);
+                    screenStringRenderer.renderContentBody(writer, context, this);
+                    screenStringRenderer.renderContentEnd(writer, context, this);
+                }
+                UtilGenerics.<MapStack<String>>cast(context).pop();
+            } catch (IOException e) {
+                String errMsg = "Error rendering content with contentId [" + getContentId(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            } catch (GenericEntityException e) {
+                String errMsg = "Error obtaining content with contentId [" + getContentId(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+
+        }
+
+        public String getContentId(Map<String, Object> context) {
+            return this.contentId.expandString(context);
+        }
+
+        public String getDataResourceId() {
+            return this.dataResourceId.getOriginal();
+        }
+
+        public String getDataResourceId(Map<String, Object> context) {
+            return this.dataResourceId.expandString(context);
+        }
+
+        public String getEditRequest(Map<String, Object> context) {
+            return this.editRequest.expandString(context);
+        }
+
+        public String getEditContainerStyle(Map<String, Object> context) {
+            return this.editContainerStyle.expandString(context);
+        }
+
+        public String getEnableEditName(Map<String, Object> context) {
+            return this.enableEditName.expandString(context);
+        }
+
+        public boolean xmlEscape() {
+            return this.xmlEscape;
+        }
+
+        public String getWidth() {
+            return this.width;
+        }
+
+        public String getHeight() {
+            return this.height;
+        }
+
+        public String getBorder() {
+            return this.border;
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getContentId() {
+            return contentId;
+        }
+
+        public FlexibleStringExpander getEditRequest() {
+            return editRequest;
+        }
+
+        public FlexibleStringExpander getEditContainerStyle() {
+            return editContainerStyle;
+        }
+
+        public FlexibleStringExpander getEnableEditName() {
+            return enableEditName;
+        }
+    }
+
+    public static final class SubContent extends ModelScreenWidget {
+        public static final String TAG_NAME = "sub-content";
+        private final FlexibleStringExpander contentId;
+        private final FlexibleStringExpander mapKey;
+        private final FlexibleStringExpander editRequest;
+        private final FlexibleStringExpander editContainerStyle;
+        private final FlexibleStringExpander enableEditName;
+        private final boolean xmlEscape;
+
+        public SubContent(ModelScreen modelScreen, Element subContentElement) {
+            super(modelScreen, subContentElement);
+            this.contentId = FlexibleStringExpander.getInstance(subContentElement.getAttribute("content-id"));
+            String mapKey = subContentElement.getAttribute("map-key");
+            if (mapKey.isEmpty()) {
+                mapKey = subContentElement.getAttribute("assoc-name");
+            }
+            this.mapKey = FlexibleStringExpander.getInstance(mapKey);
+            this.editRequest = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-request"));
+            this.editContainerStyle = FlexibleStringExpander.getInstance(subContentElement.getAttribute("edit-container-style"));
+            this.enableEditName = FlexibleStringExpander.getInstance(subContentElement.getAttribute("enable-edit-name"));
+            this.xmlEscape = "true".equals(subContentElement.getAttribute("xml-escape"));
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            try {
+                screenStringRenderer.renderSubContentBegin(writer, context, this);
+                screenStringRenderer.renderSubContentBody(writer, context, this);
+                screenStringRenderer.renderSubContentEnd(writer, context, this);
+            } catch (IOException e) {
+                String errMsg = "Error rendering subContent with contentId [" + getContentId(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        }
+
+        public String getContentId(Map<String, Object> context) {
+            return this.contentId.expandString(context);
+        }
+
+        public String getMapKey(Map<String, Object> context) {
+            return this.mapKey.expandString(context);
+        }
+
+        public String getEditRequest(Map<String, Object> context) {
+            return this.editRequest.expandString(context);
+        }
+
+        public String getEditContainerStyle(Map<String, Object> context) {
+            return this.editContainerStyle.expandString(context);
+        }
+
+        public String getEnableEditName(Map<String, Object> context) {
+            return this.enableEditName.expandString(context);
+        }
+
+        public boolean xmlEscape() {
+            return this.xmlEscape;
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            // TODO Auto-generated method stub
+            
+        }
+    }
+
+    public static final class Menu extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-menu";
+        private final FlexibleStringExpander nameExdr;
+        private final FlexibleStringExpander locationExdr;
+
+        public Menu(ModelScreen modelScreen, Element menuElement) {
+            super(modelScreen, menuElement);
+            this.nameExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("name"));
+            this.locationExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("location"));
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) 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.getName(context);
+            String location = this.getLocation(context);
+            ModelMenu modelMenu = null;
+            try {
+                modelMenu = MenuFactory.getMenuFromLocation(location, name);
+            } catch (Exception e) {
+                String errMsg = "Error rendering included menu named [" + name + "] at location [" + location + "]: ";
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg + e);
+            }
+            return modelMenu;
+        }
+
+        public String getName(Map<String, Object> context) {
+            return this.nameExdr.expandString(context);
+        }
+
+        public String getLocation(Map<String, Object> context) {
+            return this.locationExdr.expandString(context);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getLocationExdr() {
+            return locationExdr;
+        }
+    }
+
+    public static final class ScreenLink extends ModelScreenWidget {
+        public static final String TAG_NAME = "link";
+        private final Link link;
+        private final ScreenImage image;
+
+        public ScreenLink(ModelScreen modelScreen, Element linkElement) {
+            super(modelScreen, linkElement);
+            this.link = new Link(linkElement);
+            Element imageElement = UtilXml.firstChildElement(linkElement, "image");
+            if (imageElement != null) {
+                this.image = new ScreenImage(modelScreen, imageElement);
+            } else {
+                this.image = null;
+            }
+        }
+
+        public String getName() {
+            return link.getName();
+        }
+
+        public String getText(Map<String, Object> context) {
+            return link.getText(context);
+        }
+
+        public String getId(Map<String, Object> context) {
+            return link.getId(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return link.getStyle(context);
+        }
+
+        public String getTarget(Map<String, Object> context) {
+            return link.getTarget(context);
+        }
+
+        public String getName(Map<String, Object> context) {
+            return link.getName(context);
+        }
+
+        public String getTargetWindow(Map<String, Object> context) {
+            return link.getTargetWindow(context);
+        }
+
+        public String getUrlMode() {
+            return link.getUrlMode();
+        }
+
+        public String getPrefix(Map<String, Object> context) {
+            return link.getPrefix(context);
+        }
+
+        public boolean getFullPath() {
+            return link.getFullPath();
+        }
+
+        public boolean getSecure() {
+            return link.getSecure();
+        }
+
+        public boolean getEncode() {
+            return link.getEncode();
+        }
+
+        public ScreenImage getImage() {
+            return image;
+        }
+
+        public String getLinkType() {
+            return link.getLinkType();
+        }
+
+        public String getWidth() {
+            return link.getWidth();
+        }
+
+        public String getHeight() {
+            return link.getHeight();
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> context) {
+            return link.getParameterMap(context);
+        }
+
+        public FlexibleStringExpander getTextExdr() {
+            return link.getTextExdr();
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return link.getIdExdr();
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return link.getStyleExdr();
+        }
+
+        public FlexibleStringExpander getTargetExdr() {
+            return link.getTargetExdr();
+        }
+
+        public FlexibleStringExpander getTargetWindowExdr() {
+            return link.getTargetWindowExdr();
+        }
+
+        public FlexibleStringExpander getPrefixExdr() {
+            return link.getPrefixExdr();
+        }
+
+        public FlexibleStringExpander getNameExdr() {
+            return link.getNameExdr();
+        }
+
+        public List<Parameter> getParameterList() {
+            return link.getParameterList();
+        }
+
+        public AutoServiceParameters getAutoServiceParameters() {
+            return link.getAutoServiceParameters();
+        }
+
+        public AutoEntityParameters getAutoEntityParameters() {
+            return link.getAutoEntityParameters();
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            try {
+                screenStringRenderer.renderLink(writer, context, this);
+            } catch (IOException e) {
+                String errMsg = "Error rendering link with id [" + link.getId(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public Link getLink() {
+            return link;
+        }
+    }
+
+    public static final class ScreenImage extends ModelScreenWidget {
+        public static final String TAG_NAME = "image";
+        private final Image image;
+
+        public String getName() {
+            return image.getName();
+        }
+
+        public String getSrc(Map<String, Object> context) {
+            return image.getSrc(context);
+        }
+
+        public String getId(Map<String, Object> context) {
+            return image.getId(context);
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return image.getStyle(context);
+        }
+
+        public String getWidth(Map<String, Object> context) {
+            return image.getWidth(context);
+        }
+
+        public String getHeight(Map<String, Object> context) {
+            return image.getHeight(context);
+        }
+
+        public String getBorder(Map<String, Object> context) {
+            return image.getBorder(context);
+        }
+
+        public String getAlt(Map<String, Object> context) {
+            return image.getAlt(context);
+        }
+
+        public String getUrlMode() {
+            return image.getUrlMode();
+        }
+
+        public FlexibleStringExpander getSrcExdr() {
+            return image.getSrcExdr();
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return image.getIdExdr();
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return image.getStyleExdr();
+        }
+
+        public FlexibleStringExpander getWidthExdr() {
+            return image.getWidthExdr();
+        }
+
+        public FlexibleStringExpander getHeightExdr() {
+            return image.getHeightExdr();
+        }
+
+        public FlexibleStringExpander getBorderExdr() {
+            return image.getBorderExdr();
+        }
+
+        public FlexibleStringExpander getAlt() {
+            return image.getAlt();
+        }
+
+        public ScreenImage(ModelScreen modelScreen, Element imageElement) {
+            super(modelScreen, imageElement);
+            this.image = new Image(imageElement);
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) {
+            try {
+                screenStringRenderer.renderImage(writer, context, this);
+            } catch (IOException e) {
+                String errMsg = "Error rendering image with id [" + image.getId(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public Image getImage() {
+            return image;
+        }
+    }
+
+    public static final class PortalPage extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-portal-page";
+        private final FlexibleStringExpander idExdr;
+        private final FlexibleStringExpander confModeExdr;
+        private final Boolean usePrivate;
+
+        public PortalPage(ModelScreen modelScreen, Element portalPageElement) {
+            super(modelScreen, portalPageElement);
+            this.idExdr = FlexibleStringExpander.getInstance(portalPageElement.getAttribute("id"));
+            this.confModeExdr = FlexibleStringExpander.getInstance(portalPageElement.getAttribute("conf-mode"));
+            this.usePrivate = !("false".equals(portalPageElement.getAttribute("use-private")));
+        }
+
+        private GenericValue getPortalPageValue(Map<String, Object> context) {
+            Delegator delegator = (Delegator) context.get("delegator");
+            String expandedPortalPageId = getId(context);
+            GenericValue portalPage = null;
+            if (!expandedPortalPageId.isEmpty()) {
+                if (usePrivate) {
+                    portalPage = PortalPageWorker.getPortalPage(expandedPortalPageId, context);
+                } else {
+                    try {
+                        portalPage = EntityQuery.use(delegator)
+                                                .from("PortalPage")
+                                                .where("portalPageId", expandedPortalPageId)
+                                                .cache().queryOne();
+                    } catch (GenericEntityException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }
+            if (portalPage == null) {
+                String errMsg = "Could not find PortalPage with portalPageId [" + expandedPortalPageId + "] ";
+                Debug.logError(errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+            return portalPage;
+        }
+
+        @Override
+        public void renderWidgetString(Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+            try {
+                Delegator delegator = (Delegator) context.get("delegator");
+                List<GenericValue> portalPageColumns = null;
+                List<GenericValue> portalPagePortlets = null;
+                List<GenericValue> portletAttributes = null;
+                GenericValue portalPage = getPortalPageValue(context);
+                String actualPortalPageId = portalPage.getString("portalPageId");
+                portalPageColumns = EntityQuery.use(delegator)
+                                               .from("PortalPageColumn")
+                                               .where("portalPageId", actualPortalPageId)
+                                               .orderBy("columnSeqId")
+                                               .cache(true)
+                                               .queryList();
+                
+                // Renders the portalPage header
+                screenStringRenderer.renderPortalPageBegin(writer, context, this);
+                
+                // First column has no previous column
+                String prevColumnSeqId = "";
+                
+                // Iterates through the PortalPage columns
+                ListIterator <GenericValue>columnsIterator = portalPageColumns.listIterator();
+                while(columnsIterator.hasNext()) {
+                    GenericValue columnValue = columnsIterator.next();
+                    String columnSeqId = columnValue.getString("columnSeqId");
+                    
+                    // Renders the portalPageColumn header
+                    screenStringRenderer.renderPortalPageColumnBegin(writer, context, this, columnValue);
+
+                    // Get the Portlets located in the current column
+                    portalPagePortlets = EntityQuery.use(delegator)
+                                                    .from("PortalPagePortletView")
+                                                    .where("portalPageId", portalPage.getString("portalPageId"), "columnSeqId", columnSeqId)
+                                                    .orderBy("sequenceNum")
+                                                    .queryList();
+                    // First Portlet in a Column has no previous Portlet
+                    String prevPortletId = "";
+                    String prevPortletSeqId = "";
+
+                    // If this is not the last column, get the next columnSeqId
+                    String nextColumnSeqId = "";
+                    if (columnsIterator.hasNext()) {
+                        nextColumnSeqId = portalPageColumns.get(columnsIterator.nextIndex()).getString("columnSeqId");
+                    }
+                    
+                    // Iterates through the Portlets in the Column
+                    ListIterator <GenericValue>portletsIterator = portalPagePortlets.listIterator();
+                    while(portletsIterator.hasNext()) {
+                        GenericValue portletValue = portletsIterator.next();
+
+                        // If not the last portlet in the column, get the next nextPortletId and nextPortletSeqId
+                        String nextPortletId = "";
+                        String nextPortletSeqId = "";
+                        if (portletsIterator.hasNext()) {
+                            nextPortletId = portalPagePortlets.get(portletsIterator.nextIndex()).getString("portalPortletId");
+                            nextPortletSeqId = portalPagePortlets.get(portletsIterator.nextIndex()).getString("portletSeqId");
+                        }
+
+                        // Set info to allow portlet movement in the page
+                        context.put("prevPortletId", prevPortletId);
+                        context.put("prevPortletSeqId", prevPortletSeqId);
+                        context.put("nextPortletId", nextPortletId);
+                        context.put("nextPortletSeqId", nextPortletSeqId);
+                        context.put("prevColumnSeqId", prevColumnSeqId);
+                        context.put("nextColumnSeqId", nextColumnSeqId);
+                       
+                        // Get portlet's attributes
+                        portletAttributes = EntityQuery.use(delegator)
+                                                       .from("PortletAttribute")
+                                                       .where("portalPageId", portletValue.get("portalPageId"), "portalPortletId", portletValue.get("portalPortletId"), "portletSeqId", portletValue.get("portletSeqId"))
+                                                       .queryList();
+                        
+                        ListIterator <GenericValue>attributesIterator = portletAttributes.listIterator();
+                        while (attributesIterator.hasNext()) {
+                            GenericValue attribute = attributesIterator.next();
+                            context.put(attribute.getString("attrName"), attribute.getString("attrValue"));
+                        }
+                        
+                        // Renders the portalPagePortlet
+                        screenStringRenderer.renderPortalPagePortletBegin(writer, context, this, portletValue);
+                        screenStringRenderer.renderPortalPagePortletBody(writer, context, this, portletValue);
+                        screenStringRenderer.renderPortalPagePortletEnd(writer, context, this, portletValue);
+
+                        // Remove the portlet's attributes so that these are not available for other portlets
+                        while (attributesIterator.hasPrevious()) {
+                            GenericValue attribute = attributesIterator.previous();
+                            context.remove(attribute.getString("attrName"));
+                        }
+                        
+                        // Uses the actual portlet as prevPortlet for next iteration
+                        prevPortletId = (String) portletValue.get("portalPortletId");
+                        prevPortletSeqId = (String) portletValue.get("portletSeqId");
+                    }
+                    // Renders the portalPageColumn footer
+                    screenStringRenderer.renderPortalPageColumnEnd(writer, context, this, columnValue);
+
+                    // Uses the actual columnSeqId as prevColumnSeqId for next iteration
+                    prevColumnSeqId = columnSeqId;
+                }
+                // Renders the portalPage footer
+                screenStringRenderer.renderPortalPageEnd(writer, context, this);
+            } catch (IOException e) {
+                String errMsg = "Error rendering PortalPage with portalPageId [" + getId(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            } catch (GenericEntityException e) {
+                String errMsg = "Error obtaining PortalPage with portalPageId [" + getId(context) + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public String getOriginalPortalPageId(Map<String, Object> context) {
+            GenericValue portalPage = getPortalPageValue(context);
+            return portalPage.getString("originalPortalPageId");
+        }
+        
+        public String getActualPortalPageId(Map<String, Object> context) {
+            GenericValue portalPage = getPortalPageValue(context);
+            return portalPage.getString("portalPageId");
+        }
+
+        public String getConfMode(Map<String, Object> context) {
+            return this.confModeExdr.expandString(context);
+        }
+
+        public String getUsePrivate() {
+            return Boolean.toString(this.usePrivate);
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public FlexibleStringExpander getConfModeExdr() {
+            return confModeExdr;
+        }
+    }
+
+}
diff --git a/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java b/framework/widget/src/org/ofbiz/widget/model/ModelTree.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/tree/ModelTree.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelTree.java
index 8c85016..9a2bf60 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelTree.java
@@ -1,1139 +1,1135 @@
-/*******************************************************************************
- * 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.ofbiz.widget.tree;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.MapStack;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.model.ModelEntity;
-import org.ofbiz.entity.model.ModelField;
-import org.ofbiz.entity.util.EntityListIterator;
-import org.ofbiz.entity.util.EntityQuery;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.*;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.CommonWidgetModels.Parameter;
-import org.ofbiz.widget.screen.ModelScreen;
-import org.ofbiz.widget.screen.ScreenFactory;
-import org.ofbiz.widget.screen.ScreenRenderException;
-import org.ofbiz.widget.screen.ScreenStringRenderer;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-/**
- * Models the &lt;tree&gt; element.
- * 
- * @see <code>widget-tree.xsd</code>
- */
-@SuppressWarnings("serial")
-public class ModelTree extends ModelWidget {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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.
-     * 
-     * 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 = ModelTree.class.getName();
-
-    private final String defaultEntityName;
-    private final String defaultRenderStyle;
-    private final FlexibleStringExpander defaultWrapStyleExdr;
-    private final FlexibleStringExpander expandCollapseRequestExdr;
-    private final boolean forceChildCheck;
-    private final String location;
-    private final Map<String, ModelNode> nodeMap;
-    private final int openDepth;
-    private final int postTrailOpenDepth;
-    private final String rootNodeName;
-    private final FlexibleStringExpander trailNameExdr;
-
-    public ModelTree(Element treeElement, String location) {
-        super(treeElement);
-        this.location = location;
-        this.rootNodeName = treeElement.getAttribute("root-node-name");
-        String defaultRenderStyle = UtilXml.checkEmpty(treeElement.getAttribute("default-render-style"), "simple");
-        // A temporary hack to accommodate those who might still be using "render-style" instead of "default-render-style"
-        if (defaultRenderStyle.isEmpty() || defaultRenderStyle.equals("simple")) {
-            String rStyle = treeElement.getAttribute("render-style");
-            if (!rStyle.isEmpty())
-                defaultRenderStyle = rStyle;
-        }
-        this.defaultRenderStyle = defaultRenderStyle;
-        this.defaultWrapStyleExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("default-wrap-style"));
-        this.expandCollapseRequestExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("expand-collapse-request"));
-        this.trailNameExdr = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(treeElement.getAttribute("trail-name"),
-                "trail"));
-        this.forceChildCheck = !"false".equals(treeElement.getAttribute("force-child-check"));
-        this.defaultEntityName = treeElement.getAttribute("entity-name");
-        int openDepth = 0;
-        if (treeElement.hasAttribute("open-depth")) {
-            try {
-                openDepth = Integer.parseInt(treeElement.getAttribute("open-depth"));
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException("Invalid open-depth attribute value for the tree definition with name: "
-                        + getName());
-            }
-        }
-        this.openDepth = openDepth;
-        int postTrailOpenDepth = 999;
-        if (treeElement.hasAttribute("post-trail-open-depth")) {
-            try {
-                postTrailOpenDepth = Integer.parseInt(treeElement.getAttribute("post-trail-open-depth"));
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException(
-                        "Invalid post-trail-open-depth attribute value for the tree definition with name: " + getName());
-            }
-        }
-        this.postTrailOpenDepth = postTrailOpenDepth;
-        List<? extends Element> nodeElements = UtilXml.childElementList(treeElement, "node");
-        if (nodeElements.size() == 0) {
-            throw new IllegalArgumentException("No node elements found for the tree definition with name: " + getName());
-        }
-        Map<String, ModelNode> nodeMap = new HashMap<String, ModelNode>();
-        for (Element nodeElementEntry : UtilXml.childElementList(treeElement, "node")) {
-            ModelNode node = new ModelNode(nodeElementEntry, this);
-            String nodeName = node.getName();
-            nodeMap.put(nodeName, node);
-        }
-        this.nodeMap = Collections.unmodifiableMap(nodeMap);
-    }
-
-    @Override
-    public void accept(ModelWidgetVisitor visitor) throws Exception {
-        visitor.visit(this);
-    }
-
-    @Override
-    public String getBoundaryCommentName() {
-        return location + "#" + getName();
-    }
-
-    public String getDefaultEntityName() {
-        return this.defaultEntityName;
-    }
-
-    public String getDefaultPkName(Map<String, Object> context) {
-        ModelEntity modelEntity = WidgetWorker.getDelegator(context).getModelEntity(this.defaultEntityName);
-        if (modelEntity.getPksSize() == 1) {
-            ModelField modelField = modelEntity.getOnlyPk();
-            return modelField.getName();
-        }
-        return null;
-    }
-
-    public String getExpandCollapseRequest(Map<String, Object> context) {
-        String expColReq = this.expandCollapseRequestExdr.expandString(context);
-        if (UtilValidate.isEmpty(expColReq)) {
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-            String s1 = request.getRequestURI();
-            int pos = s1.lastIndexOf("/");
-            if (pos >= 0)
-                expColReq = s1.substring(pos + 1);
-            else
-                expColReq = s1;
-        }
-        //append also the request parameters
-        Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
-        if (UtilValidate.isNotEmpty(paramMap)) {
-            Map<String, Object> requestParameters = new HashMap<String, Object>(paramMap);
-            requestParameters.remove(this.getTrailName(context));
-            if (UtilValidate.isNotEmpty(requestParameters)) {
-                String queryString = UtilHttp.urlEncodeArgs(requestParameters, false);
-                if (expColReq.indexOf("?") < 0) {
-                    expColReq += "?";
-                } else {
-                    expColReq += "&amp;";
-                }
-                expColReq += queryString;
-            }
-        }
-        return expColReq;
-    }
-
-    public int getOpenDepth() {
-        return openDepth;
-    }
-
-    public int getPostTrailOpenDepth() {
-        return postTrailOpenDepth;
-    }
-
-    public String getRenderStyle() {
-        return this.defaultRenderStyle;
-    }
-
-    public String getRootNodeName() {
-        return rootNodeName;
-    }
-
-    public String getTrailName(Map<String, Object> context) {
-        return this.trailNameExdr.expandString(context);
-    }
-
-    public String getWrapStyle(Map<String, Object> context) {
-        return this.defaultWrapStyleExdr.expandString(context);
-    }
-
-    /**
-     * Renders this model.
-     *
-     * @param writer
-     * @param context
-     * @param treeStringRenderer
-     */
-    @SuppressWarnings("rawtypes")
-    public void renderTreeString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer)
-            throws GeneralException {
-        Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
-        ModelNode node = nodeMap.get(rootNodeName);
-        String trailName = trailNameExdr.expandString(context);
-        String treeString = (String) context.get(trailName);
-        if (UtilValidate.isEmpty(treeString)) {
-            treeString = (String) parameters.get(trailName);
-        }
-        List<String> trail = null;
-        if (UtilValidate.isNotEmpty(treeString)) {
-            trail = StringUtil.split(treeString, "|");
-            if (UtilValidate.isEmpty(trail))
-                throw new RuntimeException("Tree 'trail' value is empty.");
-            context.put("rootEntityId", trail.get(0));
-            context.put(getDefaultPkName(context), trail.get(0));
-        } else {
-            trail = new LinkedList<String>();
-        }
-        context.put("targetNodeTrail", trail);
-        context.put("currentNodeTrail", new LinkedList());
-        try {
-            node.renderNodeString(writer, context, treeStringRenderer, 0);
-        } catch (IOException e2) {
-            String errMsg = "Error rendering included label with name [" + getName() + "] : " + e2.toString();
-            Debug.logError(e2, errMsg, module);
-            throw new RuntimeException(errMsg);
-        }
-
-    }
-
-    public String getDefaultRenderStyle() {
-        return defaultRenderStyle;
-    }
-
-    public FlexibleStringExpander getDefaultWrapStyleExdr() {
-        return defaultWrapStyleExdr;
-    }
-
-    public FlexibleStringExpander getExpandCollapseRequestExdr() {
-        return expandCollapseRequestExdr;
-    }
-
-    public boolean getForceChildCheck() {
-        return forceChildCheck;
-    }
-
-    public String getLocation() {
-        return location;
-    }
-
-    public Map<String, ModelNode> getNodeMap() {
-        return nodeMap;
-    }
-
-    public FlexibleStringExpander getTrailNameExdr() {
-        return trailNameExdr;
-    }
-
-    /**
-     * Models the &lt;node&gt; element.
-     * 
-     * @see <code>widget-tree.xsd</code>
-     */
-    public static class ModelNode extends ModelWidget {
-
-        private final List<ModelAction> actions;
-        // TODO: Make this a generic condition object.
-        private final ModelTreeCondition condition;
-        private final String entityName;
-        private final String entryName;
-        private final String expandCollapseStyle;
-        private final Label label;
-        private final Link link;
-        private final ModelTree modelTree;
-        private final String pkName;
-        private final String renderStyle;
-        private final FlexibleStringExpander screenLocationExdr;
-        private final FlexibleStringExpander screenNameExdr;
-        private final String shareScope;
-        private final List<ModelSubNode> subNodeList;
-        private final FlexibleStringExpander wrapStyleExdr;
-
-        public ModelNode(Element nodeElement, ModelTree modelTree) {
-            super(nodeElement);
-            this.modelTree = modelTree;
-            this.expandCollapseStyle = nodeElement.getAttribute("expand-collapse-style");
-            this.wrapStyleExdr = FlexibleStringExpander.getInstance(nodeElement.getAttribute("wrap-style"));
-            this.renderStyle = nodeElement.getAttribute("render-style");
-            this.entryName = nodeElement.getAttribute("entry-name");
-            this.entityName = nodeElement.getAttribute("entity-name");
-            this.pkName = nodeElement.getAttribute("join-field-name");
-            ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
-            // FIXME: Validate child elements, should be only one of actions, entity-one, service, script.
-            Element actionsElement = UtilXml.firstChildElement(nodeElement, "actions");
-            if (actionsElement != null) {
-                actions.addAll(ModelTreeAction.readNodeActions(this, actionsElement));
-            }
-            Element actionElement = UtilXml.firstChildElement(nodeElement, "entity-one");
-            if (actionElement != null) {
-                actions.add(new AbstractModelAction.EntityOne(this, actionElement));
-            }
-            actionElement = UtilXml.firstChildElement(nodeElement, "service");
-            if (actionElement != null) {
-                actions.add(new ModelTreeAction.Service(this, actionElement));
-            }
-            actionElement = UtilXml.firstChildElement(nodeElement, "script");
-            if (actionElement != null) {
-                actions.add(new ModelTreeAction.Script(this, actionElement));
-            }
-            actions.trimToSize();
-            this.actions = Collections.unmodifiableList(actions);
-            Element screenElement = UtilXml.firstChildElement(nodeElement, "include-screen");
-            if (screenElement != null) {
-                this.screenNameExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("name"));
-                this.screenLocationExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("location"));
-                this.shareScope = screenElement.getAttribute("share-scope");
-            } else {
-                this.screenNameExdr = FlexibleStringExpander.getInstance("");
-                this.screenLocationExdr = FlexibleStringExpander.getInstance("");
-                this.shareScope = "";
-            }
-            Element labelElement = UtilXml.firstChildElement(nodeElement, "label");
-            if (labelElement != null) {
-                this.label = new Label(labelElement);
-            } else {
-                this.label = null;
-            }
-            Element linkElement = UtilXml.firstChildElement(nodeElement, "link");
-            if (linkElement != null) {
-                this.link = new Link(linkElement);
-            } else {
-                this.link = null;
-            }
-            Element conditionElement = UtilXml.firstChildElement(nodeElement, "condition");
-            if (conditionElement != null) {
-                this.condition = new ModelTreeCondition(modelTree, conditionElement);
-            } else {
-                this.condition = null;
-            }
-            List<? extends Element> nodeElements = UtilXml.childElementList(nodeElement, "sub-node");
-            if (!nodeElements.isEmpty()) {
-                List<ModelSubNode> subNodeList = new ArrayList<ModelSubNode>();
-                for (Element subNodeElementEntry : nodeElements) {
-                    ModelSubNode subNode = new ModelSubNode(subNodeElementEntry, this);
-                    subNodeList.add(subNode);
-                }
-                this.subNodeList = Collections.unmodifiableList(subNodeList);
-            } else {
-                this.subNodeList = Collections.emptyList();
-            }
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        private List<Object[]> getChildren(Map<String, Object> context) {
-            List<Object[]> subNodeValues = new ArrayList<Object[]>();
-            for (ModelSubNode subNode : subNodeList) {
-                String nodeName = subNode.getNodeName(context);
-                ModelNode node = modelTree.nodeMap.get(nodeName);
-                List<ModelAction> subNodeActions = subNode.getActions();
-                //if (Debug.infoOn()) Debug.logInfo(" context.currentValue:" + context.get("currentValue"), module);
-                AbstractModelAction.runSubActions(subNodeActions, context);
-                // List dataFound = (List)context.get("dataFound");
-                Iterator<? extends Map<String, ? extends Object>> dataIter = subNode.getListIterator(context);
-                if (dataIter instanceof EntityListIterator) {
-                    EntityListIterator eli = (EntityListIterator) dataIter;
-                    Map<String, Object> val = null;
-                    while ((val = eli.next()) != null) {
-                        Object[] arr = { node, val };
-                        subNodeValues.add(arr);
-                    }
-                    try {
-                        eli.close();
-                    } catch (GenericEntityException e) {
-                        Debug.logError(e, module);
-                        throw new RuntimeException(e.getMessage());
-                    }
-                } else if (dataIter != null) {
-                    while (dataIter.hasNext()) {
-                        Map<String, ? extends Object> val = dataIter.next();
-                        Object[] arr = { node, val };
-                        subNodeValues.add(arr);
-                    }
-                }
-            }
-            return subNodeValues;
-        }
-
-        public String getEntityName() {
-            if (!this.entityName.isEmpty()) {
-                return this.entityName;
-            } else {
-                return this.modelTree.getDefaultEntityName();
-            }
-        }
-
-        public String getEntryName() {
-            return this.entryName;
-        }
-
-        public String getExpandCollapseStyle() {
-            return expandCollapseStyle;
-        }
-
-        public ModelTree getModelTree() {
-            return this.modelTree;
-        }
-
-        public String getPkName(Map<String, Object> context) {
-            if (UtilValidate.isNotEmpty(this.pkName)) {
-                return this.pkName;
-            } else {
-                return this.modelTree.getDefaultPkName(context);
-            }
-        }
-
-        public String getRenderStyle() {
-            if (this.renderStyle.isEmpty())
-                return modelTree.getRenderStyle();
-            return this.renderStyle;
-        }
-
-        public String getWrapStyle(Map<String, Object> context) {
-            String val = this.wrapStyleExdr.expandString(context);
-            if (val.isEmpty()) {
-                val = this.modelTree.getWrapStyle(context);
-            }
-            return val;
-        }
-
-        public boolean hasChildren(Map<String, Object> context) {
-            List<Object[]> subNodeValues = getChildren(context);
-            boolean hasChildren = false;
-            Long nodeCount = null;
-            String countFieldName = "childBranchCount";
-            Object obj = null;
-            if (!this.entryName.isEmpty()) {
-                Map<String, Object> map = UtilGenerics.cast(context.get(this.entryName));
-                if (map instanceof GenericValue) {
-                    ModelEntity modelEntity = ((GenericValue) map).getModelEntity();
-                    if (modelEntity.isField(countFieldName)) {
-                        obj = map.get(countFieldName);
-                    }
-                }
-            } else {
-                obj = context.get(countFieldName);
-            }
-            if (obj != null) {
-                nodeCount = (Long) obj;
-            }
-            String entName = this.getEntityName();
-            Delegator delegator = WidgetWorker.getDelegator(context);
-            ModelEntity modelEntity = delegator.getModelEntity(entName);
-            ModelField modelField = null;
-            if (modelEntity.isField(countFieldName)) {
-                modelField = modelEntity.getField(countFieldName);
-            }
-            if (nodeCount == null && modelField != null || this.modelTree.forceChildCheck) {
-                getChildren(context);
-                /*
-                String id = (String)context.get(modelTree.getPkName());
-                if (UtilValidate.isNotEmpty(id)) {
-                    try {
-                        int leafCount = ContentManagementWorker.updateStatsTopDown(delegator, id, UtilMisc.toList("SUB_CONTENT", "PUBLISH_LINK"));
-                        GenericValue entity = delegator.findOne(entName, UtilMisc.toMap(modelTree.getPkName(), id), true);
-                        obj = entity.get("childBranchCount");
-                       if (obj != null)
-                           nodeCount = (Long)obj;
-                    } catch (GenericEntityException e) {
-                        Debug.logError(e, module);
-                       throw new RuntimeException(e.getMessage());
-                    }
-                }
-                */
-                nodeCount = Long.valueOf(subNodeValues.size());
-                String pkName = this.getPkName(context);
-                String id = null;
-                if (!this.entryName.isEmpty()) {
-                    id = UtilGenerics.<Map<String, String>> cast(context.get(this.entryName)).get(pkName);
-                } else {
-                    id = (String) context.get(pkName);
-                }
-                try {
-                    if (id != null && modelEntity.getPksSize() == 1) {
-                        GenericValue entity = EntityQuery.use(delegator).from(entName).where(pkName, id).queryOne();
-                        if (modelEntity.isField("childBranchCount")) {
-                            entity.put("childBranchCount", nodeCount);
-                            entity.store();
-                        }
-                    }
-                } catch (GenericEntityException e) {
-                    Debug.logError(e, module);
-                    throw new RuntimeException(e.getMessage());
-                }
-            } else if (nodeCount == null) {
-                getChildren(context);
-                if (subNodeValues != null) {
-                    nodeCount = Long.valueOf(subNodeValues.size());
-                }
-            }
-            if (nodeCount != null && nodeCount.intValue() > 0) {
-                hasChildren = true;
-            }
-            return hasChildren;
-        }
-
-        public boolean isExpandCollapse() {
-            boolean isExpCollapse = false;
-            String rStyle = getRenderStyle();
-            if (rStyle != null && rStyle.equals("expand-collapse"))
-                isExpCollapse = true;
-            return isExpCollapse;
-        }
-
-        public boolean isFollowTrail() {
-            boolean isFollowTrail = false;
-            String rStyle = getRenderStyle();
-            if (rStyle != null && (rStyle.equals("follow-trail") || rStyle.equals("show-peers") || rStyle.equals("follow-trail"))) {
-                isFollowTrail = true;
-            }
-            return isFollowTrail;
-        }
-
-        public boolean isRootNode() {
-            return getName().equals(modelTree.getRootNodeName());
-        }
-
-        public void renderNodeString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer,
-                int depth) throws IOException, GeneralException {
-            boolean passed = true;
-            if (this.condition != null) {
-                if (!this.condition.getCondition().eval(context)) {
-                    passed = false;
-                }
-            }
-            //Debug.logInfo("in ModelMenu, name:" + this.getName(), module);
-            if (passed) {
-                List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
-                context.put("processChildren", Boolean.TRUE);
-                // this action will usually obtain the "current" entity
-                ModelTreeAction.runSubActions(this.actions, context);
-                String pkName = getPkName(context);
-                String id = null;
-                if (!this.entryName.isEmpty()) {
-                    id = UtilGenerics.<Map<String, String>> cast(context.get(this.entryName)).get(pkName);
-                } else {
-                    id = (String) context.get(pkName);
-                }
-                currentNodeTrail.add(id);
-                treeStringRenderer.renderNodeBegin(writer, context, this, depth);
-                //if (Debug.infoOn()) Debug.logInfo(" context:" +
-                // context.entrySet(), module);
-                try {
-                    String screenName = null;
-                    if (!screenNameExdr.isEmpty())
-                        screenName = screenNameExdr.expandString(context);
-                    String screenLocation = null;
-                    if (!screenLocationExdr.isEmpty())
-                        screenLocation = screenLocationExdr.expandString(context);
-                    if (screenName != null && screenLocation != null) {
-                        ScreenStringRenderer screenStringRenderer = treeStringRenderer.getScreenStringRenderer(context);
-                        ModelScreen modelScreen = ScreenFactory.getScreenFromLocation(screenLocation, screenName);
-                        modelScreen.renderScreenString(writer, context, screenStringRenderer);
-                    }
-                    if (label != null) {
-                        label.renderLabelString(writer, context, treeStringRenderer);
-                    }
-                    if (link != null) {
-                        link.renderLinkString(writer, context, treeStringRenderer);
-                    }
-                    treeStringRenderer.renderLastElement(writer, context, this);
-                    Boolean processChildren = (Boolean) context.get("processChildren");
-                    //if (Debug.infoOn()) Debug.logInfo(" processChildren:" + processChildren, module);
-                    if (processChildren.booleanValue()) {
-                        List<Object[]> subNodeValues = getChildren(context);
-                        int newDepth = depth + 1;
-                        for (Object[] arr : subNodeValues) {
-                            ModelNode node = (ModelNode) arr[0];
-                            Map<String, Object> val = UtilGenerics.checkMap(arr[1]);
-                            //GenericPK pk = val.getPrimaryKey();
-                            //if (Debug.infoOn()) Debug.logInfo(" pk:" + pk,
-                            // module);
-                            String thisPkName = node.getPkName(context);
-                            String thisEntityId = (String) val.get(thisPkName);
-                            MapStack<String> newContext = MapStack.create(context);
-                            newContext.push();
-                            String nodeEntryName = node.getEntryName();
-                            if (!nodeEntryName.isEmpty()) {
-                                newContext.put(nodeEntryName, val);
-                            } else {
-                                newContext.putAll(val);
-                            }
-                            String targetEntityId = null;
-                            List<String> targetNodeTrail = UtilGenerics.checkList(context.get("targetNodeTrail"));
-                            if (newDepth < targetNodeTrail.size()) {
-                                targetEntityId = targetNodeTrail.get(newDepth);
-                            }
-                            if ((targetEntityId != null && targetEntityId.equals(thisEntityId))
-                                    || this.showPeers(newDepth, context)) {
-                                node.renderNodeString(writer, newContext, treeStringRenderer, newDepth);
-                            }
-                        }
-                    }
-                } catch (ScreenRenderException e) {
-                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                } catch (SAXException e) {
-                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                } catch (ParserConfigurationException e3) {
-                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e3.toString();
-                    Debug.logError(e3, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                } catch (IOException e2) {
-                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e2.toString();
-                    Debug.logError(e2, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-                treeStringRenderer.renderNodeEnd(writer, context, this);
-                int removeIdx = currentNodeTrail.size() - 1;
-                if (removeIdx >= 0)
-                    currentNodeTrail.remove(removeIdx);
-            }
-        }
-
-        public boolean showPeers(int currentDepth, Map<String, Object> context) {
-            int trailSize = 0;
-            List<?> trail = UtilGenerics.checkList(context.get("targetNodeTrail"));
-            int openDepth = modelTree.getOpenDepth();
-            int postTrailOpenDepth = modelTree.getPostTrailOpenDepth();
-            if (trail != null)
-                trailSize = trail.size();
-
-            boolean showPeers = false;
-            String rStyle = getRenderStyle();
-            if (rStyle == null) {
-                showPeers = true;
-            } else if (!isFollowTrail()) {
-                showPeers = true;
-            } else if ((currentDepth < trailSize) && (rStyle != null)
-                    && (rStyle.equals("show-peers") || rStyle.equals("expand-collapse"))) {
-                showPeers = true;
-            } else if (openDepth >= currentDepth) {
-                showPeers = true;
-            } else {
-                int depthAfterTrail = currentDepth - trailSize;
-                if (depthAfterTrail >= 0 && depthAfterTrail <= postTrailOpenDepth)
-                    showPeers = true;
-            }
-            return showPeers;
-        }
-        
-        public List<ModelAction> getActions() {
-            return actions;
-        }
-
-        public ModelTreeCondition getCondition() {
-            return condition;
-        }
-
-        public Label getLabel() {
-            return label;
-        }
-
-        public Link getLink() {
-            return link;
-        }
-
-        public String getPkName() {
-            return pkName;
-        }
-
-        public FlexibleStringExpander getScreenLocationExdr() {
-            return screenLocationExdr;
-        }
-
-        public FlexibleStringExpander getScreenNameExdr() {
-            return screenNameExdr;
-        }
-
-        public String getShareScope() {
-            return shareScope;
-        }
-
-        public List<ModelSubNode> getSubNodeList() {
-            return subNodeList;
-        }
-
-        public FlexibleStringExpander getWrapStyleExdr() {
-            return wrapStyleExdr;
-        }
-
-        /**
-         * Models the &lt;image&gt; element.
-         * 
-         * @see <code>widget-tree.xsd</code>
-         */
-        public static class Image {
-
-            private final FlexibleStringExpander borderExdr;
-            private final FlexibleStringExpander heightExdr;
-            private final FlexibleStringExpander idExdr;
-            private final FlexibleStringExpander srcExdr;
-            private final FlexibleStringExpander styleExdr;
-            private final String urlMode;
-            private final FlexibleStringExpander widthExdr;
-
-            public Image(Element imageElement) {
-                this.borderExdr = FlexibleStringExpander
-                        .getInstance(UtilXml.checkEmpty(imageElement.getAttribute("border"), "0"));
-                this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
-                this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id"));
-                this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("src"));
-                this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style"));
-                this.urlMode = UtilXml.checkEmpty(imageElement.getAttribute("url-mode"), "content");
-                this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
-            }
-
-            public String getBorder(Map<String, Object> context) {
-                return this.borderExdr.expandString(context);
-            }
-
-            public String getHeight(Map<String, Object> context) {
-                return this.heightExdr.expandString(context);
-            }
-
-            public String getId(Map<String, Object> context) {
-                return this.idExdr.expandString(context);
-            }
-
-            public String getSrc(Map<String, Object> context) {
-                return this.srcExdr.expandString(context);
-            }
-
-            public String getStyle(Map<String, Object> context) {
-                return this.styleExdr.expandString(context);
-            }
-
-            public String getUrlMode() {
-                return this.urlMode;
-            }
-
-            public String getWidth(Map<String, Object> context) {
-                return this.widthExdr.expandString(context);
-            }
-
-            public void renderImageString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
-                try {
-                    treeStringRenderer.renderImage(writer, context, this);
-                } catch (IOException e) {
-                    String errMsg = "Error rendering image with id [" + getId(context) + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            }
-        }
-
-        /**
-         * Models the &lt;label&gt; element.
-         * 
-         * @see <code>widget-tree.xsd</code>
-         */
-        public static final class Label {
-            private final FlexibleStringExpander idExdr;
-            private final FlexibleStringExpander styleExdr;
-            private final FlexibleStringExpander textExdr;
-
-            public Label(Element labelElement) {
-                String textAttr = labelElement.getAttribute("text");
-                String pcdata = UtilXml.checkEmpty(UtilXml.elementValue(labelElement), "");
-                this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata);
-                this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id"));
-                this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style"));
-            }
-
-            public String getId(Map<String, Object> context) {
-                return this.idExdr.expandString(context);
-            }
-
-            public String getStyle(Map<String, Object> context) {
-                return this.styleExdr.expandString(context);
-            }
-
-            public String getText(Map<String, Object> context) {
-                String text = this.textExdr.expandString(context);
-                // FIXME: Encoding should be done by the renderer, not by the model.
-                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    text = simpleEncoder.encode(text);
-                }
-                return text;
-            }
-
-            public void renderLabelString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
-                try {
-                    treeStringRenderer.renderLabel(writer, context, this);
-                } catch (IOException e) {
-                    String errMsg = "Error rendering label with id [" + getId(context) + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            }
-
-            public FlexibleStringExpander getIdExdr() {
-                return idExdr;
-            }
-
-            public FlexibleStringExpander getStyleExdr() {
-                return styleExdr;
-            }
-
-            public FlexibleStringExpander getTextExdr() {
-                return textExdr;
-            }
-        }
-
-        /**
-         * Models the &lt;link&gt; element.
-         * 
-         * @see <code>widget-tree.xsd</code>
-         */
-        public static class Link {
-            private final boolean encode;
-            private final boolean fullPath;
-            private final FlexibleStringExpander idExdr;
-            private final Image image;
-            private final String linkType;
-            private final FlexibleStringExpander nameExdr;
-            private final List<Parameter> parameterList;
-            private final FlexibleStringExpander prefixExdr;
-            private final boolean secure;
-            private final FlexibleStringExpander styleExdr;
-            private final FlexibleStringExpander targetExdr;
-            private final FlexibleStringExpander targetWindowExdr;
-            private final FlexibleStringExpander textExdr;
-            private final FlexibleStringExpander titleExdr;
-            private final String urlMode;
-
-            public Link(Element linkElement) {
-                this.encode = "true".equals(linkElement.getAttribute("encode"));
-                this.fullPath = "true".equals(linkElement.getAttribute("full-path"));
-                this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id"));
-                Element imageElement = UtilXml.firstChildElement(linkElement, "image");
-                if (imageElement != null) {
-                    this.image = new Image(imageElement);
-                } else {
-                    this.image = null;
-                }
-                this.linkType = linkElement.getAttribute("link-type");
-                this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name"));
-                List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
-                if (!parameterElementList.isEmpty()) {
-                    List<Parameter> parameterList = new ArrayList<Parameter>(parameterElementList.size());
-                    for (Element parameterElement : parameterElementList) {
-                        parameterList.add(new Parameter(parameterElement));
-                    }
-                    this.parameterList = Collections.unmodifiableList(parameterList);
-                } else {
-                    this.parameterList = Collections.emptyList();
-                }
-                this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
-                this.secure = "true".equals(linkElement.getAttribute("secure"));
-                this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style"));
-                this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target"));
-                this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window"));
-                this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
-                this.titleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("title"));
-                this.urlMode = UtilXml.checkEmpty(linkElement.getAttribute("link-type"), "intra-app");
-            }
-
-            // FIXME: Using a widget model in this way is an ugly hack.
-            public Link(String style, String target, String text) {
-                this.encode = false;
-                this.fullPath = false;
-                this.idExdr = FlexibleStringExpander.getInstance("");
-                this.image = null;
-                this.linkType = "";
-                this.nameExdr = FlexibleStringExpander.getInstance("");
-                this.parameterList = Collections.emptyList();
-                this.prefixExdr = FlexibleStringExpander.getInstance("");
-                this.secure = false;
-                this.styleExdr = FlexibleStringExpander.getInstance(style);
-                this.targetExdr = FlexibleStringExpander.getInstance(target);
-                this.targetWindowExdr = FlexibleStringExpander.getInstance("");
-                this.textExdr = FlexibleStringExpander.getInstance(text);
-                this.titleExdr = FlexibleStringExpander.getInstance("");
-                this.urlMode = "intra-app";
-            }
-
-            public boolean getEncode() {
-                return this.encode;
-            }
-
-            public boolean getFullPath() {
-                return this.fullPath;
-            }
-
-            public String getId(Map<String, Object> context) {
-                return this.idExdr.expandString(context);
-            }
-
-            public Image getImage() {
-                return this.image;
-            }
-
-            public String getLinkType() {
-                return this.linkType;
-            }
-
-            public String getName(Map<String, Object> context) {
-                return this.nameExdr.expandString(context);
-            }
-
-            public Map<String, String> getParameterMap(Map<String, Object> context) {
-                Map<String, String> fullParameterMap = new HashMap<String, String>();
-                /* leaving this here... may want to add it at some point like the hyperlink element:
-                Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
-                if (addlParamMap != null) {
-                    fullParameterMap.putAll(addlParamMap);
-                }
-                */
-                for (CommonWidgetModels.Parameter parameter : this.parameterList) {
-                    fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-                }
-                return fullParameterMap;
-            }
-
-            public String getPrefix(Map<String, Object> context) {
-                return this.prefixExdr.expandString(context);
-            }
-
-            public boolean getSecure() {
-                return this.secure;
-            }
-
-            public String getStyle(Map<String, Object> context) {
-                return this.styleExdr.expandString(context);
-            }
-
-            public String getTarget(Map<String, Object> context) {
-                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    return this.targetExdr.expandString(UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context,
-                            simpleEncoder));
-                } else {
-                    return this.targetExdr.expandString(context);
-                }
-            }
-
-            public String getTargetWindow(Map<String, Object> context) {
-                return this.targetWindowExdr.expandString(context);
-            }
-
-            public String getText(Map<String, Object> context) {
-                String text = this.textExdr.expandString(context);
-                // FIXME: Encoding should be done by the renderer, not by the model.
-                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    text = simpleEncoder.encode(text);
-                }
-                return text;
-            }
-
-            public String getTitle(Map<String, Object> context) {
-                String title = this.titleExdr.expandString(context);
-                // FIXME: Encoding should be done by the renderer, not by the model.
-                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-                if (simpleEncoder != null) {
-                    title = simpleEncoder.encode(title);
-                }
-                return title;
-            }
-
-            public String getUrlMode() {
-                return this.urlMode;
-            }
-
-            public void renderLinkString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
-                try {
-                    treeStringRenderer.renderLink(writer, context, this);
-                } catch (IOException e) {
-                    String errMsg = "Error rendering link with id [" + getId(context) + "]: " + e.toString();
-                    Debug.logError(e, errMsg, module);
-                    throw new RuntimeException(errMsg);
-                }
-            }
-
-            public FlexibleStringExpander getIdExdr() {
-                return idExdr;
-            }
-
-            public FlexibleStringExpander getNameExdr() {
-                return nameExdr;
-            }
-
-            public List<Parameter> getParameterList() {
-                return parameterList;
-            }
-
-            public FlexibleStringExpander getPrefixExdr() {
-                return prefixExdr;
-            }
-
-            public FlexibleStringExpander getStyleExdr() {
-                return styleExdr;
-            }
-
-            public FlexibleStringExpander getTargetExdr() {
-                return targetExdr;
-            }
-
-            public FlexibleStringExpander getTargetWindowExdr() {
-                return targetWindowExdr;
-            }
-
-            public FlexibleStringExpander getTextExdr() {
-                return textExdr;
-            }
-
-            public FlexibleStringExpander getTitleExdr() {
-                return titleExdr;
-            }
-        }
-
-        /**
-         * Models the &lt;sub-node&gt; element.
-         * 
-         * @see <code>widget-tree.xsd</code>
-         */
-        public static class ModelSubNode extends ModelWidget {
-
-            private final List<ModelAction> actions;
-            private final FlexibleStringExpander nodeNameExdr;
-            private final ModelNode rootNode;
-            private final String iteratorKey;
-
-            public ModelSubNode(Element subNodeElement, ModelNode modelNode) {
-                super(subNodeElement);
-                this.rootNode = modelNode;
-                this.nodeNameExdr = FlexibleStringExpander.getInstance(subNodeElement.getAttribute("node-name"));
-                ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
-                // FIXME: Validate child elements, should be only one of actions, entity-and, entity-condition, service, script.
-                Element actionsElement = UtilXml.firstChildElement(subNodeElement, "actions");
-                if (actionsElement != null) {
-                    actions.addAll(ModelTreeAction.readSubNodeActions(this, actionsElement));
-                }
-                Element actionElement = UtilXml.firstChildElement(subNodeElement, "entity-and");
-                if (actionElement != null) {
-                    actions.add(new ModelTreeAction.EntityAnd(this, actionElement));
-                }
-                actionElement = UtilXml.firstChildElement(subNodeElement, "service");
-                if (actionElement != null) {
-                    actions.add(new ModelTreeAction.Service(this, actionElement));
-                }
-                actionElement = UtilXml.firstChildElement(subNodeElement, "entity-condition");
-                if (actionElement != null) {
-                    actions.add(new ModelTreeAction.EntityCondition(this, actionElement));
-                }
-                actionElement = UtilXml.firstChildElement(subNodeElement, "script");
-                if (actionElement != null) {
-                    actions.add(new ModelTreeAction.Script(this, actionElement));
-                }
-                actions.trimToSize();
-                this.actions = Collections.unmodifiableList(actions);
-                this.iteratorKey = this.rootNode.getName().concat(".").concat(this.nodeNameExdr.getOriginal())
-                        .concat(".ITERATOR");
-            }
-
-            @Override
-            public void accept(ModelWidgetVisitor visitor) throws Exception {
-                visitor.visit(this);
-            }
-
-            public List<ModelAction> getActions() {
-                return actions;
-            }
-
-            @SuppressWarnings("unchecked")
-            public ListIterator<? extends Map<String, ? extends Object>> getListIterator(Map<String, Object> context) {
-                return (ListIterator<? extends Map<String, ? extends Object>>) context.get(this.iteratorKey);
-            }
-
-            public ModelTree.ModelNode getNode() {
-                return this.rootNode;
-            }
-
-            public String getNodeName(Map<String, Object> context) {
-                return this.nodeNameExdr.expandString(context);
-            }
-
-            public FlexibleStringExpander getNodeNameExdr() {
-                return nodeNameExdr;
-            }
-
-            public void setListIterator(ListIterator<? extends Map<String, ? extends Object>> iter, Map<String, Object> context) {
-                context.put(this.iteratorKey, iter);
-            }
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelField;
+import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.EntityQuery;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.CommonWidgetModels.Parameter;
+import org.ofbiz.widget.renderer.ScreenRenderException;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.TreeStringRenderer;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/**
+ * Models the &lt;tree&gt; element.
+ * 
+ * @see <code>widget-tree.xsd</code>
+ */
+@SuppressWarnings("serial")
+public class ModelTree extends ModelWidget {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     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.
+     * 
+     * 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 = ModelTree.class.getName();
+
+    private final String defaultEntityName;
+    private final String defaultRenderStyle;
+    private final FlexibleStringExpander defaultWrapStyleExdr;
+    private final FlexibleStringExpander expandCollapseRequestExdr;
+    private final boolean forceChildCheck;
+    private final String location;
+    private final Map<String, ModelNode> nodeMap;
+    private final int openDepth;
+    private final int postTrailOpenDepth;
+    private final String rootNodeName;
+    private final FlexibleStringExpander trailNameExdr;
+
+    public ModelTree(Element treeElement, String location) {
+        super(treeElement);
+        this.location = location;
+        this.rootNodeName = treeElement.getAttribute("root-node-name");
+        String defaultRenderStyle = UtilXml.checkEmpty(treeElement.getAttribute("default-render-style"), "simple");
+        // A temporary hack to accommodate those who might still be using "render-style" instead of "default-render-style"
+        if (defaultRenderStyle.isEmpty() || defaultRenderStyle.equals("simple")) {
+            String rStyle = treeElement.getAttribute("render-style");
+            if (!rStyle.isEmpty())
+                defaultRenderStyle = rStyle;
+        }
+        this.defaultRenderStyle = defaultRenderStyle;
+        this.defaultWrapStyleExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("default-wrap-style"));
+        this.expandCollapseRequestExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("expand-collapse-request"));
+        this.trailNameExdr = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(treeElement.getAttribute("trail-name"),
+                "trail"));
+        this.forceChildCheck = !"false".equals(treeElement.getAttribute("force-child-check"));
+        this.defaultEntityName = treeElement.getAttribute("entity-name");
+        int openDepth = 0;
+        if (treeElement.hasAttribute("open-depth")) {
+            try {
+                openDepth = Integer.parseInt(treeElement.getAttribute("open-depth"));
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("Invalid open-depth attribute value for the tree definition with name: "
+                        + getName());
+            }
+        }
+        this.openDepth = openDepth;
+        int postTrailOpenDepth = 999;
+        if (treeElement.hasAttribute("post-trail-open-depth")) {
+            try {
+                postTrailOpenDepth = Integer.parseInt(treeElement.getAttribute("post-trail-open-depth"));
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException(
+                        "Invalid post-trail-open-depth attribute value for the tree definition with name: " + getName());
+            }
+        }
+        this.postTrailOpenDepth = postTrailOpenDepth;
+        List<? extends Element> nodeElements = UtilXml.childElementList(treeElement, "node");
+        if (nodeElements.size() == 0) {
+            throw new IllegalArgumentException("No node elements found for the tree definition with name: " + getName());
+        }
+        Map<String, ModelNode> nodeMap = new HashMap<String, ModelNode>();
+        for (Element nodeElementEntry : UtilXml.childElementList(treeElement, "node")) {
+            ModelNode node = new ModelNode(nodeElementEntry, this);
+            String nodeName = node.getName();
+            nodeMap.put(nodeName, node);
+        }
+        this.nodeMap = Collections.unmodifiableMap(nodeMap);
+    }
+
+    @Override
+    public void accept(ModelWidgetVisitor visitor) throws Exception {
+        visitor.visit(this);
+    }
+
+    @Override
+    public String getBoundaryCommentName() {
+        return location + "#" + getName();
+    }
+
+    public String getDefaultEntityName() {
+        return this.defaultEntityName;
+    }
+
+    public String getDefaultPkName(Map<String, Object> context) {
+        ModelEntity modelEntity = WidgetWorker.getDelegator(context).getModelEntity(this.defaultEntityName);
+        if (modelEntity.getPksSize() == 1) {
+            ModelField modelField = modelEntity.getOnlyPk();
+            return modelField.getName();
+        }
+        return null;
+    }
+
+    public String getExpandCollapseRequest(Map<String, Object> context) {
+        String expColReq = this.expandCollapseRequestExdr.expandString(context);
+        if (UtilValidate.isEmpty(expColReq)) {
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+            String s1 = request.getRequestURI();
+            int pos = s1.lastIndexOf("/");
+            if (pos >= 0)
+                expColReq = s1.substring(pos + 1);
+            else
+                expColReq = s1;
+        }
+        //append also the request parameters
+        Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
+        if (UtilValidate.isNotEmpty(paramMap)) {
+            Map<String, Object> requestParameters = new HashMap<String, Object>(paramMap);
+            requestParameters.remove(this.getTrailName(context));
+            if (UtilValidate.isNotEmpty(requestParameters)) {
+                String queryString = UtilHttp.urlEncodeArgs(requestParameters, false);
+                if (expColReq.indexOf("?") < 0) {
+                    expColReq += "?";
+                } else {
+                    expColReq += "&amp;";
+                }
+                expColReq += queryString;
+            }
+        }
+        return expColReq;
+    }
+
+    public int getOpenDepth() {
+        return openDepth;
+    }
+
+    public int getPostTrailOpenDepth() {
+        return postTrailOpenDepth;
+    }
+
+    public String getRenderStyle() {
+        return this.defaultRenderStyle;
+    }
+
+    public String getRootNodeName() {
+        return rootNodeName;
+    }
+
+    public String getTrailName(Map<String, Object> context) {
+        return this.trailNameExdr.expandString(context);
+    }
+
+    public String getWrapStyle(Map<String, Object> context) {
+        return this.defaultWrapStyleExdr.expandString(context);
+    }
+
+    /**
+     * Renders this model.
+     *
+     * @param writer
+     * @param context
+     * @param treeStringRenderer
+     */
+    @SuppressWarnings("rawtypes")
+    public void renderTreeString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer)
+            throws GeneralException {
+        Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
+        ModelNode node = nodeMap.get(rootNodeName);
+        String trailName = trailNameExdr.expandString(context);
+        String treeString = (String) context.get(trailName);
+        if (UtilValidate.isEmpty(treeString)) {
+            treeString = (String) parameters.get(trailName);
+        }
+        List<String> trail = null;
+        if (UtilValidate.isNotEmpty(treeString)) {
+            trail = StringUtil.split(treeString, "|");
+            if (UtilValidate.isEmpty(trail))
+                throw new RuntimeException("Tree 'trail' value is empty.");
+            context.put("rootEntityId", trail.get(0));
+            context.put(getDefaultPkName(context), trail.get(0));
+        } else {
+            trail = new LinkedList<String>();
+        }
+        context.put("targetNodeTrail", trail);
+        context.put("currentNodeTrail", new LinkedList());
+        try {
+            node.renderNodeString(writer, context, treeStringRenderer, 0);
+        } catch (IOException e2) {
+            String errMsg = "Error rendering included label with name [" + getName() + "] : " + e2.toString();
+            Debug.logError(e2, errMsg, module);
+            throw new RuntimeException(errMsg);
+        }
+
+    }
+
+    public String getDefaultRenderStyle() {
+        return defaultRenderStyle;
+    }
+
+    public FlexibleStringExpander getDefaultWrapStyleExdr() {
+        return defaultWrapStyleExdr;
+    }
+
+    public FlexibleStringExpander getExpandCollapseRequestExdr() {
+        return expandCollapseRequestExdr;
+    }
+
+    public boolean getForceChildCheck() {
+        return forceChildCheck;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    public Map<String, ModelNode> getNodeMap() {
+        return nodeMap;
+    }
+
+    public FlexibleStringExpander getTrailNameExdr() {
+        return trailNameExdr;
+    }
+
+    /**
+     * Models the &lt;node&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class ModelNode extends ModelWidget {
+
+        private final List<ModelAction> actions;
+        // TODO: Make this a generic condition object.
+        private final ModelTreeCondition condition;
+        private final String entityName;
+        private final String entryName;
+        private final String expandCollapseStyle;
+        private final Label label;
+        private final Link link;
+        private final ModelTree modelTree;
+        private final String pkName;
+        private final String renderStyle;
+        private final FlexibleStringExpander screenLocationExdr;
+        private final FlexibleStringExpander screenNameExdr;
+        private final String shareScope;
+        private final List<ModelSubNode> subNodeList;
+        private final FlexibleStringExpander wrapStyleExdr;
+
+        public ModelNode(Element nodeElement, ModelTree modelTree) {
+            super(nodeElement);
+            this.modelTree = modelTree;
+            this.expandCollapseStyle = nodeElement.getAttribute("expand-collapse-style");
+            this.wrapStyleExdr = FlexibleStringExpander.getInstance(nodeElement.getAttribute("wrap-style"));
+            this.renderStyle = nodeElement.getAttribute("render-style");
+            this.entryName = nodeElement.getAttribute("entry-name");
+            this.entityName = nodeElement.getAttribute("entity-name");
+            this.pkName = nodeElement.getAttribute("join-field-name");
+            ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
+            // FIXME: Validate child elements, should be only one of actions, entity-one, service, script.
+            Element actionsElement = UtilXml.firstChildElement(nodeElement, "actions");
+            if (actionsElement != null) {
+                actions.addAll(ModelTreeAction.readNodeActions(this, actionsElement));
+            }
+            Element actionElement = UtilXml.firstChildElement(nodeElement, "entity-one");
+            if (actionElement != null) {
+                actions.add(new AbstractModelAction.EntityOne(this, actionElement));
+            }
+            actionElement = UtilXml.firstChildElement(nodeElement, "service");
+            if (actionElement != null) {
+                actions.add(new ModelTreeAction.Service(this, actionElement));
+            }
+            actionElement = UtilXml.firstChildElement(nodeElement, "script");
+            if (actionElement != null) {
+                actions.add(new ModelTreeAction.Script(this, actionElement));
+            }
+            actions.trimToSize();
+            this.actions = Collections.unmodifiableList(actions);
+            Element screenElement = UtilXml.firstChildElement(nodeElement, "include-screen");
+            if (screenElement != null) {
+                this.screenNameExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("name"));
+                this.screenLocationExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("location"));
+                this.shareScope = screenElement.getAttribute("share-scope");
+            } else {
+                this.screenNameExdr = FlexibleStringExpander.getInstance("");
+                this.screenLocationExdr = FlexibleStringExpander.getInstance("");
+                this.shareScope = "";
+            }
+            Element labelElement = UtilXml.firstChildElement(nodeElement, "label");
+            if (labelElement != null) {
+                this.label = new Label(labelElement);
+            } else {
+                this.label = null;
+            }
+            Element linkElement = UtilXml.firstChildElement(nodeElement, "link");
+            if (linkElement != null) {
+                this.link = new Link(linkElement);
+            } else {
+                this.link = null;
+            }
+            Element conditionElement = UtilXml.firstChildElement(nodeElement, "condition");
+            if (conditionElement != null) {
+                this.condition = new ModelTreeCondition(modelTree, conditionElement);
+            } else {
+                this.condition = null;
+            }
+            List<? extends Element> nodeElements = UtilXml.childElementList(nodeElement, "sub-node");
+            if (!nodeElements.isEmpty()) {
+                List<ModelSubNode> subNodeList = new ArrayList<ModelSubNode>();
+                for (Element subNodeElementEntry : nodeElements) {
+                    ModelSubNode subNode = new ModelSubNode(subNodeElementEntry, this);
+                    subNodeList.add(subNode);
+                }
+                this.subNodeList = Collections.unmodifiableList(subNodeList);
+            } else {
+                this.subNodeList = Collections.emptyList();
+            }
+        }
+
+        @Override
+        public void accept(ModelWidgetVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        private List<Object[]> getChildren(Map<String, Object> context) {
+            List<Object[]> subNodeValues = new ArrayList<Object[]>();
+            for (ModelSubNode subNode : subNodeList) {
+                String nodeName = subNode.getNodeName(context);
+                ModelNode node = modelTree.nodeMap.get(nodeName);
+                List<ModelAction> subNodeActions = subNode.getActions();
+                //if (Debug.infoOn()) Debug.logInfo(" context.currentValue:" + context.get("currentValue"), module);
+                AbstractModelAction.runSubActions(subNodeActions, context);
+                // List dataFound = (List)context.get("dataFound");
+                Iterator<? extends Map<String, ? extends Object>> dataIter = subNode.getListIterator(context);
+                if (dataIter instanceof EntityListIterator) {
+                    EntityListIterator eli = (EntityListIterator) dataIter;
+                    Map<String, Object> val = null;
+                    while ((val = eli.next()) != null) {
+                        Object[] arr = { node, val };
+                        subNodeValues.add(arr);
+                    }
+                    try {
+                        eli.close();
+                    } catch (GenericEntityException e) {
+                        Debug.logError(e, module);
+                        throw new RuntimeException(e.getMessage());
+                    }
+                } else if (dataIter != null) {
+                    while (dataIter.hasNext()) {
+                        Map<String, ? extends Object> val = dataIter.next();
+                        Object[] arr = { node, val };
+                        subNodeValues.add(arr);
+                    }
+                }
+            }
+            return subNodeValues;
+        }
+
+        public String getEntityName() {
+            if (!this.entityName.isEmpty()) {
+                return this.entityName;
+            } else {
+                return this.modelTree.getDefaultEntityName();
+            }
+        }
+
+        public String getEntryName() {
+            return this.entryName;
+        }
+
+        public String getExpandCollapseStyle() {
+            return expandCollapseStyle;
+        }
+
+        public ModelTree getModelTree() {
+            return this.modelTree;
+        }
+
+        public String getPkName(Map<String, Object> context) {
+            if (UtilValidate.isNotEmpty(this.pkName)) {
+                return this.pkName;
+            } else {
+                return this.modelTree.getDefaultPkName(context);
+            }
+        }
+
+        public String getRenderStyle() {
+            if (this.renderStyle.isEmpty())
+                return modelTree.getRenderStyle();
+            return this.renderStyle;
+        }
+
+        public String getWrapStyle(Map<String, Object> context) {
+            String val = this.wrapStyleExdr.expandString(context);
+            if (val.isEmpty()) {
+                val = this.modelTree.getWrapStyle(context);
+            }
+            return val;
+        }
+
+        public boolean hasChildren(Map<String, Object> context) {
+            List<Object[]> subNodeValues = getChildren(context);
+            boolean hasChildren = false;
+            Long nodeCount = null;
+            String countFieldName = "childBranchCount";
+            Object obj = null;
+            if (!this.entryName.isEmpty()) {
+                Map<String, Object> map = UtilGenerics.cast(context.get(this.entryName));
+                if (map instanceof GenericValue) {
+                    ModelEntity modelEntity = ((GenericValue) map).getModelEntity();
+                    if (modelEntity.isField(countFieldName)) {
+                        obj = map.get(countFieldName);
+                    }
+                }
+            } else {
+                obj = context.get(countFieldName);
+            }
+            if (obj != null) {
+                nodeCount = (Long) obj;
+            }
+            String entName = this.getEntityName();
+            Delegator delegator = WidgetWorker.getDelegator(context);
+            ModelEntity modelEntity = delegator.getModelEntity(entName);
+            ModelField modelField = null;
+            if (modelEntity.isField(countFieldName)) {
+                modelField = modelEntity.getField(countFieldName);
+            }
+            if (nodeCount == null && modelField != null || this.modelTree.forceChildCheck) {
+                getChildren(context);
+                /*
+                String id = (String)context.get(modelTree.getPkName());
+                if (UtilValidate.isNotEmpty(id)) {
+                    try {
+                        int leafCount = ContentManagementWorker.updateStatsTopDown(delegator, id, UtilMisc.toList("SUB_CONTENT", "PUBLISH_LINK"));
+                        GenericValue entity = delegator.findOne(entName, UtilMisc.toMap(modelTree.getPkName(), id), true);
+                        obj = entity.get("childBranchCount");
+                       if (obj != null)
+                           nodeCount = (Long)obj;
+                    } catch (GenericEntityException e) {
+                        Debug.logError(e, module);
+                       throw new RuntimeException(e.getMessage());
+                    }
+                }
+                */
+                nodeCount = Long.valueOf(subNodeValues.size());
+                String pkName = this.getPkName(context);
+                String id = null;
+                if (!this.entryName.isEmpty()) {
+                    id = UtilGenerics.<Map<String, String>> cast(context.get(this.entryName)).get(pkName);
+                } else {
+                    id = (String) context.get(pkName);
+                }
+                try {
+                    if (id != null && modelEntity.getPksSize() == 1) {
+                        GenericValue entity = EntityQuery.use(delegator).from(entName).where(pkName, id).queryOne();
+                        if (modelEntity.isField("childBranchCount")) {
+                            entity.put("childBranchCount", nodeCount);
+                            entity.store();
+                        }
+                    }
+                } catch (GenericEntityException e) {
+                    Debug.logError(e, module);
+                    throw new RuntimeException(e.getMessage());
+                }
+            } else if (nodeCount == null) {
+                getChildren(context);
+                if (subNodeValues != null) {
+                    nodeCount = Long.valueOf(subNodeValues.size());
+                }
+            }
+            if (nodeCount != null && nodeCount.intValue() > 0) {
+                hasChildren = true;
+            }
+            return hasChildren;
+        }
+
+        public boolean isExpandCollapse() {
+            boolean isExpCollapse = false;
+            String rStyle = getRenderStyle();
+            if (rStyle != null && rStyle.equals("expand-collapse"))
+                isExpCollapse = true;
+            return isExpCollapse;
+        }
+
+        public boolean isFollowTrail() {
+            boolean isFollowTrail = false;
+            String rStyle = getRenderStyle();
+            if (rStyle != null && (rStyle.equals("follow-trail") || rStyle.equals("show-peers") || rStyle.equals("follow-trail"))) {
+                isFollowTrail = true;
+            }
+            return isFollowTrail;
+        }
+
+        public boolean isRootNode() {
+            return getName().equals(modelTree.getRootNodeName());
+        }
+
+        public void renderNodeString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer,
+                int depth) throws IOException, GeneralException {
+            boolean passed = true;
+            if (this.condition != null) {
+                if (!this.condition.getCondition().eval(context)) {
+                    passed = false;
+                }
+            }
+            //Debug.logInfo("in ModelMenu, name:" + this.getName(), module);
+            if (passed) {
+                List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
+                context.put("processChildren", Boolean.TRUE);
+                // this action will usually obtain the "current" entity
+                ModelTreeAction.runSubActions(this.actions, context);
+                String pkName = getPkName(context);
+                String id = null;
+                if (!this.entryName.isEmpty()) {
+                    id = UtilGenerics.<Map<String, String>> cast(context.get(this.entryName)).get(pkName);
+                } else {
+                    id = (String) context.get(pkName);
+                }
+                currentNodeTrail.add(id);
+                treeStringRenderer.renderNodeBegin(writer, context, this, depth);
+                //if (Debug.infoOn()) Debug.logInfo(" context:" +
+                // context.entrySet(), module);
+                try {
+                    String screenName = null;
+                    if (!screenNameExdr.isEmpty())
+                        screenName = screenNameExdr.expandString(context);
+                    String screenLocation = null;
+                    if (!screenLocationExdr.isEmpty())
+                        screenLocation = screenLocationExdr.expandString(context);
+                    if (screenName != null && screenLocation != null) {
+                        ScreenStringRenderer screenStringRenderer = treeStringRenderer.getScreenStringRenderer(context);
+                        ModelScreen modelScreen = ScreenFactory.getScreenFromLocation(screenLocation, screenName);
+                        modelScreen.renderScreenString(writer, context, screenStringRenderer);
+                    }
+                    if (label != null) {
+                        label.renderLabelString(writer, context, treeStringRenderer);
+                    }
+                    if (link != null) {
+                        link.renderLinkString(writer, context, treeStringRenderer);
+                    }
+                    treeStringRenderer.renderLastElement(writer, context, this);
+                    Boolean processChildren = (Boolean) context.get("processChildren");
+                    //if (Debug.infoOn()) Debug.logInfo(" processChildren:" + processChildren, module);
+                    if (processChildren.booleanValue()) {
+                        List<Object[]> subNodeValues = getChildren(context);
+                        int newDepth = depth + 1;
+                        for (Object[] arr : subNodeValues) {
+                            ModelNode node = (ModelNode) arr[0];
+                            Map<String, Object> val = UtilGenerics.checkMap(arr[1]);
+                            //GenericPK pk = val.getPrimaryKey();
+                            //if (Debug.infoOn()) Debug.logInfo(" pk:" + pk,
+                            // module);
+                            String thisPkName = node.getPkName(context);
+                            String thisEntityId = (String) val.get(thisPkName);
+                            MapStack<String> newContext = MapStack.create(context);
+                            newContext.push();
+                            String nodeEntryName = node.getEntryName();
+                            if (!nodeEntryName.isEmpty()) {
+                                newContext.put(nodeEntryName, val);
+                            } else {
+                                newContext.putAll(val);
+                            }
+                            String targetEntityId = null;
+                            List<String> targetNodeTrail = UtilGenerics.checkList(context.get("targetNodeTrail"));
+                            if (newDepth < targetNodeTrail.size()) {
+                                targetEntityId = targetNodeTrail.get(newDepth);
+                            }
+                            if ((targetEntityId != null && targetEntityId.equals(thisEntityId))
+                                    || this.showPeers(newDepth, context)) {
+                                node.renderNodeString(writer, newContext, treeStringRenderer, newDepth);
+                            }
+                        }
+                    }
+                } catch (ScreenRenderException e) {
+                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                } catch (SAXException e) {
+                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                } catch (ParserConfigurationException e3) {
+                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e3.toString();
+                    Debug.logError(e3, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                } catch (IOException e2) {
+                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e2.toString();
+                    Debug.logError(e2, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
+                treeStringRenderer.renderNodeEnd(writer, context, this);
+                int removeIdx = currentNodeTrail.size() - 1;
+                if (removeIdx >= 0)
+                    currentNodeTrail.remove(removeIdx);
+            }
+        }
+
+        public boolean showPeers(int currentDepth, Map<String, Object> context) {
+            int trailSize = 0;
+            List<?> trail = UtilGenerics.checkList(context.get("targetNodeTrail"));
+            int openDepth = modelTree.getOpenDepth();
+            int postTrailOpenDepth = modelTree.getPostTrailOpenDepth();
+            if (trail != null)
+                trailSize = trail.size();
+
+            boolean showPeers = false;
+            String rStyle = getRenderStyle();
+            if (rStyle == null) {
+                showPeers = true;
+            } else if (!isFollowTrail()) {
+                showPeers = true;
+            } else if ((currentDepth < trailSize) && (rStyle != null)
+                    && (rStyle.equals("show-peers") || rStyle.equals("expand-collapse"))) {
+                showPeers = true;
+            } else if (openDepth >= currentDepth) {
+                showPeers = true;
+            } else {
+                int depthAfterTrail = currentDepth - trailSize;
+                if (depthAfterTrail >= 0 && depthAfterTrail <= postTrailOpenDepth)
+                    showPeers = true;
+            }
+            return showPeers;
+        }
+        
+        public List<ModelAction> getActions() {
+            return actions;
+        }
+
+        public ModelTreeCondition getCondition() {
+            return condition;
+        }
+
+        public Label getLabel() {
+            return label;
+        }
+
+        public Link getLink() {
+            return link;
+        }
+
+        public String getPkName() {
+            return pkName;
+        }
+
+        public FlexibleStringExpander getScreenLocationExdr() {
+            return screenLocationExdr;
+        }
+
+        public FlexibleStringExpander getScreenNameExdr() {
+            return screenNameExdr;
+        }
+
+        public String getShareScope() {
+            return shareScope;
+        }
+
+        public List<ModelSubNode> getSubNodeList() {
+            return subNodeList;
+        }
+
+        public FlexibleStringExpander getWrapStyleExdr() {
+            return wrapStyleExdr;
+        }
+
+        /**
+         * Models the &lt;image&gt; element.
+         * 
+         * @see <code>widget-tree.xsd</code>
+         */
+        public static class Image {
+
+            private final FlexibleStringExpander borderExdr;
+            private final FlexibleStringExpander heightExdr;
+            private final FlexibleStringExpander idExdr;
+            private final FlexibleStringExpander srcExdr;
+            private final FlexibleStringExpander styleExdr;
+            private final String urlMode;
+            private final FlexibleStringExpander widthExdr;
+
+            public Image(Element imageElement) {
+                this.borderExdr = FlexibleStringExpander
+                        .getInstance(UtilXml.checkEmpty(imageElement.getAttribute("border"), "0"));
+                this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
+                this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id"));
+                this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("src"));
+                this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style"));
+                this.urlMode = UtilXml.checkEmpty(imageElement.getAttribute("url-mode"), "content");
+                this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
+            }
+
+            public String getBorder(Map<String, Object> context) {
+                return this.borderExdr.expandString(context);
+            }
+
+            public String getHeight(Map<String, Object> context) {
+                return this.heightExdr.expandString(context);
+            }
+
+            public String getId(Map<String, Object> context) {
+                return this.idExdr.expandString(context);
+            }
+
+            public String getSrc(Map<String, Object> context) {
+                return this.srcExdr.expandString(context);
+            }
+
+            public String getStyle(Map<String, Object> context) {
+                return this.styleExdr.expandString(context);
+            }
+
+            public String getUrlMode() {
+                return this.urlMode;
+            }
+
+            public String getWidth(Map<String, Object> context) {
+                return this.widthExdr.expandString(context);
+            }
+
+            public void renderImageString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
+                try {
+                    treeStringRenderer.renderImage(writer, context, this);
+                } catch (IOException e) {
+                    String errMsg = "Error rendering image with id [" + getId(context) + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
+            }
+        }
+
+        /**
+         * Models the &lt;label&gt; element.
+         * 
+         * @see <code>widget-tree.xsd</code>
+         */
+        public static final class Label {
+            private final FlexibleStringExpander idExdr;
+            private final FlexibleStringExpander styleExdr;
+            private final FlexibleStringExpander textExdr;
+
+            public Label(Element labelElement) {
+                String textAttr = labelElement.getAttribute("text");
+                String pcdata = UtilXml.checkEmpty(UtilXml.elementValue(labelElement), "");
+                this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata);
+                this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id"));
+                this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style"));
+            }
+
+            public String getId(Map<String, Object> context) {
+                return this.idExdr.expandString(context);
+            }
+
+            public String getStyle(Map<String, Object> context) {
+                return this.styleExdr.expandString(context);
+            }
+
+            public String getText(Map<String, Object> context) {
+                String text = this.textExdr.expandString(context);
+                // FIXME: Encoding should be done by the renderer, not by the model.
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    text = simpleEncoder.encode(text);
+                }
+                return text;
+            }
+
+            public void renderLabelString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
+                try {
+                    treeStringRenderer.renderLabel(writer, context, this);
+                } catch (IOException e) {
+                    String errMsg = "Error rendering label with id [" + getId(context) + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
+            }
+
+            public FlexibleStringExpander getIdExdr() {
+                return idExdr;
+            }
+
+            public FlexibleStringExpander getStyleExdr() {
+                return styleExdr;
+            }
+
+            public FlexibleStringExpander getTextExdr() {
+                return textExdr;
+            }
+        }
+
+        /**
+         * Models the &lt;link&gt; element.
+         * 
+         * @see <code>widget-tree.xsd</code>
+         */
+        public static class Link {
+            private final boolean encode;
+            private final boolean fullPath;
+            private final FlexibleStringExpander idExdr;
+            private final Image image;
+            private final String linkType;
+            private final FlexibleStringExpander nameExdr;
+            private final List<Parameter> parameterList;
+            private final FlexibleStringExpander prefixExdr;
+            private final boolean secure;
+            private final FlexibleStringExpander styleExdr;
+            private final FlexibleStringExpander targetExdr;
+            private final FlexibleStringExpander targetWindowExdr;
+            private final FlexibleStringExpander textExdr;
+            private final FlexibleStringExpander titleExdr;
+            private final String urlMode;
+
+            public Link(Element linkElement) {
+                this.encode = "true".equals(linkElement.getAttribute("encode"));
+                this.fullPath = "true".equals(linkElement.getAttribute("full-path"));
+                this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id"));
+                Element imageElement = UtilXml.firstChildElement(linkElement, "image");
+                if (imageElement != null) {
+                    this.image = new Image(imageElement);
+                } else {
+                    this.image = null;
+                }
+                this.linkType = linkElement.getAttribute("link-type");
+                this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name"));
+                List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
+                if (!parameterElementList.isEmpty()) {
+                    List<Parameter> parameterList = new ArrayList<Parameter>(parameterElementList.size());
+                    for (Element parameterElement : parameterElementList) {
+                        parameterList.add(new Parameter(parameterElement));
+                    }
+                    this.parameterList = Collections.unmodifiableList(parameterList);
+                } else {
+                    this.parameterList = Collections.emptyList();
+                }
+                this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
+                this.secure = "true".equals(linkElement.getAttribute("secure"));
+                this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style"));
+                this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target"));
+                this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window"));
+                this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
+                this.titleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("title"));
+                this.urlMode = UtilXml.checkEmpty(linkElement.getAttribute("link-type"), "intra-app");
+            }
+
+            // FIXME: Using a widget model in this way is an ugly hack.
+            public Link(String style, String target, String text) {
+                this.encode = false;
+                this.fullPath = false;
+                this.idExdr = FlexibleStringExpander.getInstance("");
+                this.image = null;
+                this.linkType = "";
+                this.nameExdr = FlexibleStringExpander.getInstance("");
+                this.parameterList = Collections.emptyList();
+                this.prefixExdr = FlexibleStringExpander.getInstance("");
+                this.secure = false;
+                this.styleExdr = FlexibleStringExpander.getInstance(style);
+                this.targetExdr = FlexibleStringExpander.getInstance(target);
+                this.targetWindowExdr = FlexibleStringExpander.getInstance("");
+                this.textExdr = FlexibleStringExpander.getInstance(text);
+                this.titleExdr = FlexibleStringExpander.getInstance("");
+                this.urlMode = "intra-app";
+            }
+
+            public boolean getEncode() {
+                return this.encode;
+            }
+
+            public boolean getFullPath() {
+                return this.fullPath;
+            }
+
+            public String getId(Map<String, Object> context) {
+                return this.idExdr.expandString(context);
+            }
+
+            public Image getImage() {
+                return this.image;
+            }
+
+            public String getLinkType() {
+                return this.linkType;
+            }
+
+            public String getName(Map<String, Object> context) {
+                return this.nameExdr.expandString(context);
+            }
+
+            public Map<String, String> getParameterMap(Map<String, Object> context) {
+                Map<String, String> fullParameterMap = new HashMap<String, String>();
+                /* leaving this here... may want to add it at some point like the hyperlink element:
+                Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
+                if (addlParamMap != null) {
+                    fullParameterMap.putAll(addlParamMap);
+                }
+                */
+                for (CommonWidgetModels.Parameter parameter : this.parameterList) {
+                    fullParameterMap.put(parameter.getName(), parameter.getValue(context));
+                }
+                return fullParameterMap;
+            }
+
+            public String getPrefix(Map<String, Object> context) {
+                return this.prefixExdr.expandString(context);
+            }
+
+            public boolean getSecure() {
+                return this.secure;
+            }
+
+            public String getStyle(Map<String, Object> context) {
+                return this.styleExdr.expandString(context);
+            }
+
+            public String getTarget(Map<String, Object> context) {
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    return this.targetExdr.expandString(UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context,
+                            simpleEncoder));
+                } else {
+                    return this.targetExdr.expandString(context);
+                }
+            }
+
+            public String getTargetWindow(Map<String, Object> context) {
+                return this.targetWindowExdr.expandString(context);
+            }
+
+            public String getText(Map<String, Object> context) {
+                String text = this.textExdr.expandString(context);
+                // FIXME: Encoding should be done by the renderer, not by the model.
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    text = simpleEncoder.encode(text);
+                }
+                return text;
+            }
+
+            public String getTitle(Map<String, Object> context) {
+                String title = this.titleExdr.expandString(context);
+                // FIXME: Encoding should be done by the renderer, not by the model.
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                if (simpleEncoder != null) {
+                    title = simpleEncoder.encode(title);
+                }
+                return title;
+            }
+
+            public String getUrlMode() {
+                return this.urlMode;
+            }
+
+            public void renderLinkString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
+                try {
+                    treeStringRenderer.renderLink(writer, context, this);
+                } catch (IOException e) {
+                    String errMsg = "Error rendering link with id [" + getId(context) + "]: " + e.toString();
+                    Debug.logError(e, errMsg, module);
+                    throw new RuntimeException(errMsg);
+                }
+            }
+
+            public FlexibleStringExpander getIdExdr() {
+                return idExdr;
+            }
+
+            public FlexibleStringExpander getNameExdr() {
+                return nameExdr;
+            }
+
+            public List<Parameter> getParameterList() {
+                return parameterList;
+            }
+
+            public FlexibleStringExpander getPrefixExdr() {
+                return prefixExdr;
+            }
+
+            public FlexibleStringExpander getStyleExdr() {
+                return styleExdr;
+            }
+
+            public FlexibleStringExpander getTargetExdr() {
+                return targetExdr;
+            }
+
+            public FlexibleStringExpander getTargetWindowExdr() {
+                return targetWindowExdr;
+            }
+
+            public FlexibleStringExpander getTextExdr() {
+                return textExdr;
+            }
+
+            public FlexibleStringExpander getTitleExdr() {
+                return titleExdr;
+            }
+        }
+
+        /**
+         * Models the &lt;sub-node&gt; element.
+         * 
+         * @see <code>widget-tree.xsd</code>
+         */
+        public static class ModelSubNode extends ModelWidget {
+
+            private final List<ModelAction> actions;
+            private final FlexibleStringExpander nodeNameExdr;
+            private final ModelNode rootNode;
+            private final String iteratorKey;
+
+            public ModelSubNode(Element subNodeElement, ModelNode modelNode) {
+                super(subNodeElement);
+                this.rootNode = modelNode;
+                this.nodeNameExdr = FlexibleStringExpander.getInstance(subNodeElement.getAttribute("node-name"));
+                ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
+                // FIXME: Validate child elements, should be only one of actions, entity-and, entity-condition, service, script.
+                Element actionsElement = UtilXml.firstChildElement(subNodeElement, "actions");
+                if (actionsElement != null) {
+                    actions.addAll(ModelTreeAction.readSubNodeActions(this, actionsElement));
+                }
+                Element actionElement = UtilXml.firstChildElement(subNodeElement, "entity-and");
+                if (actionElement != null) {
+                    actions.add(new ModelTreeAction.EntityAnd(this, actionElement));
+                }
+                actionElement = UtilXml.firstChildElement(subNodeElement, "service");
+                if (actionElement != null) {
+                    actions.add(new ModelTreeAction.Service(this, actionElement));
+                }
+                actionElement = UtilXml.firstChildElement(subNodeElement, "entity-condition");
+                if (actionElement != null) {
+                    actions.add(new ModelTreeAction.EntityCondition(this, actionElement));
+                }
+                actionElement = UtilXml.firstChildElement(subNodeElement, "script");
+                if (actionElement != null) {
+                    actions.add(new ModelTreeAction.Script(this, actionElement));
+                }
+                actions.trimToSize();
+                this.actions = Collections.unmodifiableList(actions);
+                this.iteratorKey = this.rootNode.getName().concat(".").concat(this.nodeNameExdr.getOriginal())
+                        .concat(".ITERATOR");
+            }
+
+            @Override
+            public void accept(ModelWidgetVisitor visitor) throws Exception {
+                visitor.visit(this);
+            }
+
+            public List<ModelAction> getActions() {
+                return actions;
+            }
+
+            @SuppressWarnings("unchecked")
+            public ListIterator<? extends Map<String, ? extends Object>> getListIterator(Map<String, Object> context) {
+                return (ListIterator<? extends Map<String, ? extends Object>>) context.get(this.iteratorKey);
+            }
+
+            public ModelTree.ModelNode getNode() {
+                return this.rootNode;
+            }
+
+            public String getNodeName(Map<String, Object> context) {
+                return this.nodeNameExdr.expandString(context);
+            }
+
+            public FlexibleStringExpander getNodeNameExdr() {
+                return nodeNameExdr;
+            }
+
+            public void setListIterator(ListIterator<? extends Map<String, ? extends Object>> iter, Map<String, Object> context) {
+                context.put(this.iteratorKey, iter);
+            }
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java b/framework/widget/src/org/ofbiz/widget/model/ModelTreeAction.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelTreeAction.java
index 3460b5b..f9734c8 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelTreeAction.java
@@ -1,463 +1,460 @@
-/*******************************************************************************
- * 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.ofbiz.widget.tree;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.regex.PatternSyntaxException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.ScriptUtil;
-import org.ofbiz.base.util.UtilFormatOut;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.finder.ByAndFinder;
-import org.ofbiz.entity.finder.ByConditionFinder;
-import org.ofbiz.entity.finder.EntityFinderUtil;
-import org.ofbiz.entity.util.EntityListIterator;
-import org.ofbiz.minilang.MiniLangException;
-import org.ofbiz.minilang.SimpleMethod;
-import org.ofbiz.minilang.method.MethodContext;
-import org.ofbiz.service.DispatchContext;
-import org.ofbiz.service.GenericServiceException;
-import org.ofbiz.service.ModelService;
-import org.ofbiz.widget.AbstractModelAction;
-import org.ofbiz.widget.ModelAction;
-import org.ofbiz.widget.ModelActionVisitor;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.tree.ModelTree.ModelNode;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Abstract tree action.
- */
-@SuppressWarnings("serial")
-public abstract class ModelTreeAction extends AbstractModelAction {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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.
-     * 
-     * 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 = ModelTreeAction.class.getName();
-
-    public static List<ModelAction> readNodeActions(ModelNode modelNode, Element actionsElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(actionsElement);
-        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
-        for (Element actionElement : actionElementList) {
-            if ("service".equals(actionElement.getNodeName())) {
-                actions.add(new Service(modelNode, actionElement));
-            } else if ("script".equals(actionElement.getNodeName())) {
-                actions.add(new Script(modelNode, actionElement));
-            } else {
-                actions.add(AbstractModelAction.newInstance(modelNode, actionElement));
-            }
-        }
-        return actions;
-    }
-
-    public static List<ModelAction> readSubNodeActions(ModelNode.ModelSubNode modelSubNode, Element actionsElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(actionsElement);
-        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
-        for (Element actionElement : actionElementList) {
-            if ("service".equals(actionElement.getNodeName())) {
-                actions.add(new Service(modelSubNode, actionElement));
-            } else if ("entity-and".equals(actionElement.getNodeName())) {
-                actions.add(new EntityAnd(modelSubNode, actionElement));
-            } else if ("entity-condition".equals(actionElement.getNodeName())) {
-                actions.add(new EntityCondition(modelSubNode, actionElement));
-            } else if ("script".equals(actionElement.getNodeName())) {
-                actions.add(new Script(modelSubNode, actionElement));
-            } else {
-                actions.add(AbstractModelAction.newInstance(modelSubNode, actionElement));
-            }
-        }
-        return actions;
-    }
-
-    private final ModelNode.ModelSubNode modelSubNode;
-    private final ModelTree modelTree;
-
-    protected ModelTreeAction(ModelNode modelNode, Element actionElement) {
-        if (Debug.verboseOn())
-            Debug.logVerbose("Reading Tree action with name: " + actionElement.getNodeName(), module);
-        this.modelTree = modelNode.getModelTree();
-        this.modelSubNode = null;
-    }
-
-    protected ModelTreeAction(ModelNode.ModelSubNode modelSubNode, Element actionElement) {
-        if (Debug.verboseOn())
-            Debug.logVerbose("Reading Tree action with name: " + actionElement.getNodeName(), module);
-        this.modelSubNode = modelSubNode;
-        this.modelTree = modelSubNode.getNode().getModelTree();
-    }
-
-    public ModelNode.ModelSubNode getModelSubNode() {
-        return modelSubNode;
-    }
-
-    public ModelTree getModelTree() {
-        return modelTree;
-    }
-
-    /**
-     * Models the &lt;entity-and&gt; element.
-     * 
-     * @see <code>widget-tree.xsd</code>
-     */
-    public static class EntityAnd extends ModelTreeAction {
-        private final ByAndFinder finder;
-        private final String listName;
-
-        public EntityAnd(ModelNode.ModelSubNode modelSubNode, Element entityAndElement) {
-            super(modelSubNode, entityAndElement);
-            boolean useCache = "true".equalsIgnoreCase(entityAndElement.getAttribute("use-cache"));
-            Document ownerDoc = entityAndElement.getOwnerDocument();
-            if (!useCache)
-                UtilXml.addChildElement(entityAndElement, "use-iterator", ownerDoc);
-            String listName = UtilFormatOut.checkEmpty(entityAndElement.getAttribute("list"),
-                    entityAndElement.getAttribute("list-name"));
-            if (UtilValidate.isEmpty(listName))
-                listName = "_LIST_ITERATOR_";
-            this.listName = listName;
-            entityAndElement.setAttribute("list-name", this.listName);
-            finder = new ByAndFinder(entityAndElement);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public ByAndFinder getFinder() {
-            return finder;
-        }
-
-        public String getListName() {
-            return listName;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                context.put(this.listName, null);
-                finder.runFind(context, WidgetWorker.getDelegator(context));
-                Object obj = context.get(this.listName);
-                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
-                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
-                    this.getModelSubNode().setListIterator(listIt, context);
-                } else {
-                    if (obj instanceof List<?>) {
-                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.checkList(obj);
-                        this.getModelSubNode().setListIterator(list.listIterator(), context);
-                    }
-                }
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-
-    /**
-     * Models the &lt;entity-condition&gt; element.
-     * 
-     * @see <code>widget-tree.xsd</code>
-     */
-    public static class EntityCondition extends ModelTreeAction {
-        private final ByConditionFinder finder;
-        private final String listName;
-
-        public EntityCondition(ModelNode.ModelSubNode modelSubNode, Element entityConditionElement) {
-            super(modelSubNode, entityConditionElement);
-            Document ownerDoc = entityConditionElement.getOwnerDocument();
-            boolean useCache = "true".equalsIgnoreCase(entityConditionElement.getAttribute("use-cache"));
-            if (!useCache)
-                UtilXml.addChildElement(entityConditionElement, "use-iterator", ownerDoc);
-            String listName = UtilFormatOut.checkEmpty(entityConditionElement.getAttribute("list"),
-                    entityConditionElement.getAttribute("list-name"));
-            if (UtilValidate.isEmpty(listName))
-                listName = "_LIST_ITERATOR_";
-            this.listName = listName;
-            entityConditionElement.setAttribute("list-name", this.listName);
-            finder = new ByConditionFinder(entityConditionElement);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public ByConditionFinder getFinder() {
-            return finder;
-        }
-
-        public String getListName() {
-            return listName;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                context.put(this.listName, null);
-                finder.runFind(context, WidgetWorker.getDelegator(context));
-                Object obj = context.get(this.listName);
-                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
-                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
-                    this.getModelSubNode().setListIterator(listIt, context);
-                } else {
-                    if (obj instanceof List<?>) {
-                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.cast(obj);
-                        this.getModelSubNode().setListIterator(list.listIterator(), context);
-                    }
-                }
-            } catch (GeneralException e) {
-                String errMsg = "Error doing entity query by condition: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-
-    /**
-     * Models the &lt;script&gt; element.
-     * 
-     * @see <code>widget-tree.xsd</code>
-     */
-    public static class Script extends ModelTreeAction {
-        private final String location;
-        private final String method;
-
-        public Script(ModelNode modelNode, Element scriptElement) {
-            super(modelNode, scriptElement);
-            String scriptLocation = scriptElement.getAttribute("location");
-            this.location = WidgetWorker.getScriptLocation(scriptLocation);
-            this.method = WidgetWorker.getScriptMethodName(scriptLocation);
-        }
-
-        public Script(ModelNode.ModelSubNode modelSubNode, Element scriptElement) {
-            super(modelSubNode, scriptElement);
-            String scriptLocation = scriptElement.getAttribute("location");
-            this.location = WidgetWorker.getScriptLocation(scriptLocation);
-            this.method = WidgetWorker.getScriptMethodName(scriptLocation);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public String getLocation() {
-            return location;
-        }
-
-        public String getMethod() {
-            return method;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            context.put("_LIST_ITERATOR_", null);
-            if (location.endsWith(".xml")) {
-                Map<String, Object> localContext = new HashMap<String, Object>();
-                localContext.putAll(context);
-                DispatchContext ctx = WidgetWorker.getDispatcher(context).getDispatchContext();
-                MethodContext methodContext = new MethodContext(ctx, localContext, null);
-                try {
-                    SimpleMethod.runSimpleMethod(location, method, methodContext);
-                    context.putAll(methodContext.getResults());
-                } catch (MiniLangException e) {
-                    throw new RuntimeException("Error running simple method at location [" + location + "]", e);
-                }
-            } else {
-                ScriptUtil.executeScript(this.location, this.method, context);
-            }
-            Object obj = context.get("_LIST_ITERATOR_");
-            if (this.getModelSubNode() != null) {
-                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
-                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
-                    this.getModelSubNode().setListIterator(listIt, context);
-                } else {
-                    if (obj instanceof List<?>) {
-                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.checkList(obj);
-                        this.getModelSubNode().setListIterator(list.listIterator(), context);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Models the &lt;service&gt; element.
-     * 
-     * @see <code>widget-tree.xsd</code>
-     */
-    public static class Service extends ModelTreeAction {
-        private final FlexibleStringExpander autoFieldMapExdr;
-        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
-        private final FlexibleStringExpander resultMapListNameExdr;
-        private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
-        private final FlexibleStringExpander resultMapValueNameExdr;
-        private final FlexibleStringExpander serviceNameExdr;
-        private final FlexibleStringExpander valueNameExdr;
-
-        public Service(ModelNode modelNode, Element serviceElement) {
-            super(modelNode, serviceElement);
-            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
-            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
-            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
-            this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
-            this.resultMapValueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-value"));
-            this.valueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("value"));
-            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
-        }
-
-        public Service(ModelNode.ModelSubNode modelSubNode, Element serviceElement) {
-            super(modelSubNode, serviceElement);
-            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
-            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
-            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
-            this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
-            this.resultMapValueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-value"));
-            this.valueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("value"));
-            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getAutoFieldMapExdr() {
-            return autoFieldMapExdr;
-        }
-
-        public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() {
-            return fieldMap;
-        }
-
-        public FlexibleStringExpander getResultMapListNameExdr() {
-            return resultMapListNameExdr;
-        }
-
-        public FlexibleMapAccessor<Map<String, Object>> getResultMapNameAcsr() {
-            return resultMapNameAcsr;
-        }
-
-        public FlexibleStringExpander getResultMapValueNameExdr() {
-            return resultMapValueNameExdr;
-        }
-
-        public FlexibleStringExpander getServiceNameExdr() {
-            return serviceNameExdr;
-        }
-
-        public FlexibleStringExpander getValueNameExdr() {
-            return valueNameExdr;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            String serviceNameExpanded = this.serviceNameExdr.expandString(context);
-            if (UtilValidate.isEmpty(serviceNameExpanded)) {
-                throw new IllegalArgumentException("Service name was empty, expanded from: " + this.serviceNameExdr.getOriginal());
-            }
-            String autoFieldMapString = this.autoFieldMapExdr.expandString(context);
-            boolean autoFieldMapBool = !"false".equals(autoFieldMapString);
-            try {
-                Map<String, Object> serviceContext = null;
-                if (autoFieldMapBool) {
-                    serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
-                            .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context);
-                } else {
-                    serviceContext = new HashMap<String, Object>();
-                }
-                if (this.fieldMap != null) {
-                    EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, serviceContext);
-                }
-                Map<String, Object> result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext);
-                if (!this.resultMapNameAcsr.isEmpty()) {
-                    this.resultMapNameAcsr.put(context, result);
-                    String queryString = (String) result.get("queryString");
-                    context.put("queryString", queryString);
-                    context.put("queryStringMap", result.get("queryStringMap"));
-                    if (UtilValidate.isNotEmpty(queryString)) {
-                        try {
-                            String queryStringEncoded = queryString.replaceAll("&", "%26");
-                            context.put("queryStringEncoded", queryStringEncoded);
-                        } catch (PatternSyntaxException e) {
-
-                        }
-                    }
-                } else {
-                    context.putAll(result);
-                }
-                String resultMapListName = resultMapListNameExdr.expandString(context);
-                //String resultMapListIteratorName = resultMapListIteratorNameExdr.expandString(context);
-                String resultMapValueName = resultMapValueNameExdr.expandString(context);
-                String valueName = valueNameExdr.expandString(context);
-                if (this.getModelSubNode() != null) {
-                    //ListIterator iter = null;
-                    if (UtilValidate.isNotEmpty(resultMapListName)) {
-                        List<? extends Map<String, ? extends Object>> lst = UtilGenerics.checkList(result.get(resultMapListName));
-                        if (lst != null) {
-                            if (lst instanceof ListIterator<?>) {
-                                ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(lst);
-                                this.getModelSubNode().setListIterator(listIt, context);
-                            } else {
-                                this.getModelSubNode().setListIterator(lst.listIterator(), context);
-                            }
-                        }
-                    }
-                } else {
-                    if (UtilValidate.isNotEmpty(resultMapValueName)) {
-                        if (UtilValidate.isNotEmpty(valueName)) {
-                            context.put(valueName, result.get(resultMapValueName));
-                        } else {
-                            Map<String, Object> resultMap = UtilGenerics.checkMap(result.get(resultMapValueName));
-                            context.putAll(resultMap);
-                        }
-                    }
-                }
-            } catch (GenericServiceException e) {
-                String errMsg = "Error calling service with name " + serviceNameExpanded + ": " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.regex.PatternSyntaxException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.ScriptUtil;
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.collections.FlexibleMapAccessor;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.finder.ByAndFinder;
+import org.ofbiz.entity.finder.ByConditionFinder;
+import org.ofbiz.entity.finder.EntityFinderUtil;
+import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.minilang.MiniLangException;
+import org.ofbiz.minilang.SimpleMethod;
+import org.ofbiz.minilang.method.MethodContext;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.ModelService;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.ModelTree.ModelNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Abstract tree action.
+ */
+@SuppressWarnings("serial")
+public abstract class ModelTreeAction extends AbstractModelAction {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     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.
+     * 
+     * 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 = ModelTreeAction.class.getName();
+
+    public static List<ModelAction> readNodeActions(ModelNode modelNode, Element actionsElement) {
+        List<? extends Element> actionElementList = UtilXml.childElementList(actionsElement);
+        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
+        for (Element actionElement : actionElementList) {
+            if ("service".equals(actionElement.getNodeName())) {
+                actions.add(new Service(modelNode, actionElement));
+            } else if ("script".equals(actionElement.getNodeName())) {
+                actions.add(new Script(modelNode, actionElement));
+            } else {
+                actions.add(AbstractModelAction.newInstance(modelNode, actionElement));
+            }
+        }
+        return actions;
+    }
+
+    public static List<ModelAction> readSubNodeActions(ModelNode.ModelSubNode modelSubNode, Element actionsElement) {
+        List<? extends Element> actionElementList = UtilXml.childElementList(actionsElement);
+        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
+        for (Element actionElement : actionElementList) {
+            if ("service".equals(actionElement.getNodeName())) {
+                actions.add(new Service(modelSubNode, actionElement));
+            } else if ("entity-and".equals(actionElement.getNodeName())) {
+                actions.add(new EntityAnd(modelSubNode, actionElement));
+            } else if ("entity-condition".equals(actionElement.getNodeName())) {
+                actions.add(new EntityCondition(modelSubNode, actionElement));
+            } else if ("script".equals(actionElement.getNodeName())) {
+                actions.add(new Script(modelSubNode, actionElement));
+            } else {
+                actions.add(AbstractModelAction.newInstance(modelSubNode, actionElement));
+            }
+        }
+        return actions;
+    }
+
+    private final ModelNode.ModelSubNode modelSubNode;
+    private final ModelTree modelTree;
+
+    protected ModelTreeAction(ModelNode modelNode, Element actionElement) {
+        if (Debug.verboseOn())
+            Debug.logVerbose("Reading Tree action with name: " + actionElement.getNodeName(), module);
+        this.modelTree = modelNode.getModelTree();
+        this.modelSubNode = null;
+    }
+
+    protected ModelTreeAction(ModelNode.ModelSubNode modelSubNode, Element actionElement) {
+        if (Debug.verboseOn())
+            Debug.logVerbose("Reading Tree action with name: " + actionElement.getNodeName(), module);
+        this.modelSubNode = modelSubNode;
+        this.modelTree = modelSubNode.getNode().getModelTree();
+    }
+
+    public ModelNode.ModelSubNode getModelSubNode() {
+        return modelSubNode;
+    }
+
+    public ModelTree getModelTree() {
+        return modelTree;
+    }
+
+    /**
+     * Models the &lt;entity-and&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class EntityAnd extends ModelTreeAction {
+        private final ByAndFinder finder;
+        private final String listName;
+
+        public EntityAnd(ModelNode.ModelSubNode modelSubNode, Element entityAndElement) {
+            super(modelSubNode, entityAndElement);
+            boolean useCache = "true".equalsIgnoreCase(entityAndElement.getAttribute("use-cache"));
+            Document ownerDoc = entityAndElement.getOwnerDocument();
+            if (!useCache)
+                UtilXml.addChildElement(entityAndElement, "use-iterator", ownerDoc);
+            String listName = UtilFormatOut.checkEmpty(entityAndElement.getAttribute("list"),
+                    entityAndElement.getAttribute("list-name"));
+            if (UtilValidate.isEmpty(listName))
+                listName = "_LIST_ITERATOR_";
+            this.listName = listName;
+            entityAndElement.setAttribute("list-name", this.listName);
+            finder = new ByAndFinder(entityAndElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public ByAndFinder getFinder() {
+            return finder;
+        }
+
+        public String getListName() {
+            return listName;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            try {
+                context.put(this.listName, null);
+                finder.runFind(context, WidgetWorker.getDelegator(context));
+                Object obj = context.get(this.listName);
+                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
+                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
+                    this.getModelSubNode().setListIterator(listIt, context);
+                } else {
+                    if (obj instanceof List<?>) {
+                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.checkList(obj);
+                        this.getModelSubNode().setListIterator(list.listIterator(), context);
+                    }
+                }
+            } catch (GeneralException e) {
+                String errMsg = "Error doing entity query by condition: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+        }
+    }
+
+    /**
+     * Models the &lt;entity-condition&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class EntityCondition extends ModelTreeAction {
+        private final ByConditionFinder finder;
+        private final String listName;
+
+        public EntityCondition(ModelNode.ModelSubNode modelSubNode, Element entityConditionElement) {
+            super(modelSubNode, entityConditionElement);
+            Document ownerDoc = entityConditionElement.getOwnerDocument();
+            boolean useCache = "true".equalsIgnoreCase(entityConditionElement.getAttribute("use-cache"));
+            if (!useCache)
+                UtilXml.addChildElement(entityConditionElement, "use-iterator", ownerDoc);
+            String listName = UtilFormatOut.checkEmpty(entityConditionElement.getAttribute("list"),
+                    entityConditionElement.getAttribute("list-name"));
+            if (UtilValidate.isEmpty(listName))
+                listName = "_LIST_ITERATOR_";
+            this.listName = listName;
+            entityConditionElement.setAttribute("list-name", this.listName);
+            finder = new ByConditionFinder(entityConditionElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public ByConditionFinder getFinder() {
+            return finder;
+        }
+
+        public String getListName() {
+            return listName;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            try {
+                context.put(this.listName, null);
+                finder.runFind(context, WidgetWorker.getDelegator(context));
+                Object obj = context.get(this.listName);
+                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
+                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
+                    this.getModelSubNode().setListIterator(listIt, context);
+                } else {
+                    if (obj instanceof List<?>) {
+                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.cast(obj);
+                        this.getModelSubNode().setListIterator(list.listIterator(), context);
+                    }
+                }
+            } catch (GeneralException e) {
+                String errMsg = "Error doing entity query by condition: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+        }
+    }
+
+    /**
+     * Models the &lt;script&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class Script extends ModelTreeAction {
+        private final String location;
+        private final String method;
+
+        public Script(ModelNode modelNode, Element scriptElement) {
+            super(modelNode, scriptElement);
+            String scriptLocation = scriptElement.getAttribute("location");
+            this.location = WidgetWorker.getScriptLocation(scriptLocation);
+            this.method = WidgetWorker.getScriptMethodName(scriptLocation);
+        }
+
+        public Script(ModelNode.ModelSubNode modelSubNode, Element scriptElement) {
+            super(modelSubNode, scriptElement);
+            String scriptLocation = scriptElement.getAttribute("location");
+            this.location = WidgetWorker.getScriptLocation(scriptLocation);
+            this.method = WidgetWorker.getScriptMethodName(scriptLocation);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public String getLocation() {
+            return location;
+        }
+
+        public String getMethod() {
+            return method;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            context.put("_LIST_ITERATOR_", null);
+            if (location.endsWith(".xml")) {
+                Map<String, Object> localContext = new HashMap<String, Object>();
+                localContext.putAll(context);
+                DispatchContext ctx = WidgetWorker.getDispatcher(context).getDispatchContext();
+                MethodContext methodContext = new MethodContext(ctx, localContext, null);
+                try {
+                    SimpleMethod.runSimpleMethod(location, method, methodContext);
+                    context.putAll(methodContext.getResults());
+                } catch (MiniLangException e) {
+                    throw new RuntimeException("Error running simple method at location [" + location + "]", e);
+                }
+            } else {
+                ScriptUtil.executeScript(this.location, this.method, context);
+            }
+            Object obj = context.get("_LIST_ITERATOR_");
+            if (this.getModelSubNode() != null) {
+                if (obj != null && (obj instanceof EntityListIterator || obj instanceof ListIterator<?>)) {
+                    ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(obj);
+                    this.getModelSubNode().setListIterator(listIt, context);
+                } else {
+                    if (obj instanceof List<?>) {
+                        List<? extends Map<String, ? extends Object>> list = UtilGenerics.checkList(obj);
+                        this.getModelSubNode().setListIterator(list.listIterator(), context);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Models the &lt;service&gt; element.
+     * 
+     * @see <code>widget-tree.xsd</code>
+     */
+    public static class Service extends ModelTreeAction {
+        private final FlexibleStringExpander autoFieldMapExdr;
+        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
+        private final FlexibleStringExpander resultMapListNameExdr;
+        private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
+        private final FlexibleStringExpander resultMapValueNameExdr;
+        private final FlexibleStringExpander serviceNameExdr;
+        private final FlexibleStringExpander valueNameExdr;
+
+        public Service(ModelNode modelNode, Element serviceElement) {
+            super(modelNode, serviceElement);
+            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
+            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
+            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
+            this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
+            this.resultMapValueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-value"));
+            this.valueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("value"));
+            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
+        }
+
+        public Service(ModelNode.ModelSubNode modelSubNode, Element serviceElement) {
+            super(modelSubNode, serviceElement);
+            this.serviceNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("service-name"));
+            this.resultMapNameAcsr = FlexibleMapAccessor.getInstance(serviceElement.getAttribute("result-map"));
+            this.autoFieldMapExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("auto-field-map"));
+            this.resultMapListNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-list"));
+            this.resultMapValueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("result-map-value"));
+            this.valueNameExdr = FlexibleStringExpander.getInstance(serviceElement.getAttribute("value"));
+            this.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getAutoFieldMapExdr() {
+            return autoFieldMapExdr;
+        }
+
+        public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() {
+            return fieldMap;
+        }
+
+        public FlexibleStringExpander getResultMapListNameExdr() {
+            return resultMapListNameExdr;
+        }
+
+        public FlexibleMapAccessor<Map<String, Object>> getResultMapNameAcsr() {
+            return resultMapNameAcsr;
+        }
+
+        public FlexibleStringExpander getResultMapValueNameExdr() {
+            return resultMapValueNameExdr;
+        }
+
+        public FlexibleStringExpander getServiceNameExdr() {
+            return serviceNameExdr;
+        }
+
+        public FlexibleStringExpander getValueNameExdr() {
+            return valueNameExdr;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            String serviceNameExpanded = this.serviceNameExdr.expandString(context);
+            if (UtilValidate.isEmpty(serviceNameExpanded)) {
+                throw new IllegalArgumentException("Service name was empty, expanded from: " + this.serviceNameExdr.getOriginal());
+            }
+            String autoFieldMapString = this.autoFieldMapExdr.expandString(context);
+            boolean autoFieldMapBool = !"false".equals(autoFieldMapString);
+            try {
+                Map<String, Object> serviceContext = null;
+                if (autoFieldMapBool) {
+                    serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
+                            .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, context);
+                } else {
+                    serviceContext = new HashMap<String, Object>();
+                }
+                if (this.fieldMap != null) {
+                    EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, serviceContext);
+                }
+                Map<String, Object> result = WidgetWorker.getDispatcher(context).runSync(serviceNameExpanded, serviceContext);
+                if (!this.resultMapNameAcsr.isEmpty()) {
+                    this.resultMapNameAcsr.put(context, result);
+                    String queryString = (String) result.get("queryString");
+                    context.put("queryString", queryString);
+                    context.put("queryStringMap", result.get("queryStringMap"));
+                    if (UtilValidate.isNotEmpty(queryString)) {
+                        try {
+                            String queryStringEncoded = queryString.replaceAll("&", "%26");
+                            context.put("queryStringEncoded", queryStringEncoded);
+                        } catch (PatternSyntaxException e) {
+
+                        }
+                    }
+                } else {
+                    context.putAll(result);
+                }
+                String resultMapListName = resultMapListNameExdr.expandString(context);
+                //String resultMapListIteratorName = resultMapListIteratorNameExdr.expandString(context);
+                String resultMapValueName = resultMapValueNameExdr.expandString(context);
+                String valueName = valueNameExdr.expandString(context);
+                if (this.getModelSubNode() != null) {
+                    //ListIterator iter = null;
+                    if (UtilValidate.isNotEmpty(resultMapListName)) {
+                        List<? extends Map<String, ? extends Object>> lst = UtilGenerics.checkList(result.get(resultMapListName));
+                        if (lst != null) {
+                            if (lst instanceof ListIterator<?>) {
+                                ListIterator<? extends Map<String, ? extends Object>> listIt = UtilGenerics.cast(lst);
+                                this.getModelSubNode().setListIterator(listIt, context);
+                            } else {
+                                this.getModelSubNode().setListIterator(lst.listIterator(), context);
+                            }
+                        }
+                    }
+                } else {
+                    if (UtilValidate.isNotEmpty(resultMapValueName)) {
+                        if (UtilValidate.isNotEmpty(valueName)) {
+                            context.put(valueName, result.get(resultMapValueName));
+                        } else {
+                            Map<String, Object> resultMap = UtilGenerics.checkMap(result.get(resultMapValueName));
+                            context.putAll(resultMap);
+                        }
+                    }
+                }
+            } catch (GenericServiceException e) {
+                String errMsg = "Error calling service with name " + serviceNameExpanded + ": " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java b/framework/widget/src/org/ofbiz/widget/model/ModelTreeCondition.java
similarity index 92%
rename from framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelTreeCondition.java
index 6812871..a225bfc 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelTreeCondition.java
@@ -1,41 +1,39 @@
-/*******************************************************************************
- * 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.ofbiz.widget.tree;
-
-import org.ofbiz.widget.AbstractModelCondition;
-import org.ofbiz.widget.ModelCondition;
-import org.w3c.dom.Element;
-
-/**
- * Models the &lt;condition&gt; element.
- * 
- * @see <code>widget-tree.xsd</code>
- */
-public class ModelTreeCondition {
-    public static final String module = ModelTreeCondition.class.getName();
-    private final ModelCondition condition;
-
-    public ModelTreeCondition(ModelTree modelTree, Element conditionElement) {
-        this.condition = AbstractModelCondition.DEFAULT_CONDITION_FACTORY.newInstance(modelTree, conditionElement);
-    }
-
-    public ModelCondition getCondition() {
-        return condition;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import org.w3c.dom.Element;
+
+/**
+ * Models the &lt;condition&gt; element.
+ * 
+ * @see <code>widget-tree.xsd</code>
+ */
+public class ModelTreeCondition {
+    public static final String module = ModelTreeCondition.class.getName();
+    private final ModelCondition condition;
+
+    public ModelTreeCondition(ModelTree modelTree, Element conditionElement) {
+        this.condition = AbstractModelCondition.DEFAULT_CONDITION_FACTORY.newInstance(modelTree, conditionElement);
+    }
+
+    public ModelCondition getCondition() {
+        return condition;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/ModelWidget.java b/framework/widget/src/org/ofbiz/widget/model/ModelWidget.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/ModelWidget.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelWidget.java
index 9c9e4b4..8aec83e 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelWidget.java
@@ -1,155 +1,154 @@
-/*******************************************************************************
- * 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.ofbiz.widget;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.widget.xml.XmlWidgetVisitor;
-import org.w3c.dom.Element;
-
-/**
- * Widget Library - Widget model class. ModelWidget is a base class that is
- * extended by other widget model classes.
- */
-@SuppressWarnings("serial")
-public abstract class ModelWidget implements Serializable {
-
-    public static final String module = ModelWidget.class.getName();
-    /**
-     * The parameter name used to control widget boundary comments. Currently
-     * set to "widgetVerbose".
-     */
-    public static final String enableBoundaryCommentsParam = "widgetVerbose";
-
-    private final String name;
-    private final String systemId;
-    private final int startColumn;
-    private final int startLine;
-
-    /**
-     * Derived classes must call this constructor.
-     * @param name The widget name
-     */
-    protected ModelWidget(String name) {
-        this.name = name;
-        this.systemId = "anonymous";
-        this.startColumn = 0;
-        this.startLine = 0;
-    }
-
-    /**
-     * Derived classes must call this constructor.
-     * @param widgetElement The XML Element for the widget
-     */
-    protected ModelWidget(Element widgetElement) {
-        this.name = widgetElement.getAttribute("name");
-        this.systemId = (String) widgetElement.getUserData("systemId");
-        this.startColumn = ((Integer) widgetElement.getUserData("startColumn")).intValue();
-        this.startLine = ((Integer) widgetElement.getUserData("startLine")).intValue();
-    }
-
-    public abstract void accept(ModelWidgetVisitor visitor) throws Exception;
-
-    /**
-     * Returns the widget's name.
-     * @return Widget's name
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the url as a string, from where this widget was defined.
-     * @return url
-     */
-    public String getSystemId() {
-        return systemId;
-    }
-
-    /**
-     * Returns the column where this widget was defined, in it's containing xml file.
-     * @return start column
-     */
-    public int getStartColumn() {
-        return startColumn;
-    }
-
-    /**
-     * Returns the line where this widget was defined, in it's containing xml file.
-     * @return start line
-     */
-    public int getStartLine() {
-        return startLine;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        ModelWidgetVisitor visitor = new XmlWidgetVisitor(sb);
-        try {
-            accept(visitor);
-        } catch (Exception e) {
-            Debug.logWarning(e, "Exception thrown in XmlWidgetVisitor: ", module);
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Returns the widget's name to be used in boundary comments. The default action
-     * is to return the widget's name. Derived classes can override this method to
-     * return a customized name.
-     * @return Name to be used in boundary comments
-     */
-    public String getBoundaryCommentName() {
-        return name;
-    }
-
-    /**
-     * Returns <code>true</code> if widget boundary comments are enabled. Widget boundary comments are
-     * enabled by setting <code>widget.verbose=true</code> in the <code>widget.properties</code> file.
-     * The <code>true</code> setting can be overridden in <code>web.xml</code> or in the screen
-     * rendering context. If <code>widget.verbose</code> is set to <code>false</code> in the
-     * <code>widget.properties</code> file, then that setting will override all other settings and
-     * disable all widget boundary comments.
-     * 
-     * @param context Optional context Map
-     */
-    public static boolean widgetBoundaryCommentsEnabled(Map<String, ? extends Object> context) {
-        boolean result = "true".equals(UtilProperties.getPropertyValue("widget", "widget.verbose"));
-        if (result && context != null) {
-            String str = (String) context.get(enableBoundaryCommentsParam);
-            if (str != null) {
-                result = "true".equals(str);
-            } else{
-                Map<String, ? extends Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
-                if (parameters != null) {
-                    str = (String) parameters.get(enableBoundaryCommentsParam);
-                    if (str != null) {
-                        result = "true".equals(str);
-                    }
-                }
-            }
-        }
-        return result;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilProperties;
+import org.w3c.dom.Element;
+
+/**
+ * Widget Library - Widget model class. ModelWidget is a base class that is
+ * extended by other widget model classes.
+ */
+@SuppressWarnings("serial")
+public abstract class ModelWidget implements Serializable {
+
+    public static final String module = ModelWidget.class.getName();
+    /**
+     * The parameter name used to control widget boundary comments. Currently
+     * set to "widgetVerbose".
+     */
+    public static final String enableBoundaryCommentsParam = "widgetVerbose";
+
+    private final String name;
+    private final String systemId;
+    private final int startColumn;
+    private final int startLine;
+
+    /**
+     * Derived classes must call this constructor.
+     * @param name The widget name
+     */
+    protected ModelWidget(String name) {
+        this.name = name;
+        this.systemId = "anonymous";
+        this.startColumn = 0;
+        this.startLine = 0;
+    }
+
+    /**
+     * Derived classes must call this constructor.
+     * @param widgetElement The XML Element for the widget
+     */
+    protected ModelWidget(Element widgetElement) {
+        this.name = widgetElement.getAttribute("name");
+        this.systemId = (String) widgetElement.getUserData("systemId");
+        this.startColumn = ((Integer) widgetElement.getUserData("startColumn")).intValue();
+        this.startLine = ((Integer) widgetElement.getUserData("startLine")).intValue();
+    }
+
+    public abstract void accept(ModelWidgetVisitor visitor) throws Exception;
+
+    /**
+     * Returns the widget's name.
+     * @return Widget's name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the url as a string, from where this widget was defined.
+     * @return url
+     */
+    public String getSystemId() {
+        return systemId;
+    }
+
+    /**
+     * Returns the column where this widget was defined, in it's containing xml file.
+     * @return start column
+     */
+    public int getStartColumn() {
+        return startColumn;
+    }
+
+    /**
+     * Returns the line where this widget was defined, in it's containing xml file.
+     * @return start line
+     */
+    public int getStartLine() {
+        return startLine;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        ModelWidgetVisitor visitor = new XmlWidgetVisitor(sb);
+        try {
+            accept(visitor);
+        } catch (Exception e) {
+            Debug.logWarning(e, "Exception thrown in XmlWidgetVisitor: ", module);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Returns the widget's name to be used in boundary comments. The default action
+     * is to return the widget's name. Derived classes can override this method to
+     * return a customized name.
+     * @return Name to be used in boundary comments
+     */
+    public String getBoundaryCommentName() {
+        return name;
+    }
+
+    /**
+     * Returns <code>true</code> if widget boundary comments are enabled. Widget boundary comments are
+     * enabled by setting <code>widget.verbose=true</code> in the <code>widget.properties</code> file.
+     * The <code>true</code> setting can be overridden in <code>web.xml</code> or in the screen
+     * rendering context. If <code>widget.verbose</code> is set to <code>false</code> in the
+     * <code>widget.properties</code> file, then that setting will override all other settings and
+     * disable all widget boundary comments.
+     * 
+     * @param context Optional context Map
+     */
+    public static boolean widgetBoundaryCommentsEnabled(Map<String, ? extends Object> context) {
+        boolean result = "true".equals(UtilProperties.getPropertyValue("widget", "widget.verbose"));
+        if (result && context != null) {
+            String str = (String) context.get(enableBoundaryCommentsParam);
+            if (str != null) {
+                result = "true".equals(str);
+            } else{
+                Map<String, ? extends Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
+                if (parameters != null) {
+                    str = (String) parameters.get(enableBoundaryCommentsParam);
+                    if (str != null) {
+                        result = "true".equals(str);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java b/framework/widget/src/org/ofbiz/widget/model/ModelWidgetCondition.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelWidgetCondition.java
index 56feb69..99fce33 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelWidgetCondition.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
 import java.io.Serializable;
 import java.lang.reflect.Method;
diff --git a/framework/widget/src/org/ofbiz/widget/ModelWidgetVisitor.java b/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java
similarity index 89%
rename from framework/widget/src/org/ofbiz/widget/ModelWidgetVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java
index c2b13ca..50643fa 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelWidgetVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java
@@ -16,16 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget;
+package org.ofbiz.widget.model;
 
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.menu.ModelMenu;
-import org.ofbiz.widget.menu.ModelMenuItem;
-import org.ofbiz.widget.screen.HtmlWidget;
-import org.ofbiz.widget.screen.IterateSectionWidget;
-import org.ofbiz.widget.screen.ModelScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget;
-import org.ofbiz.widget.tree.ModelTree;
+import org.ofbiz.widget.model.HtmlWidget;
 
 /**
  *  A <code>ModelWidget</code> visitor.
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ScreenFactory.java b/framework/widget/src/org/ofbiz/widget/model/ScreenFactory.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/screen/ScreenFactory.java
rename to framework/widget/src/org/ofbiz/widget/model/ScreenFactory.java
index 1cdaaa1..d6021ef 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ScreenFactory.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ScreenFactory.java
@@ -1,212 +1,213 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.location.FlexibleLocation;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.cache.UtilCache;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-
-/**
- * Widget Library - Screen factory class
- */
-public class ScreenFactory {
-
-    public static final String module = ScreenFactory.class.getName();
-
-    public static final UtilCache<String, Map<String, ModelScreen>> screenLocationCache = UtilCache.createUtilCache("widget.screen.locationResource", 0, 0, false);
-    public static final UtilCache<String, Map<String, ModelScreen>> screenWebappCache = UtilCache.createUtilCache("widget.screen.webappResource", 0, 0, false);
-
-    public static boolean isCombinedName(String combinedName) {
-        int numSignIndex = combinedName.lastIndexOf("#");
-        if (numSignIndex == -1) {
-            return false;
-        }
-        if (numSignIndex + 1 >= combinedName.length()) {
-            return false;
-        }
-        return true;
-    }
-
-    public static String getResourceNameFromCombined(String combinedName) {
-        // split out the name on the last "#"
-        int numSignIndex = combinedName.lastIndexOf("#");
-        if (numSignIndex == -1) {
-            throw new IllegalArgumentException("Error in screen location/name: no \"#\" found to separate the location from the name; correct example: component://product/screen/product/ProductScreens.xml#EditProduct");
-        }
-        if (numSignIndex + 1 >= combinedName.length()) {
-            throw new IllegalArgumentException("Error in screen location/name: the \"#\" was at the end with no screen name after it; correct example: component://product/screen/product/ProductScreens.xml#EditProduct");
-        }
-        String resourceName = combinedName.substring(0, numSignIndex);
-        return resourceName;
-    }
-
-    public static String getScreenNameFromCombined(String combinedName) {
-        // split out the name on the last "#"
-        int numSignIndex = combinedName.lastIndexOf("#");
-        if (numSignIndex == -1) {
-            throw new IllegalArgumentException("Error in screen location/name: no \"#\" found to separate the location from the name; correct example: component://product/screen/product/ProductScreens.xml#EditProduct");
-        }
-        if (numSignIndex + 1 >= combinedName.length()) {
-            throw new IllegalArgumentException("Error in screen location/name: the \"#\" was at the end with no screen name after it; correct example: component://product/screen/product/ProductScreens.xml#EditProduct");
-        }
-        String screenName = combinedName.substring(numSignIndex + 1);
-        return screenName;
-    }
-
-    public static ModelScreen getScreenFromLocation(String combinedName)
-            throws IOException, SAXException, ParserConfigurationException {
-        String resourceName = getResourceNameFromCombined(combinedName);
-        String screenName = getScreenNameFromCombined(combinedName);
-        return getScreenFromLocation(resourceName, screenName);
-    }
-
-    public static ModelScreen getScreenFromLocation(String resourceName, String screenName)
-            throws IOException, SAXException, ParserConfigurationException {
-        Map<String, ModelScreen> modelScreenMap = getScreensFromLocation(resourceName);
-        ModelScreen modelScreen = modelScreenMap.get(screenName);
-        if (modelScreen == null) {
-            throw new IllegalArgumentException("Could not find screen with name [" + screenName + "] in class resource [" + resourceName + "]");
-        }
-        return modelScreen;
-    }
-
-    public static Map<String, ModelScreen> getScreensFromLocation(String resourceName)
-            throws IOException, SAXException, ParserConfigurationException {
-        Map<String, ModelScreen> modelScreenMap = screenLocationCache.get(resourceName);
-        if (modelScreenMap == null) {
-            synchronized (ScreenFactory.class) {
-                modelScreenMap = screenLocationCache.get(resourceName);
-                if (modelScreenMap == null) {
-                    long startTime = System.currentTimeMillis();
-                    URL screenFileUrl = null;
-                    screenFileUrl = FlexibleLocation.resolveLocation(resourceName);
-                    if (screenFileUrl == null) {
-                        throw new IllegalArgumentException("Could not resolve location to URL: " + resourceName);
-                    }
-                    Document screenFileDoc = UtilXml.readXmlDocument(screenFileUrl, true, true);
-                    modelScreenMap = readScreenDocument(screenFileDoc, resourceName);
-                    screenLocationCache.put(resourceName, modelScreenMap);
-                    double totalSeconds = (System.currentTimeMillis() - startTime)/1000.0;
-                    Debug.logInfo("Got " + modelScreenMap.size() + " screens in " + totalSeconds + "s from: " + screenFileUrl.toExternalForm(), module);
-                }
-            }
-        }
-
-        if (modelScreenMap.isEmpty()) {
-            throw new IllegalArgumentException("Could not find screen file with name [" + resourceName + "]");
-        }
-        return modelScreenMap;
-    }
-
-    public static ModelScreen getScreenFromWebappContext(String resourceName, String screenName, HttpServletRequest request)
-            throws IOException, SAXException, ParserConfigurationException {
-        String webappName = UtilHttp.getApplicationName(request);
-        String cacheKey = webappName + "::" + resourceName;
-
-
-        Map<String, ModelScreen> modelScreenMap = screenWebappCache.get(cacheKey);
-        if (modelScreenMap == null) {
-            synchronized (ScreenFactory.class) {
-                modelScreenMap = screenWebappCache.get(cacheKey);
-                if (modelScreenMap == null) {
-                    ServletContext servletContext = (ServletContext) request.getAttribute("servletContext");
-
-                    URL screenFileUrl = servletContext.getResource(resourceName);
-                    Document screenFileDoc = UtilXml.readXmlDocument(screenFileUrl, true, true);
-                    modelScreenMap = readScreenDocument(screenFileDoc, resourceName);
-                    screenWebappCache.put(cacheKey, modelScreenMap);
-                }
-            }
-        }
-
-        ModelScreen modelScreen = modelScreenMap.get(screenName);
-        if (modelScreen == null) {
-            throw new IllegalArgumentException("Could not find screen with name [" + screenName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]");
-        }
-        return modelScreen;
-    }
-
-    public static Map<String, ModelScreen> readScreenDocument(Document screenFileDoc, String sourceLocation) {
-        Map<String, ModelScreen> modelScreenMap = new HashMap<String, ModelScreen>();
-        if (screenFileDoc != null) {
-            // read document and construct ModelScreen for each screen element
-            Element rootElement = screenFileDoc.getDocumentElement();
-            List<? extends Element> screenElements = UtilXml.childElementList(rootElement, "screen");
-            for (Element screenElement: screenElements) {
-                ModelScreen modelScreen = new ModelScreen(screenElement, modelScreenMap, sourceLocation);
-                //Debug.logInfo("Read Screen with name: " + modelScreen.getName(), module);
-                modelScreenMap.put(modelScreen.getName(), modelScreen);
-            }
-        }
-        return modelScreenMap;
-    }
-
-    public static void renderReferencedScreen(String name, String location, ModelScreenWidget parentWidget, Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
-        // check to see if the name is a composite name separated by a #, if so split it up and get it by the full loc#name
-        if (ScreenFactory.isCombinedName(name)) {
-            String combinedName = name;
-            location = ScreenFactory.getResourceNameFromCombined(combinedName);
-            name = ScreenFactory.getScreenNameFromCombined(combinedName);
-        }
-
-        ModelScreen modelScreen = null;
-        if (UtilValidate.isNotEmpty(location)) {
-            try {
-                modelScreen = ScreenFactory.getScreenFromLocation(location, name);
-            } catch (IOException e) {
-                String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (SAXException e) {
-                String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (ParserConfigurationException e) {
-                String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        } else {
-            modelScreen = parentWidget.getModelScreen().getModelScreenMap().get(name);
-            if (modelScreen == null) {
-                throw new IllegalArgumentException("Could not find screen with name [" + name + "] in the same file as the screen with name [" + parentWidget.getModelScreen().getName() + "]");
-            }
-        }
-        //Debug.logInfo("parent(" + parentWidget + ") rendering(" + modelScreen + ")", module);
-        modelScreen.renderScreenString(writer, context, screenStringRenderer);
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.location.FlexibleLocation;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.cache.UtilCache;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Widget Library - Screen factory class
+ */
+public class ScreenFactory {
+
+    public static final String module = ScreenFactory.class.getName();
+
+    public static final UtilCache<String, Map<String, ModelScreen>> screenLocationCache = UtilCache.createUtilCache("widget.screen.locationResource", 0, 0, false);
+    public static final UtilCache<String, Map<String, ModelScreen>> screenWebappCache = UtilCache.createUtilCache("widget.screen.webappResource", 0, 0, false);
+
+    public static boolean isCombinedName(String combinedName) {
+        int numSignIndex = combinedName.lastIndexOf("#");
+        if (numSignIndex == -1) {
+            return false;
+        }
+        if (numSignIndex + 1 >= combinedName.length()) {
+            return false;
+        }
+        return true;
+    }
+
+    public static String getResourceNameFromCombined(String combinedName) {
+        // split out the name on the last "#"
+        int numSignIndex = combinedName.lastIndexOf("#");
+        if (numSignIndex == -1) {
+            throw new IllegalArgumentException("Error in screen location/name: no \"#\" found to separate the location from the name; correct example: component://product/screen/product/ProductScreens.xml#EditProduct");
+        }
+        if (numSignIndex + 1 >= combinedName.length()) {
+            throw new IllegalArgumentException("Error in screen location/name: the \"#\" was at the end with no screen name after it; correct example: component://product/screen/product/ProductScreens.xml#EditProduct");
+        }
+        String resourceName = combinedName.substring(0, numSignIndex);
+        return resourceName;
+    }
+
+    public static String getScreenNameFromCombined(String combinedName) {
+        // split out the name on the last "#"
+        int numSignIndex = combinedName.lastIndexOf("#");
+        if (numSignIndex == -1) {
+            throw new IllegalArgumentException("Error in screen location/name: no \"#\" found to separate the location from the name; correct example: component://product/screen/product/ProductScreens.xml#EditProduct");
+        }
+        if (numSignIndex + 1 >= combinedName.length()) {
+            throw new IllegalArgumentException("Error in screen location/name: the \"#\" was at the end with no screen name after it; correct example: component://product/screen/product/ProductScreens.xml#EditProduct");
+        }
+        String screenName = combinedName.substring(numSignIndex + 1);
+        return screenName;
+    }
+
+    public static ModelScreen getScreenFromLocation(String combinedName)
+            throws IOException, SAXException, ParserConfigurationException {
+        String resourceName = getResourceNameFromCombined(combinedName);
+        String screenName = getScreenNameFromCombined(combinedName);
+        return getScreenFromLocation(resourceName, screenName);
+    }
+
+    public static ModelScreen getScreenFromLocation(String resourceName, String screenName)
+            throws IOException, SAXException, ParserConfigurationException {
+        Map<String, ModelScreen> modelScreenMap = getScreensFromLocation(resourceName);
+        ModelScreen modelScreen = modelScreenMap.get(screenName);
+        if (modelScreen == null) {
+            throw new IllegalArgumentException("Could not find screen with name [" + screenName + "] in class resource [" + resourceName + "]");
+        }
+        return modelScreen;
+    }
+
+    public static Map<String, ModelScreen> getScreensFromLocation(String resourceName)
+            throws IOException, SAXException, ParserConfigurationException {
+        Map<String, ModelScreen> modelScreenMap = screenLocationCache.get(resourceName);
+        if (modelScreenMap == null) {
+            synchronized (ScreenFactory.class) {
+                modelScreenMap = screenLocationCache.get(resourceName);
+                if (modelScreenMap == null) {
+                    long startTime = System.currentTimeMillis();
+                    URL screenFileUrl = null;
+                    screenFileUrl = FlexibleLocation.resolveLocation(resourceName);
+                    if (screenFileUrl == null) {
+                        throw new IllegalArgumentException("Could not resolve location to URL: " + resourceName);
+                    }
+                    Document screenFileDoc = UtilXml.readXmlDocument(screenFileUrl, true, true);
+                    modelScreenMap = readScreenDocument(screenFileDoc, resourceName);
+                    screenLocationCache.put(resourceName, modelScreenMap);
+                    double totalSeconds = (System.currentTimeMillis() - startTime)/1000.0;
+                    Debug.logInfo("Got " + modelScreenMap.size() + " screens in " + totalSeconds + "s from: " + screenFileUrl.toExternalForm(), module);
+                }
+            }
+        }
+
+        if (modelScreenMap.isEmpty()) {
+            throw new IllegalArgumentException("Could not find screen file with name [" + resourceName + "]");
+        }
+        return modelScreenMap;
+    }
+
+    public static ModelScreen getScreenFromWebappContext(String resourceName, String screenName, HttpServletRequest request)
+            throws IOException, SAXException, ParserConfigurationException {
+        String webappName = UtilHttp.getApplicationName(request);
+        String cacheKey = webappName + "::" + resourceName;
+
+
+        Map<String, ModelScreen> modelScreenMap = screenWebappCache.get(cacheKey);
+        if (modelScreenMap == null) {
+            synchronized (ScreenFactory.class) {
+                modelScreenMap = screenWebappCache.get(cacheKey);
+                if (modelScreenMap == null) {
+                    ServletContext servletContext = (ServletContext) request.getAttribute("servletContext");
+
+                    URL screenFileUrl = servletContext.getResource(resourceName);
+                    Document screenFileDoc = UtilXml.readXmlDocument(screenFileUrl, true, true);
+                    modelScreenMap = readScreenDocument(screenFileDoc, resourceName);
+                    screenWebappCache.put(cacheKey, modelScreenMap);
+                }
+            }
+        }
+
+        ModelScreen modelScreen = modelScreenMap.get(screenName);
+        if (modelScreen == null) {
+            throw new IllegalArgumentException("Could not find screen with name [" + screenName + "] in webapp resource [" + resourceName + "] in the webapp [" + webappName + "]");
+        }
+        return modelScreen;
+    }
+
+    public static Map<String, ModelScreen> readScreenDocument(Document screenFileDoc, String sourceLocation) {
+        Map<String, ModelScreen> modelScreenMap = new HashMap<String, ModelScreen>();
+        if (screenFileDoc != null) {
+            // read document and construct ModelScreen for each screen element
+            Element rootElement = screenFileDoc.getDocumentElement();
+            List<? extends Element> screenElements = UtilXml.childElementList(rootElement, "screen");
+            for (Element screenElement: screenElements) {
+                ModelScreen modelScreen = new ModelScreen(screenElement, modelScreenMap, sourceLocation);
+                //Debug.logInfo("Read Screen with name: " + modelScreen.getName(), module);
+                modelScreenMap.put(modelScreen.getName(), modelScreen);
+            }
+        }
+        return modelScreenMap;
+    }
+
+    public static void renderReferencedScreen(String name, String location, ModelScreenWidget parentWidget, Appendable writer, Map<String, Object> context, ScreenStringRenderer screenStringRenderer) throws GeneralException, IOException {
+        // check to see if the name is a composite name separated by a #, if so split it up and get it by the full loc#name
+        if (ScreenFactory.isCombinedName(name)) {
+            String combinedName = name;
+            location = ScreenFactory.getResourceNameFromCombined(combinedName);
+            name = ScreenFactory.getScreenNameFromCombined(combinedName);
+        }
+
+        ModelScreen modelScreen = null;
+        if (UtilValidate.isNotEmpty(location)) {
+            try {
+                modelScreen = ScreenFactory.getScreenFromLocation(location, name);
+            } catch (IOException e) {
+                String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            } catch (SAXException e) {
+                String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            } catch (ParserConfigurationException e) {
+                String errMsg = "Error rendering included screen named [" + name + "] at location [" + location + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        } else {
+            modelScreen = parentWidget.getModelScreen().getModelScreenMap().get(name);
+            if (modelScreen == null) {
+                throw new IllegalArgumentException("Could not find screen with name [" + name + "] in the same file as the screen with name [" + parentWidget.getModelScreen().getName() + "]");
+            }
+        }
+        //Debug.logInfo("parent(" + parentWidget + ") rendering(" + modelScreen + ")", module);
+        modelScreen.renderScreenString(writer, context, screenStringRenderer);
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/tree/TreeFactory.java b/framework/widget/src/org/ofbiz/widget/model/TreeFactory.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/tree/TreeFactory.java
rename to framework/widget/src/org/ofbiz/widget/model/TreeFactory.java
index 9e64cae..7772e7f 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/TreeFactory.java
+++ b/framework/widget/src/org/ofbiz/widget/model/TreeFactory.java
@@ -1,87 +1,87 @@
-/*******************************************************************************
- * 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.ofbiz.widget.tree;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.location.FlexibleLocation;
-import org.ofbiz.base.util.UtilXml;
-import org.ofbiz.base.util.cache.UtilCache;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.service.LocalDispatcher;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-
-/**
- * Widget Library - Tree factory class
- */
-public class TreeFactory {
-
-    public static final String module = TreeFactory.class.getName();
-
-    public static final UtilCache<String, Map<String, ModelTree>> treeLocationCache = UtilCache.createUtilCache("widget.tree.locationResource", 0, 0, false);
-
-    public static ModelTree getTreeFromLocation(String resourceName, String treeName, Delegator delegator, LocalDispatcher dispatcher)
-            throws IOException, SAXException, ParserConfigurationException {
-        Map<String, ModelTree> modelTreeMap = treeLocationCache.get(resourceName);
-        if (modelTreeMap == null) {
-            synchronized (TreeFactory.class) {
-                modelTreeMap = treeLocationCache.get(resourceName);
-                if (modelTreeMap == null) {
-                    ClassLoader loader = Thread.currentThread().getContextClassLoader();
-                    if (loader == null) {
-                        loader = TreeFactory.class.getClassLoader();
-                    }
-
-                    URL treeFileUrl = null;
-                    treeFileUrl = FlexibleLocation.resolveLocation(resourceName); //, loader);
-                    Document treeFileDoc = UtilXml.readXmlDocument(treeFileUrl, true, true);
-                    modelTreeMap = readTreeDocument(treeFileDoc, delegator, dispatcher, resourceName);
-                    treeLocationCache.put(resourceName, modelTreeMap);
-                }
-            }
-        }
-
-        ModelTree modelTree = modelTreeMap.get(treeName);
-        if (modelTree == null) {
-            throw new IllegalArgumentException("Could not find tree with name [" + treeName + "] in class resource [" + resourceName + "]");
-        }
-        return modelTree;
-    }
-
-    public static Map<String, ModelTree> readTreeDocument(Document treeFileDoc, Delegator delegator, LocalDispatcher dispatcher, String treeLocation) {
-        Map<String, ModelTree> modelTreeMap = new HashMap<String, ModelTree>();
-        if (treeFileDoc != null) {
-            // read document and construct ModelTree for each tree element
-            Element rootElement = treeFileDoc.getDocumentElement();
-            for (Element treeElement: UtilXml.childElementList(rootElement, "tree")) {
-                ModelTree modelTree = new ModelTree(treeElement, treeLocation);
-                modelTreeMap.put(modelTree.getName(), modelTree);
-            }
-        }
-        return modelTreeMap;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.model;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.location.FlexibleLocation;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.cache.UtilCache;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.service.LocalDispatcher;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Widget Library - Tree factory class
+ */
+public class TreeFactory {
+
+    public static final String module = TreeFactory.class.getName();
+
+    public static final UtilCache<String, Map<String, ModelTree>> treeLocationCache = UtilCache.createUtilCache("widget.tree.locationResource", 0, 0, false);
+
+    public static ModelTree getTreeFromLocation(String resourceName, String treeName, Delegator delegator, LocalDispatcher dispatcher)
+            throws IOException, SAXException, ParserConfigurationException {
+        Map<String, ModelTree> modelTreeMap = treeLocationCache.get(resourceName);
+        if (modelTreeMap == null) {
+            synchronized (TreeFactory.class) {
+                modelTreeMap = treeLocationCache.get(resourceName);
+                if (modelTreeMap == null) {
+                    ClassLoader loader = Thread.currentThread().getContextClassLoader();
+                    if (loader == null) {
+                        loader = TreeFactory.class.getClassLoader();
+                    }
+
+                    URL treeFileUrl = null;
+                    treeFileUrl = FlexibleLocation.resolveLocation(resourceName); //, loader);
+                    Document treeFileDoc = UtilXml.readXmlDocument(treeFileUrl, true, true);
+                    modelTreeMap = readTreeDocument(treeFileDoc, delegator, dispatcher, resourceName);
+                    treeLocationCache.put(resourceName, modelTreeMap);
+                }
+            }
+        }
+
+        ModelTree modelTree = modelTreeMap.get(treeName);
+        if (modelTree == null) {
+            throw new IllegalArgumentException("Could not find tree with name [" + treeName + "] in class resource [" + resourceName + "]");
+        }
+        return modelTree;
+    }
+
+    public static Map<String, ModelTree> readTreeDocument(Document treeFileDoc, Delegator delegator, LocalDispatcher dispatcher, String treeLocation) {
+        Map<String, ModelTree> modelTreeMap = new HashMap<String, ModelTree>();
+        if (treeFileDoc != null) {
+            // read document and construct ModelTree for each tree element
+            Element rootElement = treeFileDoc.getDocumentElement();
+            for (Element treeElement: UtilXml.childElementList(rootElement, "tree")) {
+                ModelTree modelTree = new ModelTree(treeElement, treeLocation);
+                modelTreeMap.put(modelTree.getName(), modelTree);
+            }
+        }
+        return modelTreeMap;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/xml/AbstractWidgetVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java
similarity index 93%
rename from framework/widget/src/org/ofbiz/widget/xml/AbstractWidgetVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java
index 66d92ad..86d6e5d 100644
--- a/framework/widget/src/org/ofbiz/widget/xml/AbstractWidgetVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java
@@ -16,29 +16,28 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.xml;
+package org.ofbiz.widget.model;
 
 import java.util.Collection;
 
 import org.ofbiz.base.util.Assert;
 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
 import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.CommonWidgetModels.AutoEntityParameters;
-import org.ofbiz.widget.CommonWidgetModels.AutoServiceParameters;
-import org.ofbiz.widget.CommonWidgetModels.Image;
-import org.ofbiz.widget.CommonWidgetModels.Link;
-import org.ofbiz.widget.CommonWidgetModels.Parameter;
+import org.ofbiz.widget.model.CommonWidgetModels.AutoEntityParameters;
+import org.ofbiz.widget.model.CommonWidgetModels.AutoServiceParameters;
+import org.ofbiz.widget.model.CommonWidgetModels.Image;
+import org.ofbiz.widget.model.CommonWidgetModels.Link;
+import org.ofbiz.widget.model.CommonWidgetModels.Parameter;
 
 /**
  * Abstract XML widget visitor.
  *
  */
-public abstract class AbstractWidgetVisitor {
+public abstract class XmlAbstractWidgetVisitor {
 
     protected final Appendable writer;
 
-    public AbstractWidgetVisitor(Appendable writer) {
+    public XmlAbstractWidgetVisitor(Appendable writer) {
         Assert.notNull("writer", writer);
         this.writer = writer;
     }
diff --git a/framework/widget/src/org/ofbiz/widget/xml/XmlWidgetActionVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java
similarity index 83%
rename from framework/widget/src/org/ofbiz/widget/xml/XmlWidgetActionVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java
index bfc76d3..540127e 100644
--- a/framework/widget/src/org/ofbiz/widget/xml/XmlWidgetActionVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java
@@ -16,20 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.xml;
+package org.ofbiz.widget.model;
 
-import org.ofbiz.widget.AbstractModelAction.EntityAnd;
-import org.ofbiz.widget.AbstractModelAction.EntityCondition;
-import org.ofbiz.widget.AbstractModelAction.EntityOne;
-import org.ofbiz.widget.AbstractModelAction.GetRelated;
-import org.ofbiz.widget.AbstractModelAction.GetRelatedOne;
-import org.ofbiz.widget.AbstractModelAction.PropertyMap;
-import org.ofbiz.widget.AbstractModelAction.PropertyToField;
-import org.ofbiz.widget.AbstractModelAction.Script;
-import org.ofbiz.widget.AbstractModelAction.Service;
-import org.ofbiz.widget.AbstractModelAction.SetField;
-import org.ofbiz.widget.ModelActionVisitor;
-import org.ofbiz.widget.form.ModelFormAction.CallParentActions;
+import org.ofbiz.widget.model.AbstractModelAction.EntityAnd;
+import org.ofbiz.widget.model.AbstractModelAction.EntityCondition;
+import org.ofbiz.widget.model.AbstractModelAction.EntityOne;
+import org.ofbiz.widget.model.AbstractModelAction.GetRelated;
+import org.ofbiz.widget.model.AbstractModelAction.GetRelatedOne;
+import org.ofbiz.widget.model.AbstractModelAction.PropertyMap;
+import org.ofbiz.widget.model.AbstractModelAction.PropertyToField;
+import org.ofbiz.widget.model.AbstractModelAction.Script;
+import org.ofbiz.widget.model.AbstractModelAction.Service;
+import org.ofbiz.widget.model.AbstractModelAction.SetField;
+import org.ofbiz.widget.model.ModelFormAction.CallParentActions;
 
 /**
  * An object that generates XML from widget models.
@@ -37,7 +36,7 @@
  * "pretty print" the XML, then use a transformer.
  *
  */
-public class XmlWidgetActionVisitor extends AbstractWidgetVisitor implements ModelActionVisitor {
+public class XmlWidgetActionVisitor extends XmlAbstractWidgetVisitor implements ModelActionVisitor {
 
     public static final String module = XmlWidgetActionVisitor.class.getName();
 
@@ -57,7 +56,7 @@
     }
 
     @Override
-    public void visit(org.ofbiz.widget.tree.ModelTreeAction.EntityAnd entityAnd) throws Exception {
+    public void visit(org.ofbiz.widget.model.ModelTreeAction.EntityAnd entityAnd) throws Exception {
         writer.append("<entity-and/>");
         // TODO: Create ByAndFinder visitor
     }
@@ -69,7 +68,7 @@
     }
 
     @Override
-    public void visit(org.ofbiz.widget.tree.ModelTreeAction.EntityCondition entityCondition) throws Exception {
+    public void visit(org.ofbiz.widget.model.ModelTreeAction.EntityCondition entityCondition) throws Exception {
         writer.append("<entity-condition/>");
         // TODO: Create ByConditionFinder visitor
     }
@@ -133,7 +132,7 @@
     }
 
     @Override
-    public void visit(org.ofbiz.widget.tree.ModelTreeAction.Script script) throws Exception {
+    public void visit(org.ofbiz.widget.model.ModelTreeAction.Script script) throws Exception {
         writer.append("<script");
         visitAttribute("location", script.getLocation());
         visitAttribute("method", script.getMethod());
@@ -153,7 +152,7 @@
     }
 
     @Override
-    public void visit(org.ofbiz.widget.form.ModelFormAction.Service service) throws Exception {
+    public void visit(org.ofbiz.widget.model.ModelFormAction.Service service) throws Exception {
         writer.append("<service");
         visitAttribute("service-name", service.getServiceNameExdr());
         visitAttribute("result-map", service.getResultMapNameAcsr());
@@ -167,7 +166,7 @@
     }
 
     @Override
-    public void visit(org.ofbiz.widget.tree.ModelTreeAction.Service service) throws Exception {
+    public void visit(org.ofbiz.widget.model.ModelTreeAction.Service service) throws Exception {
         writer.append("<service");
         visitAttribute("service-name", service.getServiceNameExdr());
         visitAttribute("result-map", service.getResultMapNameAcsr());
@@ -196,7 +195,7 @@
     }
 
     @Override
-    public void visit(org.ofbiz.widget.menu.ModelMenuAction.SetField setField) throws Exception {
+    public void visit(org.ofbiz.widget.model.ModelMenuAction.SetField setField) throws Exception {
         writer.append("<set");
         visitAttribute("field", setField.getField());
         visitAttribute("from-field", setField.getFromField());
diff --git a/framework/widget/src/org/ofbiz/widget/xml/XmlWidgetConditionVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java
similarity index 84%
rename from framework/widget/src/org/ofbiz/widget/xml/XmlWidgetConditionVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java
index 5b13a26..9bd4b89 100644
--- a/framework/widget/src/org/ofbiz/widget/xml/XmlWidgetConditionVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java
@@ -16,27 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.xml;
+package org.ofbiz.widget.model;
 
 import java.util.Collection;
 
-import org.ofbiz.widget.AbstractModelCondition.And;
-import org.ofbiz.widget.AbstractModelCondition.IfCompare;
-import org.ofbiz.widget.AbstractModelCondition.IfCompareField;
-import org.ofbiz.widget.AbstractModelCondition.IfEmpty;
-import org.ofbiz.widget.AbstractModelCondition.IfEntityPermission;
-import org.ofbiz.widget.AbstractModelCondition.IfHasPermission;
-import org.ofbiz.widget.AbstractModelCondition.IfRegexp;
-import org.ofbiz.widget.AbstractModelCondition.IfServicePermission;
-import org.ofbiz.widget.AbstractModelCondition.IfValidateMethod;
-import org.ofbiz.widget.AbstractModelCondition.Not;
-import org.ofbiz.widget.AbstractModelCondition.Or;
-import org.ofbiz.widget.AbstractModelCondition.Xor;
-import org.ofbiz.widget.ModelCondition;
-import org.ofbiz.widget.ModelConditionVisitor;
-import org.ofbiz.widget.menu.ModelMenuCondition;
-import org.ofbiz.widget.screen.ModelScreenCondition.IfEmptySection;
-import org.ofbiz.widget.tree.ModelTreeCondition;
+import org.ofbiz.widget.model.AbstractModelCondition.And;
+import org.ofbiz.widget.model.AbstractModelCondition.IfCompare;
+import org.ofbiz.widget.model.AbstractModelCondition.IfCompareField;
+import org.ofbiz.widget.model.AbstractModelCondition.IfEmpty;
+import org.ofbiz.widget.model.AbstractModelCondition.IfEntityPermission;
+import org.ofbiz.widget.model.AbstractModelCondition.IfHasPermission;
+import org.ofbiz.widget.model.AbstractModelCondition.IfRegexp;
+import org.ofbiz.widget.model.AbstractModelCondition.IfServicePermission;
+import org.ofbiz.widget.model.AbstractModelCondition.IfValidateMethod;
+import org.ofbiz.widget.model.AbstractModelCondition.Not;
+import org.ofbiz.widget.model.AbstractModelCondition.Or;
+import org.ofbiz.widget.model.AbstractModelCondition.Xor;
+import org.ofbiz.widget.model.ModelScreenCondition.IfEmptySection;
 
 /**
  * An object that generates XML from widget models.
@@ -44,7 +40,7 @@
  * "pretty print" the XML, then use a transformer.
  *
  */
-public class XmlWidgetConditionVisitor extends AbstractWidgetVisitor implements ModelConditionVisitor {
+public class XmlWidgetConditionVisitor extends XmlAbstractWidgetVisitor implements ModelConditionVisitor {
 
     public XmlWidgetConditionVisitor(Appendable writer) {
         super(writer);
diff --git a/framework/widget/src/org/ofbiz/widget/xml/XmlWidgetFieldVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
similarity index 92%
rename from framework/widget/src/org/ofbiz/widget/xml/XmlWidgetFieldVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
index a07d92d..c56368c 100644
--- a/framework/widget/src/org/ofbiz/widget/xml/XmlWidgetFieldVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
@@ -16,14 +16,36 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.xml;
+package org.ofbiz.widget.model;
 
 import java.util.Collection;
 
-import org.ofbiz.widget.ModelFieldVisitor;
-import org.ofbiz.widget.CommonWidgetModels.Link;
-import org.ofbiz.widget.form.ModelFormField.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.model.CommonWidgetModels.Link;
+import org.ofbiz.widget.model.ModelFormField.AutoComplete;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayEntityField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.InPlaceEditor;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubHyperlink;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
 
 /**
  * An object that generates XML from widget models.
@@ -31,7 +53,7 @@
  * "pretty print" the XML, then use a transformer.
  *
  */
-public class XmlWidgetFieldVisitor extends AbstractWidgetVisitor implements ModelFieldVisitor {
+public class XmlWidgetFieldVisitor extends XmlAbstractWidgetVisitor implements ModelFieldVisitor {
 
     public XmlWidgetFieldVisitor(Appendable writer) {
         super(writer);
diff --git a/framework/widget/src/org/ofbiz/widget/xml/XmlWidgetVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java
similarity index 92%
rename from framework/widget/src/org/ofbiz/widget/xml/XmlWidgetVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java
index b55d0dd..129eb26 100644
--- a/framework/widget/src/org/ofbiz/widget/xml/XmlWidgetVisitor.java
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java
@@ -16,50 +16,35 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.xml;
+package org.ofbiz.widget.model;
 
 import java.util.Collection;
 import java.util.Map;
 
-import org.ofbiz.widget.ModelAction;
-import org.ofbiz.widget.ModelActionVisitor;
-import org.ofbiz.widget.ModelConditionVisitor;
-import org.ofbiz.widget.ModelFieldVisitor;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.ModelFormField;
-import org.ofbiz.widget.menu.ModelMenu;
-import org.ofbiz.widget.menu.ModelMenuItem;
-import org.ofbiz.widget.screen.HtmlWidget;
-import org.ofbiz.widget.screen.HtmlWidget.HtmlTemplate;
-import org.ofbiz.widget.screen.HtmlWidget.HtmlTemplateDecorator;
-import org.ofbiz.widget.screen.HtmlWidget.HtmlTemplateDecoratorSection;
-import org.ofbiz.widget.screen.IterateSectionWidget;
-import org.ofbiz.widget.screen.ModelScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget;
-import org.ofbiz.widget.screen.ModelScreenWidget.Column;
-import org.ofbiz.widget.screen.ModelScreenWidget.ColumnContainer;
-import org.ofbiz.widget.screen.ModelScreenWidget.Container;
-import org.ofbiz.widget.screen.ModelScreenWidget.Content;
-import org.ofbiz.widget.screen.ModelScreenWidget.DecoratorScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget.DecoratorSection;
-import org.ofbiz.widget.screen.ModelScreenWidget.DecoratorSectionInclude;
-import org.ofbiz.widget.screen.ModelScreenWidget.Form;
-import org.ofbiz.widget.screen.ModelScreenWidget.HorizontalSeparator;
-import org.ofbiz.widget.screen.ModelScreenWidget.IncludeScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget.Label;
-import org.ofbiz.widget.screen.ModelScreenWidget.Menu;
-import org.ofbiz.widget.screen.ModelScreenWidget.PlatformSpecific;
-import org.ofbiz.widget.screen.ModelScreenWidget.PortalPage;
-import org.ofbiz.widget.screen.ModelScreenWidget.ScreenImage;
-import org.ofbiz.widget.screen.ModelScreenWidget.ScreenLink;
-import org.ofbiz.widget.screen.ModelScreenWidget.Screenlet;
-import org.ofbiz.widget.screen.ModelScreenWidget.Section;
-import org.ofbiz.widget.screen.ModelScreenWidget.Tree;
-import org.ofbiz.widget.tree.ModelTree;
-import org.ofbiz.widget.tree.ModelTree.ModelNode;
-import org.ofbiz.widget.tree.ModelTree.ModelNode.ModelSubNode;
+import org.ofbiz.widget.model.HtmlWidget.HtmlTemplate;
+import org.ofbiz.widget.model.HtmlWidget.HtmlTemplateDecorator;
+import org.ofbiz.widget.model.HtmlWidget.HtmlTemplateDecoratorSection;
+import org.ofbiz.widget.model.ModelScreenWidget.Column;
+import org.ofbiz.widget.model.ModelScreenWidget.ColumnContainer;
+import org.ofbiz.widget.model.ModelScreenWidget.Container;
+import org.ofbiz.widget.model.ModelScreenWidget.Content;
+import org.ofbiz.widget.model.ModelScreenWidget.DecoratorScreen;
+import org.ofbiz.widget.model.ModelScreenWidget.DecoratorSection;
+import org.ofbiz.widget.model.ModelScreenWidget.DecoratorSectionInclude;
+import org.ofbiz.widget.model.ModelScreenWidget.Form;
+import org.ofbiz.widget.model.ModelScreenWidget.HorizontalSeparator;
+import org.ofbiz.widget.model.ModelScreenWidget.IncludeScreen;
+import org.ofbiz.widget.model.ModelScreenWidget.Label;
+import org.ofbiz.widget.model.ModelScreenWidget.Menu;
+import org.ofbiz.widget.model.ModelScreenWidget.PlatformSpecific;
+import org.ofbiz.widget.model.ModelScreenWidget.PortalPage;
+import org.ofbiz.widget.model.ModelScreenWidget.ScreenImage;
+import org.ofbiz.widget.model.ModelScreenWidget.ScreenLink;
+import org.ofbiz.widget.model.ModelScreenWidget.Screenlet;
+import org.ofbiz.widget.model.ModelScreenWidget.Section;
+import org.ofbiz.widget.model.ModelScreenWidget.Tree;
+import org.ofbiz.widget.model.ModelTree.ModelNode;
+import org.ofbiz.widget.model.ModelTree.ModelNode.ModelSubNode;
 
 /**
  * An object that generates an XML representation from widget models.
@@ -67,7 +52,7 @@
  * "pretty print" the XML, then use a transformer.
  *
  */
-public class XmlWidgetVisitor extends AbstractWidgetVisitor implements ModelWidgetVisitor {
+public class XmlWidgetVisitor extends XmlAbstractWidgetVisitor implements ModelWidgetVisitor {
 
     private final ModelFieldVisitor fieldVisitor;
     private final ModelActionVisitor actionVisitor;
@@ -399,7 +384,6 @@
         }
         for (ModelMenuItem menuItem : modelMenu.getMenuItemList()) {
             menuItem.accept(this);
-            ;
         }
         writer.append("</menu>");
     }
diff --git a/framework/widget/src/org/ofbiz/widget/PortalPageWorker.java b/framework/widget/src/org/ofbiz/widget/portal/PortalPageWorker.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/PortalPageWorker.java
rename to framework/widget/src/org/ofbiz/widget/portal/PortalPageWorker.java
index 5061208..7225b06 100644
--- a/framework/widget/src/org/ofbiz/widget/PortalPageWorker.java
+++ b/framework/widget/src/org/ofbiz/widget/portal/PortalPageWorker.java
@@ -1,176 +1,177 @@
-/*******************************************************************************
- * 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.ofbiz.widget;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.condition.EntityCondition;
-import org.ofbiz.entity.condition.EntityOperator;
-import org.ofbiz.entity.util.EntityQuery;
-import org.ofbiz.entity.util.EntityUtil;
-import org.ofbiz.security.Security;
-
-/**
- * PortalPageWorker Class
- */
-public class PortalPageWorker {
-
-    public static final String module = PortalPageWorker.class.getName();
-
-    public PortalPageWorker() { }
-
-    public String renderPortalPageAsTextExt(Delegator delegator, String portalPageId, Map<String, Object> templateContext,
-            boolean cache) throws GeneralException, IOException {
-        return "success";
-    }
-
-    /**
-    * Returns a list of PortalPages that have the specified parentPortalPageId as parent.
-    * If a specific PortalPage exists for the current userLogin it is returned instead of the original one.
-    */
-    public static List<GenericValue> getPortalPages(String parentPortalPageId, Map<String, Object> context) {
-        List<GenericValue> portalPages = null;
-        if (UtilValidate.isNotEmpty(parentPortalPageId)) {
-            Delegator delegator = WidgetWorker.getDelegator(context);
-            try {
-                // first get public pages
-                EntityCondition cond =
-                    EntityCondition.makeCondition(UtilMisc.toList(
-                        EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, "_NA_"),
-                        EntityCondition.makeCondition(UtilMisc.toList(
-                                EntityCondition.makeCondition("portalPageId", EntityOperator.EQUALS, parentPortalPageId),
-                                EntityCondition.makeCondition("parentPortalPageId", EntityOperator.EQUALS, parentPortalPageId)),
-                                EntityOperator.OR)),
-                        EntityOperator.AND);
-                portalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
-                List<GenericValue> userPortalPages = new ArrayList<GenericValue>();
-                if (UtilValidate.isNotEmpty(context.get("userLogin"))) { // check if a user is logged in
-                    String userLoginId = ((GenericValue)context.get("userLogin")).getString("userLoginId");
-                    // replace with private pages
-                    for (GenericValue portalPage : portalPages) {
-                        List<GenericValue> privatePortalPages = EntityQuery.use(delegator)
-                                                                           .from("PortalPage")
-                                                                           .where("ownerUserLoginId", userLoginId, "originalPortalPageId", portalPage.getString("portalPageId"))
-                                                                           .queryList();
-                        if (UtilValidate.isNotEmpty(privatePortalPages)) {
-                            userPortalPages.add(privatePortalPages.get(0));
-                        } else {
-                            userPortalPages.add(portalPage);
-                        }
-                    }
-                    // add any other created private pages
-                    userPortalPages.addAll(EntityQuery.use(delegator)
-                                                      .from("PortalPage")
-                                                      .where("ownerUserLoginId", userLoginId, "originalPortalPageId", null, "parentPortalPageId", parentPortalPageId)
-                                                      .queryList());
-                }
-                portalPages = EntityUtil.orderBy(userPortalPages, UtilMisc.toList("sequenceNum"));
-            } catch (GenericEntityException e) {
-                Debug.logError("Could not retrieve portalpages:" + e.getMessage(), module);
-            }
-        }
-        return portalPages;
-    }
-
-    /**
-    * Returns the PortalPage with the specified portalPageId.
-    * If a specific PortalPage exists for the current userLogin it is returned instead of the original one.
-    */
-    public static GenericValue getPortalPage(String portalPageId, Map<String, Object> context) {
-        GenericValue portalPage = null;
-        if (UtilValidate.isNotEmpty(portalPageId)) {
-            Delegator delegator = WidgetWorker.getDelegator(context);
-            try {
-                // Get the current userLoginId
-                String userLoginId = "_NA_";
-                if (UtilValidate.isNotEmpty(context.get("userLogin"))) { // check if a user is logged in
-                    userLoginId = ((GenericValue)context.get("userLogin")).getString("userLoginId");
-                }
-                
-                // Get the PortalPage ensuring that it is either owned by the user or a system page
-                EntityCondition cond = EntityCondition.makeCondition(UtilMisc.toList(
-                    EntityCondition.makeCondition("portalPageId", EntityOperator.EQUALS, portalPageId),
-                    EntityCondition.makeCondition(UtilMisc.toList(
-                        EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, "_NA_"),
-                        EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, userLoginId)),
-                        EntityOperator.OR)),
-                    EntityOperator.AND);
-                List <GenericValue> portalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
-                if (UtilValidate.isNotEmpty(portalPages)) {
-                    portalPage = EntityUtil.getFirst(portalPages);
-                }
-                
-                // If a derived PortalPage private to the user exists, returns this instead of the system one
-                cond = EntityCondition.makeCondition(UtilMisc.toList(
-                        EntityCondition.makeCondition("originalPortalPageId", EntityOperator.EQUALS, portalPageId),
-                        EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, userLoginId)),
-                        EntityOperator.AND);
-                List <GenericValue> privateDerivedPortalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
-                if (UtilValidate.isNotEmpty(privateDerivedPortalPages)) {
-                    portalPage = EntityUtil.getFirst(privateDerivedPortalPages);
-                }
-            } catch (GenericEntityException e) {
-                Debug.logError("Could not retrieve portalpage:" + e.getMessage(), module);
-            }
-        }
-        return portalPage;
-    }
-
-    /**
-    * Checks if the user is allowed to configure the PortalPage.
-    * PortalPage configuration is allowed if he is the PortalPage owner or he has got the PORTALPAGE_ADMIN permission
-    */   
-    public static Boolean userIsAllowedToConfigure(String portalPageId, Map<String, Object> context) {
-        Boolean userIsAllowed = false;
-
-        if (UtilValidate.isNotEmpty(portalPageId)) {
-            GenericValue userLogin = (GenericValue) context.get("userLogin");
-            if (UtilValidate.isNotEmpty(userLogin)) {
-                String userLoginId = (String) userLogin.get("userLoginId");
-                Security security = (Security) context.get("security");
-
-                Boolean hasPortalAdminPermission = security.hasPermission("PORTALPAGE_ADMIN", userLogin);
-                try {
-                    Delegator delegator = WidgetWorker.getDelegator(context);
-                    GenericValue portalPage = EntityQuery.use(delegator).from("PortalPage").where("portalPageId", portalPageId).queryOne();
-                    if (UtilValidate.isNotEmpty(portalPage)) {
-                        String ownerUserLoginId = (String) portalPage.get("ownerUserLoginId");
-                        // Users with PORTALPAGE_ADMIN permission can configure every Portal Page
-                        userIsAllowed = (ownerUserLoginId.equals(userLoginId) || hasPortalAdminPermission);
-                    }
-                } catch (GenericEntityException e) {
-                    return false;
-                }
-            }
-        }
-
-        return userIsAllowed;       
-    }
-    
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.portal;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.condition.EntityOperator;
+import org.ofbiz.entity.util.EntityQuery;
+import org.ofbiz.entity.util.EntityUtil;
+import org.ofbiz.security.Security;
+import org.ofbiz.widget.WidgetWorker;
+
+/**
+ * PortalPageWorker Class
+ */
+public class PortalPageWorker {
+
+    public static final String module = PortalPageWorker.class.getName();
+
+    public PortalPageWorker() { }
+
+    public String renderPortalPageAsTextExt(Delegator delegator, String portalPageId, Map<String, Object> templateContext,
+            boolean cache) throws GeneralException, IOException {
+        return "success";
+    }
+
+    /**
+    * Returns a list of PortalPages that have the specified parentPortalPageId as parent.
+    * If a specific PortalPage exists for the current userLogin it is returned instead of the original one.
+    */
+    public static List<GenericValue> getPortalPages(String parentPortalPageId, Map<String, Object> context) {
+        List<GenericValue> portalPages = null;
+        if (UtilValidate.isNotEmpty(parentPortalPageId)) {
+            Delegator delegator = WidgetWorker.getDelegator(context);
+            try {
+                // first get public pages
+                EntityCondition cond =
+                    EntityCondition.makeCondition(UtilMisc.toList(
+                        EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, "_NA_"),
+                        EntityCondition.makeCondition(UtilMisc.toList(
+                                EntityCondition.makeCondition("portalPageId", EntityOperator.EQUALS, parentPortalPageId),
+                                EntityCondition.makeCondition("parentPortalPageId", EntityOperator.EQUALS, parentPortalPageId)),
+                                EntityOperator.OR)),
+                        EntityOperator.AND);
+                portalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
+                List<GenericValue> userPortalPages = new ArrayList<GenericValue>();
+                if (UtilValidate.isNotEmpty(context.get("userLogin"))) { // check if a user is logged in
+                    String userLoginId = ((GenericValue)context.get("userLogin")).getString("userLoginId");
+                    // replace with private pages
+                    for (GenericValue portalPage : portalPages) {
+                        List<GenericValue> privatePortalPages = EntityQuery.use(delegator)
+                                                                           .from("PortalPage")
+                                                                           .where("ownerUserLoginId", userLoginId, "originalPortalPageId", portalPage.getString("portalPageId"))
+                                                                           .queryList();
+                        if (UtilValidate.isNotEmpty(privatePortalPages)) {
+                            userPortalPages.add(privatePortalPages.get(0));
+                        } else {
+                            userPortalPages.add(portalPage);
+                        }
+                    }
+                    // add any other created private pages
+                    userPortalPages.addAll(EntityQuery.use(delegator)
+                                                      .from("PortalPage")
+                                                      .where("ownerUserLoginId", userLoginId, "originalPortalPageId", null, "parentPortalPageId", parentPortalPageId)
+                                                      .queryList());
+                }
+                portalPages = EntityUtil.orderBy(userPortalPages, UtilMisc.toList("sequenceNum"));
+            } catch (GenericEntityException e) {
+                Debug.logError("Could not retrieve portalpages:" + e.getMessage(), module);
+            }
+        }
+        return portalPages;
+    }
+
+    /**
+    * Returns the PortalPage with the specified portalPageId.
+    * If a specific PortalPage exists for the current userLogin it is returned instead of the original one.
+    */
+    public static GenericValue getPortalPage(String portalPageId, Map<String, Object> context) {
+        GenericValue portalPage = null;
+        if (UtilValidate.isNotEmpty(portalPageId)) {
+            Delegator delegator = WidgetWorker.getDelegator(context);
+            try {
+                // Get the current userLoginId
+                String userLoginId = "_NA_";
+                if (UtilValidate.isNotEmpty(context.get("userLogin"))) { // check if a user is logged in
+                    userLoginId = ((GenericValue)context.get("userLogin")).getString("userLoginId");
+                }
+                
+                // Get the PortalPage ensuring that it is either owned by the user or a system page
+                EntityCondition cond = EntityCondition.makeCondition(UtilMisc.toList(
+                    EntityCondition.makeCondition("portalPageId", EntityOperator.EQUALS, portalPageId),
+                    EntityCondition.makeCondition(UtilMisc.toList(
+                        EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, "_NA_"),
+                        EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, userLoginId)),
+                        EntityOperator.OR)),
+                    EntityOperator.AND);
+                List <GenericValue> portalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
+                if (UtilValidate.isNotEmpty(portalPages)) {
+                    portalPage = EntityUtil.getFirst(portalPages);
+                }
+                
+                // If a derived PortalPage private to the user exists, returns this instead of the system one
+                cond = EntityCondition.makeCondition(UtilMisc.toList(
+                        EntityCondition.makeCondition("originalPortalPageId", EntityOperator.EQUALS, portalPageId),
+                        EntityCondition.makeCondition("ownerUserLoginId", EntityOperator.EQUALS, userLoginId)),
+                        EntityOperator.AND);
+                List <GenericValue> privateDerivedPortalPages = EntityQuery.use(delegator).from("PortalPage").where(cond).queryList();
+                if (UtilValidate.isNotEmpty(privateDerivedPortalPages)) {
+                    portalPage = EntityUtil.getFirst(privateDerivedPortalPages);
+                }
+            } catch (GenericEntityException e) {
+                Debug.logError("Could not retrieve portalpage:" + e.getMessage(), module);
+            }
+        }
+        return portalPage;
+    }
+
+    /**
+    * Checks if the user is allowed to configure the PortalPage.
+    * PortalPage configuration is allowed if he is the PortalPage owner or he has got the PORTALPAGE_ADMIN permission
+    */   
+    public static Boolean userIsAllowedToConfigure(String portalPageId, Map<String, Object> context) {
+        Boolean userIsAllowed = false;
+
+        if (UtilValidate.isNotEmpty(portalPageId)) {
+            GenericValue userLogin = (GenericValue) context.get("userLogin");
+            if (UtilValidate.isNotEmpty(userLogin)) {
+                String userLoginId = (String) userLogin.get("userLoginId");
+                Security security = (Security) context.get("security");
+
+                Boolean hasPortalAdminPermission = security.hasPermission("PORTALPAGE_ADMIN", userLogin);
+                try {
+                    Delegator delegator = WidgetWorker.getDelegator(context);
+                    GenericValue portalPage = EntityQuery.use(delegator).from("PortalPage").where("portalPageId", portalPageId).queryOne();
+                    if (UtilValidate.isNotEmpty(portalPage)) {
+                        String ownerUserLoginId = (String) portalPage.get("ownerUserLoginId");
+                        // Users with PORTALPAGE_ADMIN permission can configure every Portal Page
+                        userIsAllowed = (ownerUserLoginId.equals(userLoginId) || hasPortalAdminPermission);
+                    }
+                } catch (GenericEntityException e) {
+                    return false;
+                }
+            }
+        }
+
+        return userIsAllowed;       
+    }
+    
+}
diff --git a/framework/widget/src/org/ofbiz/widget/PortalPageWorkerInterface.java b/framework/widget/src/org/ofbiz/widget/portal/PortalPageWorkerInterface.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/PortalPageWorkerInterface.java
rename to framework/widget/src/org/ofbiz/widget/portal/PortalPageWorkerInterface.java
index 3cc1d87..bc60a5b 100644
--- a/framework/widget/src/org/ofbiz/widget/PortalPageWorkerInterface.java
+++ b/framework/widget/src/org/ofbiz/widget/portal/PortalPageWorkerInterface.java
@@ -1,33 +1,33 @@
-/*******************************************************************************
- * 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.ofbiz.widget;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.entity.Delegator;
-
-/**
- * PortalPageWorkerInterface
- */
-public interface PortalPageWorkerInterface {
-    public String renderPortalPageAsTextExt(Delegator delegator, String portalPageId, Map<String, Object> templateContext,
-            boolean cache) throws GeneralException, IOException;
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.portal;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.entity.Delegator;
+
+/**
+ * PortalPageWorkerInterface
+ */
+public interface PortalPageWorkerInterface {
+    public String renderPortalPageAsTextExt(Delegator delegator, String portalPageId, Map<String, Object> templateContext,
+            boolean cache) throws GeneralException, IOException;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/WidgetPortalPageWorker.java b/framework/widget/src/org/ofbiz/widget/portal/WidgetPortalPageWorker.java
similarity index 94%
rename from framework/widget/src/org/ofbiz/widget/WidgetPortalPageWorker.java
rename to framework/widget/src/org/ofbiz/widget/portal/WidgetPortalPageWorker.java
index 8b942a3..66dd28d 100644
--- a/framework/widget/src/org/ofbiz/widget/WidgetPortalPageWorker.java
+++ b/framework/widget/src/org/ofbiz/widget/portal/WidgetPortalPageWorker.java
@@ -1,41 +1,42 @@
-/*******************************************************************************
- * 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.ofbiz.widget;
-import org.ofbiz.base.util.Debug;
-
-/**
- * PortalPageWorker Class
- */
-public class WidgetPortalPageWorker {
-    public static final String module = WidgetPortalPageWorker.class.getName();
-    public static PortalPageWorkerInterface portalPageWorker = null;
-    static {
-        try {
-            ClassLoader loader = Thread.currentThread().getContextClassLoader();
-            // note: loadClass is necessary for these since this class doesn't know anything about them at compile time
-            portalPageWorker = (PortalPageWorkerInterface) loader.loadClass("org.ofbiz.widget.PortalPageWorker").newInstance();
-        } catch (ClassNotFoundException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        } catch (IllegalAccessException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        } catch (InstantiationException e) {
-            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.portal;
+
+import org.ofbiz.base.util.Debug;
+
+/**
+ * PortalPageWorker Class
+ */
+public class WidgetPortalPageWorker {
+    public static final String module = WidgetPortalPageWorker.class.getName();
+    public static PortalPageWorkerInterface portalPageWorker = null;
+    static {
+        try {
+            ClassLoader loader = Thread.currentThread().getContextClassLoader();
+            // note: loadClass is necessary for these since this class doesn't know anything about them at compile time
+            portalPageWorker = (PortalPageWorkerInterface) loader.loadClass("org.ofbiz.widget.portal.PortalPageWorker").newInstance();
+        } catch (ClassNotFoundException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        } catch (IllegalAccessException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        } catch (InstantiationException e) {
+            Debug.logError(e, "Could not pre-initialize dynamically loaded class: ", module);
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
similarity index 99%
rename from framework/widget/src/org/ofbiz/widget/form/FormRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
index c4619d1..f257c78 100644
--- a/framework/widget/src/org/ofbiz/widget/form/FormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/FormRenderer.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.form;
+package org.ofbiz.widget.renderer;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -41,10 +41,13 @@
 import org.ofbiz.entity.GenericEntity;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.util.EntityListIterator;
-import org.ofbiz.widget.AbstractModelAction;
 import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.ModelForm.FieldGroup;
-import org.ofbiz.widget.form.ModelForm.FieldGroupBase;
+import org.ofbiz.widget.model.AbstractModelAction;
+import org.ofbiz.widget.model.FieldInfo;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelForm.FieldGroup;
+import org.ofbiz.widget.model.ModelForm.FieldGroupBase;
+import org.ofbiz.widget.model.ModelFormField;
 
 /**
  * A form rendering engine.
diff --git a/framework/widget/src/org/ofbiz/widget/form/FormStringRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/form/FormStringRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
index 487d894..9f64859 100644
--- a/framework/widget/src/org/ofbiz/widget/form/FormStringRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/FormStringRenderer.java
@@ -1,96 +1,99 @@
-/*******************************************************************************
- * 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.ofbiz.widget.form;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Widget Library - Form String Renderer interface.
- */
-public interface FormStringRenderer {
-    public void renderDisplayField(Appendable writer, Map<String, Object> context, ModelFormField.DisplayField displayField) throws IOException;
-    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, ModelFormField.HyperlinkField hyperlinkField) throws IOException;
-
-    public void renderTextField(Appendable writer, Map<String, Object> context, ModelFormField.TextField textField) throws IOException;
-    public void renderTextareaField(Appendable writer, Map<String, Object> context, ModelFormField.TextareaField textareaField) throws IOException;
-    public void renderDateTimeField(Appendable writer, Map<String, Object> context, ModelFormField.DateTimeField dateTimeField) throws IOException;
-
-    public void renderDropDownField(Appendable writer, Map<String, Object> context, ModelFormField.DropDownField dropDownField) throws IOException;
-    public void renderCheckField(Appendable writer, Map<String, Object> context, ModelFormField.CheckField checkField) throws IOException;
-    public void renderRadioField(Appendable writer, Map<String, Object> context, ModelFormField.RadioField radioField) throws IOException;
-
-    public void renderSubmitField(Appendable writer, Map<String, Object> context, ModelFormField.SubmitField submitField) throws IOException;
-    public void renderResetField(Appendable writer, Map<String, Object> context, ModelFormField.ResetField resetField) throws IOException;
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException;
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField.HiddenField hiddenField) throws IOException;
-    public void renderIgnoredField(Appendable writer, Map<String, Object> context, ModelFormField.IgnoredField ignoredField) throws IOException;
-
-    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
-    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
-
-    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-
-    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-
-    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException;
-    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException;
-
-    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException;
-
-    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException;
-    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException;
-    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-
-    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-
-    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
-    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
-    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
-    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException;
-    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException;
-
-    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
-
-    public void renderTextFindField(Appendable writer, Map<String, Object> context, ModelFormField.TextFindField textField) throws IOException;
-    public void renderDateFindField(Appendable writer, Map<String, Object> context, ModelFormField.DateFindField textField) throws IOException;
-    public void renderRangeFindField(Appendable writer, Map<String, Object> context, ModelFormField.RangeFindField textField) throws IOException;
-    public void renderLookupField(Appendable writer, Map<String, Object> context, ModelFormField.LookupField textField) throws IOException;
-    public void renderFileField(Appendable writer, Map<String, Object> context, ModelFormField.FileField textField) throws IOException;
-    public void renderPasswordField(Appendable writer, Map<String, Object> context, ModelFormField.PasswordField textField) throws IOException;
-    public void renderImageField(Appendable writer, Map<String, Object> context, ModelFormField.ImageField textField) throws IOException;
-    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException;
-    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ModelFormField.ContainerField containerField) throws IOException;
-    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException;
-    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException;
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelFormField;
+
+/**
+ * Widget Library - Form String Renderer interface.
+ */
+public interface FormStringRenderer {
+    public void renderDisplayField(Appendable writer, Map<String, Object> context, ModelFormField.DisplayField displayField) throws IOException;
+    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, ModelFormField.HyperlinkField hyperlinkField) throws IOException;
+
+    public void renderTextField(Appendable writer, Map<String, Object> context, ModelFormField.TextField textField) throws IOException;
+    public void renderTextareaField(Appendable writer, Map<String, Object> context, ModelFormField.TextareaField textareaField) throws IOException;
+    public void renderDateTimeField(Appendable writer, Map<String, Object> context, ModelFormField.DateTimeField dateTimeField) throws IOException;
+
+    public void renderDropDownField(Appendable writer, Map<String, Object> context, ModelFormField.DropDownField dropDownField) throws IOException;
+    public void renderCheckField(Appendable writer, Map<String, Object> context, ModelFormField.CheckField checkField) throws IOException;
+    public void renderRadioField(Appendable writer, Map<String, Object> context, ModelFormField.RadioField radioField) throws IOException;
+
+    public void renderSubmitField(Appendable writer, Map<String, Object> context, ModelFormField.SubmitField submitField) throws IOException;
+    public void renderResetField(Appendable writer, Map<String, Object> context, ModelFormField.ResetField resetField) throws IOException;
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException;
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField.HiddenField hiddenField) throws IOException;
+    public void renderIgnoredField(Appendable writer, Map<String, Object> context, ModelFormField.IgnoredField ignoredField) throws IOException;
+
+    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
+    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
+
+    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+
+    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+
+    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException;
+    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException;
+
+    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException;
+
+    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException;
+    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException;
+    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+
+    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+
+    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
+    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
+    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException;
+    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException;
+    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException;
+
+    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException;
+
+    public void renderTextFindField(Appendable writer, Map<String, Object> context, ModelFormField.TextFindField textField) throws IOException;
+    public void renderDateFindField(Appendable writer, Map<String, Object> context, ModelFormField.DateFindField textField) throws IOException;
+    public void renderRangeFindField(Appendable writer, Map<String, Object> context, ModelFormField.RangeFindField textField) throws IOException;
+    public void renderLookupField(Appendable writer, Map<String, Object> context, ModelFormField.LookupField textField) throws IOException;
+    public void renderFileField(Appendable writer, Map<String, Object> context, ModelFormField.FileField textField) throws IOException;
+    public void renderPasswordField(Appendable writer, Map<String, Object> context, ModelFormField.PasswordField textField) throws IOException;
+    public void renderImageField(Appendable writer, Map<String, Object> context, ModelFormField.ImageField textField) throws IOException;
+    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException;
+    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ModelFormField.ContainerField containerField) throws IOException;
+    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException;
+    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/menu/MenuStringRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/MenuStringRenderer.java
similarity index 91%
rename from framework/widget/src/org/ofbiz/widget/menu/MenuStringRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/MenuStringRenderer.java
index 71f6a32..b1bf5c3 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/MenuStringRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/MenuStringRenderer.java
@@ -1,39 +1,41 @@
-/*******************************************************************************
- * 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") throws IOException ; 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.ofbiz.widget.menu;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.ofbiz.widget.CommonWidgetModels.Image;
-
-
-/**
- * Widget Library - Form String Renderer interface
- */
-public interface MenuStringRenderer {
-    public void renderMenuItem(Appendable writer, Map<String, Object> context, ModelMenuItem menuItem) throws IOException ;
-    public void renderMenuOpen(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException ;
-    public void renderMenuClose(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException ;
-    public void renderFormatSimpleWrapperOpen(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException ;
-    public void renderFormatSimpleWrapperClose(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException ;
-    public void renderFormatSimpleWrapperRows(Appendable writer, Map<String, Object> context, Object menu) throws IOException ;
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelMenuItem.MenuLink link) throws IOException ;
-    public void renderImage(Appendable writer, Map<String, Object> context, Image image) throws IOException ;
-}
+/*******************************************************************************
+ * 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") throws IOException ; 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.ofbiz.widget.renderer;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.ofbiz.widget.model.CommonWidgetModels.Image;
+import org.ofbiz.widget.model.ModelMenu;
+import org.ofbiz.widget.model.ModelMenuItem;
+
+
+/**
+ * Widget Library - Form String Renderer interface
+ */
+public interface MenuStringRenderer {
+    public void renderMenuItem(Appendable writer, Map<String, Object> context, ModelMenuItem menuItem) throws IOException ;
+    public void renderMenuOpen(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException ;
+    public void renderMenuClose(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException ;
+    public void renderFormatSimpleWrapperOpen(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException ;
+    public void renderFormatSimpleWrapperClose(Appendable writer, Map<String, Object> context, ModelMenu menu) throws IOException ;
+    public void renderFormatSimpleWrapperRows(Appendable writer, Map<String, Object> context, Object menu) throws IOException ;
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelMenuItem.MenuLink link) throws IOException ;
+    public void renderImage(Appendable writer, Map<String, Object> context, Image image) throws IOException ;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/menu/MenuWrapTransform.java b/framework/widget/src/org/ofbiz/widget/renderer/MenuWrapTransform.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/menu/MenuWrapTransform.java
rename to framework/widget/src/org/ofbiz/widget/renderer/MenuWrapTransform.java
index e95b924..45120b5 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/MenuWrapTransform.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/MenuWrapTransform.java
@@ -1,200 +1,200 @@
-/*******************************************************************************
- * 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.ofbiz.widget.menu;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.template.FreeMarkerWorker;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.webapp.ftl.LoopWriter;
-import org.ofbiz.widget.WidgetContentWorker;
-import org.ofbiz.widget.html.HtmlMenuWrapper;
-
-import freemarker.core.Environment;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateTransformModel;
-import freemarker.template.TransformControl;
-
-//import com.clarkware.profiler.Profiler;
-/**
- * MenuWrapTransform -  a FreeMarker transform that allow the ModelMenu
- * stuff to be used at the FM level. It can be used to add "function bars"
- * to pages.
- *
- * Accepts the following arguments (all of which can alternatively be present in the template context):
- * - List<Map<String, ? extends Object>> globalNodeTrail
- * - String contentAssocPredicateId
- * - String nullThruDatesOnly
- * - String subDataResourceTypeId
- * - String renderOnStart
- * - String renderOnClose
- * - String menuDefFile
- * - String menuName
- * - String menuWrapperClassName
- * - String associatedContentId
- *
- * This is an interactive FreeMarker transform that allows the user to modify the contents that are placed within it.
- */
-public class MenuWrapTransform implements TemplateTransformModel {
-
-    public static final String module = MenuWrapTransform.class.getName();
-    public static final String [] upSaveKeyNames = {"globalNodeTrail"};
-    public static final String [] saveKeyNames = {"contentId", "subContentId", "subDataResourceTypeId", "mimeTypeId", "whenMap", "locale",  "wrapTemplateId", "encloseWrapText", "nullThruDatesOnly", "renderOnStart", "renderOnClose", "menuDefFile", "menuName", "associatedContentId", "wrapperClassName"};
-
-    @SuppressWarnings("unchecked")
-    public Writer getWriter(final Writer out, Map args) {
-        final Environment env = Environment.getCurrentEnvironment();
-        final Delegator delegator = FreeMarkerWorker.getWrappedObject("delegator", env);
-        final HttpServletRequest request = FreeMarkerWorker.getWrappedObject("request", env);
-        final HttpServletResponse response = FreeMarkerWorker.getWrappedObject("response", env);
-        final HttpSession session = FreeMarkerWorker.getWrappedObject("session", env);
-
-        final GenericValue userLogin = FreeMarkerWorker.getWrappedObject("userLogin", env);
-        final Map<String, Object> templateCtx = FreeMarkerWorker.getWrappedObject("context", env);
-
-        FreeMarkerWorker.getSiteParameters(request, templateCtx);
-
-        final Map<String, Object> savedValuesUp = new HashMap<String, Object>();
-        FreeMarkerWorker.saveContextValues(templateCtx, upSaveKeyNames, savedValuesUp);
-
-        Map<String, Object> checkedArgs = UtilGenerics.checkMap(args);
-        FreeMarkerWorker.overrideWithArgs(templateCtx, checkedArgs);
-        //final String menuDefFile = (String)templateCtx.get("menuDefFile");
-        //final String menuName = (String)templateCtx.get("menuName");
-        //final String associatedContentId = (String)templateCtx.get("associatedContentId");
-        List<Map<String, ? extends Object>> trail = UtilGenerics.checkList(templateCtx.get("globalNodeTrail"));
-        String contentAssocPredicateId = (String)templateCtx.get("contentAssocPredicateId");
-        String strNullThruDatesOnly = (String)templateCtx.get("nullThruDatesOnly");
-        Boolean nullThruDatesOnly = (strNullThruDatesOnly != null && strNullThruDatesOnly.equalsIgnoreCase("true")) ? Boolean.TRUE :Boolean.FALSE;
-        GenericValue val = null;
-        try {
-            if (WidgetContentWorker.contentWorker != null) {
-                val = WidgetContentWorker.contentWorker.getCurrentContentExt(delegator, trail, userLogin, templateCtx, nullThruDatesOnly, contentAssocPredicateId);
-            } else {
-                Debug.logError("Not rendering content, not ContentWorker found.", module);
-            }
-        } catch (GeneralException e) {
-            throw new RuntimeException("Error getting current content. " + e.toString());
-        }
-        final GenericValue view = val;
-
-        String dataResourceId = null;
-        try {
-            dataResourceId = (String) view.get("drDataResourceId");
-        } catch (Exception e) {
-            dataResourceId = (String) view.get("dataResourceId");
-        }
-        String subContentIdSub = (String) view.get("contentId");
-        // This order is taken so that the dataResourceType can be overridden in the transform arguments.
-        String subDataResourceTypeId = (String)templateCtx.get("subDataResourceTypeId");
-        if (UtilValidate.isEmpty(subDataResourceTypeId)) {
-            try {
-                subDataResourceTypeId = (String) view.get("drDataResourceTypeId");
-            } catch (Exception e) {
-                // view may be "Content"
-            }
-            // TODO: If this value is still empty then it is probably necessary to get a value from
-            // the parent context. But it will already have one and it is the same context that is
-            // being passed.
-        }
-        // This order is taken so that the mimeType can be overridden in the transform arguments.
-        String mimeTypeId = null;
-        if (WidgetContentWorker.contentWorker != null) {
-            mimeTypeId = WidgetContentWorker.contentWorker.getMimeTypeIdExt(delegator, view, templateCtx);
-        } else {
-            Debug.logError("Not rendering content, not ContentWorker found.", module);
-        }
-        templateCtx.put("drDataResourceId", dataResourceId);
-        templateCtx.put("mimeTypeId", mimeTypeId);
-        templateCtx.put("dataResourceId", dataResourceId);
-        templateCtx.put("subContentIdSub", subContentIdSub);
-        templateCtx.put("subDataResourceTypeId", subDataResourceTypeId);
-        final Map<String, Object> savedValues = new HashMap<String, Object>();
-        FreeMarkerWorker.saveContextValues(templateCtx, saveKeyNames, savedValues);
-
-        final StringBuilder buf = new StringBuilder();
-
-        return new LoopWriter(out) {
-
-            @Override
-            public int onStart() throws TemplateModelException, IOException {
-                String renderOnStart = (String)templateCtx.get("renderOnStart");
-                if (renderOnStart != null && renderOnStart.equalsIgnoreCase("true")) {
-                    renderMenu();
-                }
-                return TransformControl.EVALUATE_BODY;
-            }
-
-            @Override
-            public void write(char cbuf[], int off, int len) {
-                buf.append(cbuf, off, len);
-            }
-
-            @Override
-            public void flush() throws IOException {
-                out.flush();
-            }
-
-            @Override
-            public void close() throws IOException {
-                FreeMarkerWorker.reloadValues(templateCtx, savedValues, env);
-                String wrappedContent = buf.toString();
-                out.write(wrappedContent);
-                String renderOnClose = (String)templateCtx.get("renderOnClose");
-                if (renderOnClose == null || !renderOnClose.equalsIgnoreCase("false")) {
-                    renderMenu();
-                }
-                FreeMarkerWorker.reloadValues(templateCtx, savedValuesUp, env);
-            }
-
-            public void renderMenu() throws IOException {
-
-                String menuDefFile = (String)templateCtx.get("menuDefFile");
-                String menuName = (String)templateCtx.get("menuName");
-                String menuWrapperClassName = (String)templateCtx.get("menuWrapperClassName");
-                HtmlMenuWrapper menuWrapper = HtmlMenuWrapper.getMenuWrapper(request, response, session, menuDefFile, menuName, menuWrapperClassName);
-
-                if (menuWrapper == null) {
-                    throw new IOException("HtmlMenuWrapper with def file:" + menuDefFile + " menuName:" + menuName + " and HtmlMenuWrapper class:" + menuWrapperClassName + " could not be instantiated.");
-                }
-
-                String associatedContentId = (String)templateCtx.get("associatedContentId");
-                menuWrapper.putInContext("defaultAssociatedContentId", associatedContentId);
-                menuWrapper.putInContext("currentValue", view);
-
-                String menuStr = menuWrapper.renderMenuString();
-                out.write(menuStr);
-            }
-
-        };
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.template.FreeMarkerWorker;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.webapp.ftl.LoopWriter;
+import org.ofbiz.widget.content.WidgetContentWorker;
+import org.ofbiz.widget.renderer.html.HtmlMenuWrapper;
+
+import freemarker.core.Environment;
+import freemarker.template.TemplateModelException;
+import freemarker.template.TemplateTransformModel;
+import freemarker.template.TransformControl;
+
+//import com.clarkware.profiler.Profiler;
+/**
+ * MenuWrapTransform -  a FreeMarker transform that allow the ModelMenu
+ * stuff to be used at the FM level. It can be used to add "function bars"
+ * to pages.
+ *
+ * Accepts the following arguments (all of which can alternatively be present in the template context):
+ * - List<Map<String, ? extends Object>> globalNodeTrail
+ * - String contentAssocPredicateId
+ * - String nullThruDatesOnly
+ * - String subDataResourceTypeId
+ * - String renderOnStart
+ * - String renderOnClose
+ * - String menuDefFile
+ * - String menuName
+ * - String menuWrapperClassName
+ * - String associatedContentId
+ *
+ * This is an interactive FreeMarker transform that allows the user to modify the contents that are placed within it.
+ */
+public class MenuWrapTransform implements TemplateTransformModel {
+
+    public static final String module = MenuWrapTransform.class.getName();
+    public static final String [] upSaveKeyNames = {"globalNodeTrail"};
+    public static final String [] saveKeyNames = {"contentId", "subContentId", "subDataResourceTypeId", "mimeTypeId", "whenMap", "locale",  "wrapTemplateId", "encloseWrapText", "nullThruDatesOnly", "renderOnStart", "renderOnClose", "menuDefFile", "menuName", "associatedContentId", "wrapperClassName"};
+
+    @SuppressWarnings("unchecked")
+    public Writer getWriter(final Writer out, Map args) {
+        final Environment env = Environment.getCurrentEnvironment();
+        final Delegator delegator = FreeMarkerWorker.getWrappedObject("delegator", env);
+        final HttpServletRequest request = FreeMarkerWorker.getWrappedObject("request", env);
+        final HttpServletResponse response = FreeMarkerWorker.getWrappedObject("response", env);
+        final HttpSession session = FreeMarkerWorker.getWrappedObject("session", env);
+
+        final GenericValue userLogin = FreeMarkerWorker.getWrappedObject("userLogin", env);
+        final Map<String, Object> templateCtx = FreeMarkerWorker.getWrappedObject("context", env);
+
+        FreeMarkerWorker.getSiteParameters(request, templateCtx);
+
+        final Map<String, Object> savedValuesUp = new HashMap<String, Object>();
+        FreeMarkerWorker.saveContextValues(templateCtx, upSaveKeyNames, savedValuesUp);
+
+        Map<String, Object> checkedArgs = UtilGenerics.checkMap(args);
+        FreeMarkerWorker.overrideWithArgs(templateCtx, checkedArgs);
+        //final String menuDefFile = (String)templateCtx.get("menuDefFile");
+        //final String menuName = (String)templateCtx.get("menuName");
+        //final String associatedContentId = (String)templateCtx.get("associatedContentId");
+        List<Map<String, ? extends Object>> trail = UtilGenerics.checkList(templateCtx.get("globalNodeTrail"));
+        String contentAssocPredicateId = (String)templateCtx.get("contentAssocPredicateId");
+        String strNullThruDatesOnly = (String)templateCtx.get("nullThruDatesOnly");
+        Boolean nullThruDatesOnly = (strNullThruDatesOnly != null && strNullThruDatesOnly.equalsIgnoreCase("true")) ? Boolean.TRUE :Boolean.FALSE;
+        GenericValue val = null;
+        try {
+            if (WidgetContentWorker.contentWorker != null) {
+                val = WidgetContentWorker.contentWorker.getCurrentContentExt(delegator, trail, userLogin, templateCtx, nullThruDatesOnly, contentAssocPredicateId);
+            } else {
+                Debug.logError("Not rendering content, not ContentWorker found.", module);
+            }
+        } catch (GeneralException e) {
+            throw new RuntimeException("Error getting current content. " + e.toString());
+        }
+        final GenericValue view = val;
+
+        String dataResourceId = null;
+        try {
+            dataResourceId = (String) view.get("drDataResourceId");
+        } catch (Exception e) {
+            dataResourceId = (String) view.get("dataResourceId");
+        }
+        String subContentIdSub = (String) view.get("contentId");
+        // This order is taken so that the dataResourceType can be overridden in the transform arguments.
+        String subDataResourceTypeId = (String)templateCtx.get("subDataResourceTypeId");
+        if (UtilValidate.isEmpty(subDataResourceTypeId)) {
+            try {
+                subDataResourceTypeId = (String) view.get("drDataResourceTypeId");
+            } catch (Exception e) {
+                // view may be "Content"
+            }
+            // TODO: If this value is still empty then it is probably necessary to get a value from
+            // the parent context. But it will already have one and it is the same context that is
+            // being passed.
+        }
+        // This order is taken so that the mimeType can be overridden in the transform arguments.
+        String mimeTypeId = null;
+        if (WidgetContentWorker.contentWorker != null) {
+            mimeTypeId = WidgetContentWorker.contentWorker.getMimeTypeIdExt(delegator, view, templateCtx);
+        } else {
+            Debug.logError("Not rendering content, not ContentWorker found.", module);
+        }
+        templateCtx.put("drDataResourceId", dataResourceId);
+        templateCtx.put("mimeTypeId", mimeTypeId);
+        templateCtx.put("dataResourceId", dataResourceId);
+        templateCtx.put("subContentIdSub", subContentIdSub);
+        templateCtx.put("subDataResourceTypeId", subDataResourceTypeId);
+        final Map<String, Object> savedValues = new HashMap<String, Object>();
+        FreeMarkerWorker.saveContextValues(templateCtx, saveKeyNames, savedValues);
+
+        final StringBuilder buf = new StringBuilder();
+
+        return new LoopWriter(out) {
+
+            @Override
+            public int onStart() throws TemplateModelException, IOException {
+                String renderOnStart = (String)templateCtx.get("renderOnStart");
+                if (renderOnStart != null && renderOnStart.equalsIgnoreCase("true")) {
+                    renderMenu();
+                }
+                return TransformControl.EVALUATE_BODY;
+            }
+
+            @Override
+            public void write(char cbuf[], int off, int len) {
+                buf.append(cbuf, off, len);
+            }
+
+            @Override
+            public void flush() throws IOException {
+                out.flush();
+            }
+
+            @Override
+            public void close() throws IOException {
+                FreeMarkerWorker.reloadValues(templateCtx, savedValues, env);
+                String wrappedContent = buf.toString();
+                out.write(wrappedContent);
+                String renderOnClose = (String)templateCtx.get("renderOnClose");
+                if (renderOnClose == null || !renderOnClose.equalsIgnoreCase("false")) {
+                    renderMenu();
+                }
+                FreeMarkerWorker.reloadValues(templateCtx, savedValuesUp, env);
+            }
+
+            public void renderMenu() throws IOException {
+
+                String menuDefFile = (String)templateCtx.get("menuDefFile");
+                String menuName = (String)templateCtx.get("menuName");
+                String menuWrapperClassName = (String)templateCtx.get("menuWrapperClassName");
+                HtmlMenuWrapper menuWrapper = HtmlMenuWrapper.getMenuWrapper(request, response, session, menuDefFile, menuName, menuWrapperClassName);
+
+                if (menuWrapper == null) {
+                    throw new IOException("HtmlMenuWrapper with def file:" + menuDefFile + " menuName:" + menuName + " and HtmlMenuWrapper class:" + menuWrapperClassName + " could not be instantiated.");
+                }
+
+                String associatedContentId = (String)templateCtx.get("associatedContentId");
+                menuWrapper.putInContext("defaultAssociatedContentId", associatedContentId);
+                menuWrapper.putInContext("currentValue", view);
+
+                String menuStr = menuWrapper.renderMenuString();
+                out.write(menuStr);
+            }
+
+        };
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/Paginator.java b/framework/widget/src/org/ofbiz/widget/renderer/Paginator.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/form/Paginator.java
rename to framework/widget/src/org/ofbiz/widget/renderer/Paginator.java
index 621c9b0..2d051f1 100644
--- a/framework/widget/src/org/ofbiz/widget/form/Paginator.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/Paginator.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.form;
+package org.ofbiz.widget.renderer;
 
 import java.util.Iterator;
 import java.util.List;
@@ -29,6 +29,7 @@
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.util.EntityListIterator;
 import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.ModelForm;
 
 /**
  * Utility methods for handling list pagination.
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ScreenRenderException.java b/framework/widget/src/org/ofbiz/widget/renderer/ScreenRenderException.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/screen/ScreenRenderException.java
rename to framework/widget/src/org/ofbiz/widget/renderer/ScreenRenderException.java
index ca8bdbc..9406a33 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ScreenRenderException.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/ScreenRenderException.java
@@ -1,48 +1,48 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import org.ofbiz.base.util.GeneralException;
-
-/**
- * Wraps any exceptions encountered during the rendering of
- * a screen.  It is thrown to the top of the recursive
- * rendering process so that we avoid having to log redundant
- * exceptions.
- */
-@SuppressWarnings("serial")
-public class ScreenRenderException extends GeneralException {
-
-    public ScreenRenderException() {
-        super();
-    }
-
-    public ScreenRenderException(Throwable nested) {
-        super(nested);
-    }
-
-    public ScreenRenderException(String str) {
-        super(str);
-    }
-
-    public ScreenRenderException(String str, Throwable nested) {
-        super(str, nested);
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer;
+
+import org.ofbiz.base.util.GeneralException;
+
+/**
+ * Wraps any exceptions encountered during the rendering of
+ * a screen.  It is thrown to the top of the recursive
+ * rendering process so that we avoid having to log redundant
+ * exceptions.
+ */
+@SuppressWarnings("serial")
+public class ScreenRenderException extends GeneralException {
+
+    public ScreenRenderException() {
+        super();
+    }
+
+    public ScreenRenderException(Throwable nested) {
+        super(nested);
+    }
+
+    public ScreenRenderException(String str) {
+        super(str);
+    }
+
+    public ScreenRenderException(String str, Throwable nested) {
+        super(str, nested);
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ScreenRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/ScreenRenderer.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/screen/ScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/ScreenRenderer.java
index 738c009..87192b5 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ScreenRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/ScreenRenderer.java
@@ -1,316 +1,318 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilDateTime;
-import org.ofbiz.base.util.UtilFormatOut;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.collections.MapStack;
-import org.ofbiz.base.util.template.FreeMarkerWorker;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntity;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.security.Security;
-import org.ofbiz.service.DispatchContext;
-import org.ofbiz.service.GenericServiceException;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.webapp.control.LoginWorker;
-import org.ofbiz.webapp.website.WebSiteWorker;
-import org.ofbiz.widget.cache.GenericWidgetOutput;
-import org.ofbiz.widget.cache.ScreenCache;
-import org.ofbiz.widget.cache.WidgetContextCacheKey;
-import org.xml.sax.SAXException;
-
-import freemarker.ext.jsp.TaglibFactory;
-import freemarker.ext.servlet.HttpRequestHashModel;
-import freemarker.ext.servlet.HttpSessionHashModel;
-
-/**
- * Widget Library - Screen model class
- */
-public class ScreenRenderer {
-
-    public static final String module = ScreenRenderer.class.getName();
-
-    protected Appendable writer;
-    protected MapStack<String> context;
-    protected ScreenStringRenderer screenStringRenderer;
-    protected int renderFormSeqNumber = 0;
-
-    public ScreenRenderer(Appendable writer, MapStack<String> context, ScreenStringRenderer screenStringRenderer) {
-        this.writer = writer;
-        this.context = context;
-        if (this.context == null) this.context = MapStack.create();
-        this.screenStringRenderer = screenStringRenderer;
-    }
-
-    /**
-     * Renders the named screen using the render environment configured when this ScreenRenderer was created.
-     *
-     * @param combinedName A combination of the resource name/location for the screen XML file and the name of the screen within that file, separated by a pound sign ("#"). This is the same format that is used in the view-map elements on the controller.xml file.
-     * @throws IOException
-     * @throws SAXException
-     * @throws ParserConfigurationException
-     */
-    public String render(String combinedName) throws GeneralException, IOException, SAXException, ParserConfigurationException {
-        String resourceName = ScreenFactory.getResourceNameFromCombined(combinedName);
-        String screenName = ScreenFactory.getScreenNameFromCombined(combinedName);
-        this.render(resourceName, screenName);
-        return "";
-    }
-
-    /**
-     * Renders the named screen using the render environment configured when this ScreenRenderer was created.
-     *
-     * @param resourceName The name/location of the resource to use, can use "component://[component-name]/" and "ofbiz://" and other special OFBiz style URLs
-     * @param screenName The name of the screen within the XML file specified by the resourceName.
-     * @throws IOException
-     * @throws SAXException
-     * @throws ParserConfigurationException
-     */
-    public String render(String resourceName, String screenName) throws GeneralException, IOException, SAXException, ParserConfigurationException {
-        ModelScreen modelScreen = ScreenFactory.getScreenFromLocation(resourceName, screenName);
-        if (modelScreen.getUseCache()) {
-            // if in the screen definition use-cache is set to true
-            // then try to get an already built screen output from the cache:
-            // 1) if we find it then we get it and attach it to the passed in writer
-            // 2) if we can't find one, we create a new StringWriter,
-            //    and pass it to the renderScreenString;
-            //    then we wrap its content and put it in the cache;
-            //    and we attach it to the passed in writer
-            WidgetContextCacheKey wcck = new WidgetContextCacheKey(context);
-            String screenCombinedName = resourceName + ":" + screenName;
-            ScreenCache screenCache = new ScreenCache();
-            GenericWidgetOutput gwo = screenCache.get(screenCombinedName, wcck);
-            if (gwo == null) {
-                Writer sw = new StringWriter();
-                modelScreen.renderScreenString(sw, context, screenStringRenderer);
-                gwo = new GenericWidgetOutput(sw.toString());
-                screenCache.put(screenCombinedName, wcck, gwo);
-                writer.append(gwo.toString());
-            } else {
-                writer.append(gwo.toString());
-            }
-        } else {
-            context.put("renderFormSeqNumber", String.valueOf(renderFormSeqNumber));
-            modelScreen.renderScreenString(writer, context, screenStringRenderer);
-        }
-        return "";
-    }
-
-    public void setRenderFormUniqueSeq (int renderFormSeqNumber) {
-        this.renderFormSeqNumber = renderFormSeqNumber;
-    }
-
-    public ScreenStringRenderer getScreenStringRenderer() {
-        return this.screenStringRenderer;
-    }
-
-    public void populateBasicContext(Map<String, Object> parameters, Delegator delegator, LocalDispatcher dispatcher, Security security, Locale locale, GenericValue userLogin) {
-        populateBasicContext(context, this, parameters, delegator, dispatcher, security, locale, userLogin);
-    }
-
-    public static void populateBasicContext(MapStack<String> context, ScreenRenderer screens, Map<String, Object> parameters, Delegator delegator, LocalDispatcher dispatcher, Security security, Locale locale, GenericValue userLogin) {
-        // ========== setup values that should always be in a screen context
-        // include an object to more easily render screens
-        context.put("screens", screens);
-
-        // make a reference for high level variables, a global context
-        context.put("globalContext", context.standAloneStack());
-
-        // make sure the "nullField" object is in there for entity ops; note this is nullField and not null because as null causes problems in FreeMarker and such...
-        context.put("nullField", GenericEntity.NULL_FIELD);
-
-        context.put("parameters", parameters);
-        context.put("delegator", delegator);
-        context.put("dispatcher", dispatcher);
-        context.put("security", security);
-        context.put("locale", locale);
-        context.put("userLogin", userLogin);
-        context.put("nowTimestamp", UtilDateTime.nowTimestamp());
-        try {
-            Map<String, Object> result = dispatcher.runSync("getUserPreferenceGroup", UtilMisc.toMap("userLogin", userLogin, "userPrefGroupTypeId", "GLOBAL_PREFERENCES"));
-            context.put("userPreferences", result.get("userPrefMap"));
-        } catch (GenericServiceException e) {
-            Debug.logError(e, "Error while getting user preferences: ", module);
-        }
-    }
-
-    /**
-     * This method populates the context for this ScreenRenderer based on the HTTP Request and Response objects and the ServletContext.
-     * It leverages various conventions used in other places, namely the ControlServlet and so on, of OFBiz to get the different resources needed.
-     *
-     * @param request
-     * @param response
-     * @param servletContext
-     */
-    public void populateContextForRequest(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
-        populateContextForRequest(context, this, request, response, servletContext);
-    }
-
-    @SuppressWarnings("rawtypes")
-    public static void populateContextForRequest(MapStack<String> context, ScreenRenderer screens, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
-        HttpSession session = request.getSession();
-
-        // attribute names to skip for session and application attributes; these are all handled as special cases, duplicating results and causing undesired messages
-        Set<String> attrNamesToSkip = UtilMisc.toSet("delegator", "dispatcher", "security", "webSiteId",
-                "org.apache.catalina.jsp_classpath");
-        Map<String, Object> parameterMap = UtilHttp.getCombinedMap(request, attrNamesToSkip);
-
-        GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
-
-        populateBasicContext(context, screens, parameterMap, (Delegator) request.getAttribute("delegator"),
-                (LocalDispatcher) request.getAttribute("dispatcher"),
-                (Security) request.getAttribute("security"), UtilHttp.getLocale(request), userLogin);
-
-        context.put("autoUserLogin", session.getAttribute("autoUserLogin"));
-        context.put("person", session.getAttribute("person"));
-        context.put("partyGroup", session.getAttribute("partyGroup"));
-
-        // some things also seem to require this, so here it is:
-        request.setAttribute("userLogin", userLogin);
-
-        // set up the user's time zone
-        context.put("timeZone", UtilHttp.getTimeZone(request));
-
-        // ========== setup values that are specific to OFBiz webapps
-
-        context.put("request", request);
-        context.put("response", response);
-        context.put("session", session);
-        context.put("application", servletContext);
-        if (session != null) {
-            context.put("webappName", session.getAttribute("_WEBAPP_NAME_"));
-        }
-        if (servletContext != null) {
-            String rootDir = (String) context.get("rootDir");
-            String webSiteId = (String) context.get("webSiteId");
-            String https = (String) context.get("https");
-            if (UtilValidate.isEmpty(rootDir)) {
-                rootDir = servletContext.getRealPath("/");
-                context.put("rootDir", rootDir);
-            }
-            if (UtilValidate.isEmpty(webSiteId)) {
-                webSiteId = WebSiteWorker.getWebSiteId(request);
-                context.put("webSiteId", webSiteId);
-            }
-            if (UtilValidate.isEmpty(https)) {
-                https = (String) servletContext.getAttribute("https");
-                context.put("https", https);
-            }
-        }
-        context.put("javaScriptEnabled", Boolean.valueOf(UtilHttp.isJavaScriptEnabled(request)));
-
-        // these ones are FreeMarker specific and will only work in FTL templates, mainly here for backward compatibility
-        context.put("sessionAttributes", new HttpSessionHashModel(session, FreeMarkerWorker.getDefaultOfbizWrapper()));
-        context.put("requestAttributes", new HttpRequestHashModel(request, FreeMarkerWorker.getDefaultOfbizWrapper()));
-        TaglibFactory JspTaglibs = new TaglibFactory(servletContext);
-        context.put("JspTaglibs", JspTaglibs);
-        context.put("requestParameters",  UtilHttp.getParameterMap(request));
-        
-        // this is a dummy object to stand-in for the JPublish page object for backward compatibility
-        context.put("page", new HashMap());
-
-        // some information from/about the ControlServlet environment
-        context.put("controlPath", request.getAttribute("_CONTROL_PATH_"));
-        context.put("contextRoot", request.getAttribute("_CONTEXT_ROOT_"));
-        context.put("serverRoot", request.getAttribute("_SERVER_ROOT_URL_"));
-        context.put("checkLoginUrl", LoginWorker.makeLoginUrl(request));
-        String externalLoginKey = LoginWorker.getExternalLoginKey(request);
-        String externalKeyParam = externalLoginKey == null ? "" : "&amp;externalLoginKey=" + externalLoginKey;
-        context.put("externalLoginKey", externalLoginKey);
-        context.put("externalKeyParam", externalKeyParam);
-
-        // setup message lists
-        List<String> eventMessageList = UtilGenerics.toList(request.getAttribute("eventMessageList"));
-        if (eventMessageList == null) eventMessageList = new LinkedList<String>();
-        List<String> errorMessageList = UtilGenerics.toList(request.getAttribute("errorMessageList"));
-        if (errorMessageList == null) errorMessageList = new LinkedList<String>();
-
-        if (request.getAttribute("_EVENT_MESSAGE_") != null) {
-            eventMessageList.add(UtilFormatOut.replaceString((String) request.getAttribute("_EVENT_MESSAGE_"), "\n", "<br/>"));
-            request.removeAttribute("_EVENT_MESSAGE_");
-        }
-        List<String> msgList = UtilGenerics.toList(request.getAttribute("_EVENT_MESSAGE_LIST_"));
-        if (msgList != null) {
-            eventMessageList.addAll(msgList);
-            request.removeAttribute("_EVENT_MESSAGE_LIST_");
-        }
-        if (request.getAttribute("_ERROR_MESSAGE_") != null) {
-            errorMessageList.add(UtilFormatOut.replaceString((String) request.getAttribute("_ERROR_MESSAGE_"), "\n", "<br/>"));
-            request.removeAttribute("_ERROR_MESSAGE_");
-        }
-        if (session.getAttribute("_ERROR_MESSAGE_") != null) {
-            errorMessageList.add(UtilFormatOut.replaceString((String) session.getAttribute("_ERROR_MESSAGE_"), "\n", "<br/>"));
-            session.removeAttribute("_ERROR_MESSAGE_");
-        }
-        msgList = UtilGenerics.toList(request.getAttribute("_ERROR_MESSAGE_LIST_"));
-        if (msgList != null) {
-            errorMessageList.addAll(msgList);
-            request.removeAttribute("_ERROR_MESSAGE_LIST_");
-        }
-        context.put("eventMessageList", eventMessageList);
-        context.put("errorMessageList", errorMessageList);
-
-        if (request.getAttribute("serviceValidationException") != null) {
-            context.put("serviceValidationException", request.getAttribute("serviceValidationException"));
-            request.removeAttribute("serviceValidationException");
-        }
-
-        // if there was an error message, this is an error
-        context.put("isError", errorMessageList.size() > 0 ? Boolean.TRUE : Boolean.FALSE);
-        // if a parameter was passed saying this is an error, it is an error
-        if ("true".equals(parameterMap.get("isError"))) {
-            context.put("isError", Boolean.TRUE);
-        }
-
-        // to preserve these values, push the MapStack
-        context.push();
-    }
-
-    public Map<String, Object> getContext() {
-        return context;
-    }
-
-    public void populateContextForService(DispatchContext dctx, Map<String, Object> serviceContext) {
-        this.populateBasicContext(serviceContext, dctx.getDelegator(), dctx.getDispatcher(),
-                dctx.getSecurity(), (Locale) serviceContext.get("locale"), (GenericValue) serviceContext.get("userLogin"));
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilDateTime;
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.base.util.template.FreeMarkerWorker;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntity;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.security.Security;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.webapp.control.LoginWorker;
+import org.ofbiz.webapp.website.WebSiteWorker;
+import org.ofbiz.widget.cache.GenericWidgetOutput;
+import org.ofbiz.widget.cache.ScreenCache;
+import org.ofbiz.widget.cache.WidgetContextCacheKey;
+import org.ofbiz.widget.model.ModelScreen;
+import org.ofbiz.widget.model.ScreenFactory;
+import org.xml.sax.SAXException;
+
+import freemarker.ext.jsp.TaglibFactory;
+import freemarker.ext.servlet.HttpRequestHashModel;
+import freemarker.ext.servlet.HttpSessionHashModel;
+
+/**
+ * Widget Library - Screen model class
+ */
+public class ScreenRenderer {
+
+    public static final String module = ScreenRenderer.class.getName();
+
+    protected Appendable writer;
+    protected MapStack<String> context;
+    protected ScreenStringRenderer screenStringRenderer;
+    protected int renderFormSeqNumber = 0;
+
+    public ScreenRenderer(Appendable writer, MapStack<String> context, ScreenStringRenderer screenStringRenderer) {
+        this.writer = writer;
+        this.context = context;
+        if (this.context == null) this.context = MapStack.create();
+        this.screenStringRenderer = screenStringRenderer;
+    }
+
+    /**
+     * Renders the named screen using the render environment configured when this ScreenRenderer was created.
+     *
+     * @param combinedName A combination of the resource name/location for the screen XML file and the name of the screen within that file, separated by a pound sign ("#"). This is the same format that is used in the view-map elements on the controller.xml file.
+     * @throws IOException
+     * @throws SAXException
+     * @throws ParserConfigurationException
+     */
+    public String render(String combinedName) throws GeneralException, IOException, SAXException, ParserConfigurationException {
+        String resourceName = ScreenFactory.getResourceNameFromCombined(combinedName);
+        String screenName = ScreenFactory.getScreenNameFromCombined(combinedName);
+        this.render(resourceName, screenName);
+        return "";
+    }
+
+    /**
+     * Renders the named screen using the render environment configured when this ScreenRenderer was created.
+     *
+     * @param resourceName The name/location of the resource to use, can use "component://[component-name]/" and "ofbiz://" and other special OFBiz style URLs
+     * @param screenName The name of the screen within the XML file specified by the resourceName.
+     * @throws IOException
+     * @throws SAXException
+     * @throws ParserConfigurationException
+     */
+    public String render(String resourceName, String screenName) throws GeneralException, IOException, SAXException, ParserConfigurationException {
+        ModelScreen modelScreen = ScreenFactory.getScreenFromLocation(resourceName, screenName);
+        if (modelScreen.getUseCache()) {
+            // if in the screen definition use-cache is set to true
+            // then try to get an already built screen output from the cache:
+            // 1) if we find it then we get it and attach it to the passed in writer
+            // 2) if we can't find one, we create a new StringWriter,
+            //    and pass it to the renderScreenString;
+            //    then we wrap its content and put it in the cache;
+            //    and we attach it to the passed in writer
+            WidgetContextCacheKey wcck = new WidgetContextCacheKey(context);
+            String screenCombinedName = resourceName + ":" + screenName;
+            ScreenCache screenCache = new ScreenCache();
+            GenericWidgetOutput gwo = screenCache.get(screenCombinedName, wcck);
+            if (gwo == null) {
+                Writer sw = new StringWriter();
+                modelScreen.renderScreenString(sw, context, screenStringRenderer);
+                gwo = new GenericWidgetOutput(sw.toString());
+                screenCache.put(screenCombinedName, wcck, gwo);
+                writer.append(gwo.toString());
+            } else {
+                writer.append(gwo.toString());
+            }
+        } else {
+            context.put("renderFormSeqNumber", String.valueOf(renderFormSeqNumber));
+            modelScreen.renderScreenString(writer, context, screenStringRenderer);
+        }
+        return "";
+    }
+
+    public void setRenderFormUniqueSeq (int renderFormSeqNumber) {
+        this.renderFormSeqNumber = renderFormSeqNumber;
+    }
+
+    public ScreenStringRenderer getScreenStringRenderer() {
+        return this.screenStringRenderer;
+    }
+
+    public void populateBasicContext(Map<String, Object> parameters, Delegator delegator, LocalDispatcher dispatcher, Security security, Locale locale, GenericValue userLogin) {
+        populateBasicContext(context, this, parameters, delegator, dispatcher, security, locale, userLogin);
+    }
+
+    public static void populateBasicContext(MapStack<String> context, ScreenRenderer screens, Map<String, Object> parameters, Delegator delegator, LocalDispatcher dispatcher, Security security, Locale locale, GenericValue userLogin) {
+        // ========== setup values that should always be in a screen context
+        // include an object to more easily render screens
+        context.put("screens", screens);
+
+        // make a reference for high level variables, a global context
+        context.put("globalContext", context.standAloneStack());
+
+        // make sure the "nullField" object is in there for entity ops; note this is nullField and not null because as null causes problems in FreeMarker and such...
+        context.put("nullField", GenericEntity.NULL_FIELD);
+
+        context.put("parameters", parameters);
+        context.put("delegator", delegator);
+        context.put("dispatcher", dispatcher);
+        context.put("security", security);
+        context.put("locale", locale);
+        context.put("userLogin", userLogin);
+        context.put("nowTimestamp", UtilDateTime.nowTimestamp());
+        try {
+            Map<String, Object> result = dispatcher.runSync("getUserPreferenceGroup", UtilMisc.toMap("userLogin", userLogin, "userPrefGroupTypeId", "GLOBAL_PREFERENCES"));
+            context.put("userPreferences", result.get("userPrefMap"));
+        } catch (GenericServiceException e) {
+            Debug.logError(e, "Error while getting user preferences: ", module);
+        }
+    }
+
+    /**
+     * This method populates the context for this ScreenRenderer based on the HTTP Request and Response objects and the ServletContext.
+     * It leverages various conventions used in other places, namely the ControlServlet and so on, of OFBiz to get the different resources needed.
+     *
+     * @param request
+     * @param response
+     * @param servletContext
+     */
+    public void populateContextForRequest(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
+        populateContextForRequest(context, this, request, response, servletContext);
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static void populateContextForRequest(MapStack<String> context, ScreenRenderer screens, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
+        HttpSession session = request.getSession();
+
+        // attribute names to skip for session and application attributes; these are all handled as special cases, duplicating results and causing undesired messages
+        Set<String> attrNamesToSkip = UtilMisc.toSet("delegator", "dispatcher", "security", "webSiteId",
+                "org.apache.catalina.jsp_classpath");
+        Map<String, Object> parameterMap = UtilHttp.getCombinedMap(request, attrNamesToSkip);
+
+        GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
+
+        populateBasicContext(context, screens, parameterMap, (Delegator) request.getAttribute("delegator"),
+                (LocalDispatcher) request.getAttribute("dispatcher"),
+                (Security) request.getAttribute("security"), UtilHttp.getLocale(request), userLogin);
+
+        context.put("autoUserLogin", session.getAttribute("autoUserLogin"));
+        context.put("person", session.getAttribute("person"));
+        context.put("partyGroup", session.getAttribute("partyGroup"));
+
+        // some things also seem to require this, so here it is:
+        request.setAttribute("userLogin", userLogin);
+
+        // set up the user's time zone
+        context.put("timeZone", UtilHttp.getTimeZone(request));
+
+        // ========== setup values that are specific to OFBiz webapps
+
+        context.put("request", request);
+        context.put("response", response);
+        context.put("session", session);
+        context.put("application", servletContext);
+        if (session != null) {
+            context.put("webappName", session.getAttribute("_WEBAPP_NAME_"));
+        }
+        if (servletContext != null) {
+            String rootDir = (String) context.get("rootDir");
+            String webSiteId = (String) context.get("webSiteId");
+            String https = (String) context.get("https");
+            if (UtilValidate.isEmpty(rootDir)) {
+                rootDir = servletContext.getRealPath("/");
+                context.put("rootDir", rootDir);
+            }
+            if (UtilValidate.isEmpty(webSiteId)) {
+                webSiteId = WebSiteWorker.getWebSiteId(request);
+                context.put("webSiteId", webSiteId);
+            }
+            if (UtilValidate.isEmpty(https)) {
+                https = (String) servletContext.getAttribute("https");
+                context.put("https", https);
+            }
+        }
+        context.put("javaScriptEnabled", Boolean.valueOf(UtilHttp.isJavaScriptEnabled(request)));
+
+        // these ones are FreeMarker specific and will only work in FTL templates, mainly here for backward compatibility
+        context.put("sessionAttributes", new HttpSessionHashModel(session, FreeMarkerWorker.getDefaultOfbizWrapper()));
+        context.put("requestAttributes", new HttpRequestHashModel(request, FreeMarkerWorker.getDefaultOfbizWrapper()));
+        TaglibFactory JspTaglibs = new TaglibFactory(servletContext);
+        context.put("JspTaglibs", JspTaglibs);
+        context.put("requestParameters",  UtilHttp.getParameterMap(request));
+        
+        // this is a dummy object to stand-in for the JPublish page object for backward compatibility
+        context.put("page", new HashMap());
+
+        // some information from/about the ControlServlet environment
+        context.put("controlPath", request.getAttribute("_CONTROL_PATH_"));
+        context.put("contextRoot", request.getAttribute("_CONTEXT_ROOT_"));
+        context.put("serverRoot", request.getAttribute("_SERVER_ROOT_URL_"));
+        context.put("checkLoginUrl", LoginWorker.makeLoginUrl(request));
+        String externalLoginKey = LoginWorker.getExternalLoginKey(request);
+        String externalKeyParam = externalLoginKey == null ? "" : "&amp;externalLoginKey=" + externalLoginKey;
+        context.put("externalLoginKey", externalLoginKey);
+        context.put("externalKeyParam", externalKeyParam);
+
+        // setup message lists
+        List<String> eventMessageList = UtilGenerics.toList(request.getAttribute("eventMessageList"));
+        if (eventMessageList == null) eventMessageList = new LinkedList<String>();
+        List<String> errorMessageList = UtilGenerics.toList(request.getAttribute("errorMessageList"));
+        if (errorMessageList == null) errorMessageList = new LinkedList<String>();
+
+        if (request.getAttribute("_EVENT_MESSAGE_") != null) {
+            eventMessageList.add(UtilFormatOut.replaceString((String) request.getAttribute("_EVENT_MESSAGE_"), "\n", "<br/>"));
+            request.removeAttribute("_EVENT_MESSAGE_");
+        }
+        List<String> msgList = UtilGenerics.toList(request.getAttribute("_EVENT_MESSAGE_LIST_"));
+        if (msgList != null) {
+            eventMessageList.addAll(msgList);
+            request.removeAttribute("_EVENT_MESSAGE_LIST_");
+        }
+        if (request.getAttribute("_ERROR_MESSAGE_") != null) {
+            errorMessageList.add(UtilFormatOut.replaceString((String) request.getAttribute("_ERROR_MESSAGE_"), "\n", "<br/>"));
+            request.removeAttribute("_ERROR_MESSAGE_");
+        }
+        if (session.getAttribute("_ERROR_MESSAGE_") != null) {
+            errorMessageList.add(UtilFormatOut.replaceString((String) session.getAttribute("_ERROR_MESSAGE_"), "\n", "<br/>"));
+            session.removeAttribute("_ERROR_MESSAGE_");
+        }
+        msgList = UtilGenerics.toList(request.getAttribute("_ERROR_MESSAGE_LIST_"));
+        if (msgList != null) {
+            errorMessageList.addAll(msgList);
+            request.removeAttribute("_ERROR_MESSAGE_LIST_");
+        }
+        context.put("eventMessageList", eventMessageList);
+        context.put("errorMessageList", errorMessageList);
+
+        if (request.getAttribute("serviceValidationException") != null) {
+            context.put("serviceValidationException", request.getAttribute("serviceValidationException"));
+            request.removeAttribute("serviceValidationException");
+        }
+
+        // if there was an error message, this is an error
+        context.put("isError", errorMessageList.size() > 0 ? Boolean.TRUE : Boolean.FALSE);
+        // if a parameter was passed saying this is an error, it is an error
+        if ("true".equals(parameterMap.get("isError"))) {
+            context.put("isError", Boolean.TRUE);
+        }
+
+        // to preserve these values, push the MapStack
+        context.push();
+    }
+
+    public Map<String, Object> getContext() {
+        return context;
+    }
+
+    public void populateContextForService(DispatchContext dctx, Map<String, Object> serviceContext) {
+        this.populateBasicContext(serviceContext, dctx.getDelegator(), dctx.getDispatcher(),
+                dctx.getSecurity(), (Locale) serviceContext.get("locale"), (GenericValue) serviceContext.get("userLogin"));
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ScreenStringRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/ScreenStringRenderer.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/screen/ScreenStringRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/ScreenStringRenderer.java
index ecb39eb..5cdc80d 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ScreenStringRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/ScreenStringRenderer.java
@@ -1,66 +1,67 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.IOException;
-import java.util.Map;
-import org.ofbiz.entity.GenericValue;
-
-import org.ofbiz.base.util.GeneralException;
-
-/**
- * Widget Library - Screen String Renderer interface.
- */
-public interface ScreenStringRenderer {
-    public String getRendererName();
-    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException;
-    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException;
-    public void renderSectionBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException;
-    public void renderSectionEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException;
-    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ModelScreenWidget.ColumnContainer columnContainer) throws IOException;
-    public void renderContainerBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException;
-    public void renderContainerEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException;
-    public void renderContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException;
-    public void renderContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException;
-    public void renderContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException;
-    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException;
-    public void renderSubContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException;
-    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException;
-
-    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.HorizontalSeparator separator) throws IOException;
-    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException;
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenLink link) throws IOException;
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenImage image) throws IOException;
-
-    public void renderContentFrame(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException;
-    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, ModelScreenWidget.Screenlet screenlet) throws IOException;
-    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, ModelScreenWidget.Screenlet screenlet) throws GeneralException, IOException;
-    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Screenlet screenlet) throws IOException;
-
-    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException;
-    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException;
-    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException;
-    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException;
-    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException;
-    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException;
-    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException;
-}
-
-
-
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.widget.model.ModelScreenWidget;
+
+/**
+ * Widget Library - Screen String Renderer interface.
+ */
+public interface ScreenStringRenderer {
+    public String getRendererName();
+    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException;
+    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException;
+    public void renderSectionBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException;
+    public void renderSectionEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException;
+    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ModelScreenWidget.ColumnContainer columnContainer) throws IOException;
+    public void renderContainerBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException;
+    public void renderContainerEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException;
+    public void renderContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException;
+    public void renderContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException;
+    public void renderContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException;
+    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException;
+    public void renderSubContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException;
+    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException;
+
+    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.HorizontalSeparator separator) throws IOException;
+    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException;
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenLink link) throws IOException;
+    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenImage image) throws IOException;
+
+    public void renderContentFrame(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException;
+    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, ModelScreenWidget.Screenlet screenlet) throws IOException;
+    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, ModelScreenWidget.Screenlet screenlet) throws GeneralException, IOException;
+    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Screenlet screenlet) throws IOException;
+
+    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException;
+    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException;
+    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException;
+    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException;
+    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException;
+    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException;
+    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException;
+}
+
+
+
diff --git a/framework/widget/src/org/ofbiz/widget/tree/TreeStringRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/TreeStringRenderer.java
similarity index 95%
rename from framework/widget/src/org/ofbiz/widget/tree/TreeStringRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/TreeStringRenderer.java
index 63184b7..d56d022 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/TreeStringRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/TreeStringRenderer.java
@@ -1,38 +1,38 @@
-/*******************************************************************************
- * 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.ofbiz.widget.tree;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.ofbiz.widget.screen.ScreenStringRenderer;
-
-/**
- * Widget Library - Tree String Renderer interface
- */
-public interface TreeStringRenderer {
-
-    public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException;
-    public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException;
-    public void renderLabel(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Label label) throws IOException;
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Link link) throws IOException;
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Image image) throws IOException;
-    public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException;
-    public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context);
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.ofbiz.widget.model.ModelTree;
+
+/**
+ * Widget Library - Tree String Renderer interface
+ */
+public interface TreeStringRenderer {
+
+    public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException;
+    public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException;
+    public void renderLabel(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Label label) throws IOException;
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Link link) throws IOException;
+    public void renderImage(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Image image) throws IOException;
+    public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException;
+    public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context);
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/UtilHelpText.java b/framework/widget/src/org/ofbiz/widget/renderer/UtilHelpText.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/form/UtilHelpText.java
rename to framework/widget/src/org/ofbiz/widget/renderer/UtilHelpText.java
index a605bb1..5f88381 100644
--- a/framework/widget/src/org/ofbiz/widget/form/UtilHelpText.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/UtilHelpText.java
@@ -1,87 +1,87 @@
-/*******************************************************************************
- * 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.ofbiz.widget.form;
-
-import java.util.Locale;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.model.ModelEntity;
-import org.ofbiz.entity.model.ModelReader;
-
-/**
- * Util for working with Help Text
- */
-public class UtilHelpText {
-
-    public static final String module = UtilHelpText.class.getName();
-
-    /**
-     * Find the help text associated with an entity field.
-     * 
-     * @param entityName the entity name
-     * @param fieldName the field name
-     * @param delegator the delegator
-     * @param locale the locale
-     * @return the help text, or the resource propertyName if no help text exists
-     */
-    public static String getEntityFieldDescription(final String entityName, final String fieldName, final Delegator delegator, final Locale locale) {
-
-        if (UtilValidate.isEmpty(entityName)) {
-            // Debug.logWarning("entityName [" + entityName + "] is empty", module);
-            return "";
-        }
-        if (UtilValidate.isEmpty(fieldName)) {
-            Debug.logWarning("fieldName [" + fieldName + "] is empty", module);
-            return "";
-        }
-        ModelReader reader = delegator.getModelReader();
-        ModelEntity entity = null;
-        try {
-            if (!reader.getEntityNames().contains(entityName)) {
-                Debug.logWarning("couldn't find entityName [" + entityName + "]", module);
-                return "";
-            }
-            entity = reader.getModelEntity(entityName);
-        } catch (GenericEntityException e) {
-            Debug.logError(e, "Error getting help text for entity=" + entityName + " field " + fieldName, module);
-            return "";
-        }
-        String entityResourceName = entity.getDefaultResourceName();
-        String messageId = "FieldDescription." + entityName + "." + fieldName;
-        String fieldDescription = UtilProperties.getMessage(entityResourceName, messageId, locale);
-        if (fieldDescription.equals(messageId)) {
-            messageId = "FieldDescription." + fieldName;
-            if (Debug.verboseOn()) {
-                Debug.logVerbose("No help text found in [" + entityResourceName + "] with key [" + messageId + "], Trying with: " + messageId, module);
-            }
-            fieldDescription = UtilProperties.getMessage(entityResourceName, messageId, locale);
-            if (fieldDescription.equals(messageId)) {
-                if (Debug.verboseOn()) {
-                    Debug.logVerbose("No help text found in [" + entityResourceName + "] with key [" + messageId + "]", module);
-                }
-                return "";
-            }
-        }
-        return fieldDescription;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer;
+
+import java.util.Locale;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelReader;
+
+/**
+ * Util for working with Help Text
+ */
+public class UtilHelpText {
+
+    public static final String module = UtilHelpText.class.getName();
+
+    /**
+     * Find the help text associated with an entity field.
+     * 
+     * @param entityName the entity name
+     * @param fieldName the field name
+     * @param delegator the delegator
+     * @param locale the locale
+     * @return the help text, or the resource propertyName if no help text exists
+     */
+    public static String getEntityFieldDescription(final String entityName, final String fieldName, final Delegator delegator, final Locale locale) {
+
+        if (UtilValidate.isEmpty(entityName)) {
+            // Debug.logWarning("entityName [" + entityName + "] is empty", module);
+            return "";
+        }
+        if (UtilValidate.isEmpty(fieldName)) {
+            Debug.logWarning("fieldName [" + fieldName + "] is empty", module);
+            return "";
+        }
+        ModelReader reader = delegator.getModelReader();
+        ModelEntity entity = null;
+        try {
+            if (!reader.getEntityNames().contains(entityName)) {
+                Debug.logWarning("couldn't find entityName [" + entityName + "]", module);
+                return "";
+            }
+            entity = reader.getModelEntity(entityName);
+        } catch (GenericEntityException e) {
+            Debug.logError(e, "Error getting help text for entity=" + entityName + " field " + fieldName, module);
+            return "";
+        }
+        String entityResourceName = entity.getDefaultResourceName();
+        String messageId = "FieldDescription." + entityName + "." + fieldName;
+        String fieldDescription = UtilProperties.getMessage(entityResourceName, messageId, locale);
+        if (fieldDescription.equals(messageId)) {
+            messageId = "FieldDescription." + fieldName;
+            if (Debug.verboseOn()) {
+                Debug.logVerbose("No help text found in [" + entityResourceName + "] with key [" + messageId + "], Trying with: " + messageId, module);
+            }
+            fieldDescription = UtilProperties.getMessage(entityResourceName, messageId, locale);
+            if (fieldDescription.equals(messageId)) {
+                if (Debug.verboseOn()) {
+                    Debug.logVerbose("No help text found in [" + entityResourceName + "] with key [" + messageId + "]", module);
+                }
+                return "";
+            }
+        }
+        return fieldDescription;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/fo/FoFormRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
similarity index 92%
rename from framework/widget/src/org/ofbiz/widget/fo/FoFormRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
index 01c78cd..29bc658 100644
--- a/framework/widget/src/org/ofbiz/widget/fo/FoFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/fo/FoFormRenderer.java
@@ -1,427 +1,427 @@
-/*******************************************************************************
- * 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.ofbiz.widget.fo;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.UtilFormatOut;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.FieldInfo;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.ModelFormField;
-import org.ofbiz.widget.form.ModelFormField.CheckField;
-import org.ofbiz.widget.form.ModelFormField.ContainerField;
-import org.ofbiz.widget.form.ModelFormField.DateFindField;
-import org.ofbiz.widget.form.ModelFormField.DateTimeField;
-import org.ofbiz.widget.form.ModelFormField.DisplayField;
-import org.ofbiz.widget.form.ModelFormField.DropDownField;
-import org.ofbiz.widget.form.ModelFormField.FieldInfoWithOptions;
-import org.ofbiz.widget.form.ModelFormField.FileField;
-import org.ofbiz.widget.form.ModelFormField.HiddenField;
-import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
-import org.ofbiz.widget.form.ModelFormField.IgnoredField;
-import org.ofbiz.widget.form.ModelFormField.ImageField;
-import org.ofbiz.widget.form.ModelFormField.LookupField;
-import org.ofbiz.widget.form.ModelFormField.PasswordField;
-import org.ofbiz.widget.form.ModelFormField.RadioField;
-import org.ofbiz.widget.form.ModelFormField.RangeFindField;
-import org.ofbiz.widget.form.ModelFormField.ResetField;
-import org.ofbiz.widget.form.ModelFormField.SubmitField;
-import org.ofbiz.widget.form.ModelFormField.TextField;
-import org.ofbiz.widget.form.ModelFormField.TextFindField;
-import org.ofbiz.widget.form.ModelFormField.TextareaField;
-import org.ofbiz.widget.html.HtmlWidgetRenderer;
-
-
-/**
- * Widget Library - FO Form Renderer implementation
- *
- */
-public class FoFormRenderer extends HtmlWidgetRenderer implements FormStringRenderer {
-
-    public static final String module = FoFormRenderer.class.getName();
-
-    HttpServletRequest request;
-    HttpServletResponse response;
-
-    public FoFormRenderer() {}
-
-    public FoFormRenderer(HttpServletRequest request, HttpServletResponse response) throws IOException {
-        this.request = request;
-        this.response = response;
-    }
-
-    private void makeBlockString(Appendable writer, String widgetStyle, String text) throws IOException {
-        writer.append("<fo:block");
-        if (UtilValidate.isNotEmpty(widgetStyle)) {
-            writer.append(" ");
-            writer.append(FoScreenRenderer.getFoStyle(widgetStyle));
-        }
-        writer.append(">");
-        writer.append(UtilFormatOut.encodeXmlValue(text));
-        writer.append("</fo:block>");
-    }
-
-    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
-        ModelFormField modelFormField = displayField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), displayField.getDescription(context));
-        appendWhitespace(writer);
-    }
-
-    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
-        ModelFormField modelFormField = hyperlinkField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), hyperlinkField.getDescription(context));
-        appendWhitespace(writer);
-    }
-
-    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
-        appendWhitespace(writer);
-    }
-
-    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
-        ModelFormField modelFormField = textareaField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textareaField.getDefaultValue(context)));
-        appendWhitespace(writer);
-    }
-
-    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
-        ModelFormField modelFormField = dateTimeField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateTimeField.getDefaultValue(context)));
-        appendWhitespace(writer);
-    }
-
-    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
-        ModelFormField modelFormField = dropDownField.getModelFormField();
-        String currentValue = modelFormField.getEntry(context);
-        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-        // if the current value should go first, display it
-        if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
-            String explicitDescription = dropDownField.getCurrentDescription(context);
-            if (UtilValidate.isNotEmpty(explicitDescription)) {
-                this.makeBlockString(writer, modelFormField.getWidgetStyle(), explicitDescription);
-            } else {
-                this.makeBlockString(writer, modelFormField.getWidgetStyle(), FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues));
-            }
-        } else {
-            boolean optionSelected = false;
-            for (ModelFormField.OptionValue optionValue : allOptionValues) {
-                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
-                if ((UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) ||
-                        (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey()))) {
-                    this.makeBlockString(writer, modelFormField.getWidgetStyle(), optionValue.getDescription());
-                    optionSelected = true;
-                    break;
-                }
-            }
-            if (!optionSelected) {
-                this.makeBlockString(writer, null, "");
-            }
-        }
-        appendWhitespace(writer);
-    }
-
-    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
-        this.makeBlockString(writer, null, "");
-    }
-
-    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
-        this.makeBlockString(writer, null, "");
-    }
-
-    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
-        this.makeBlockString(writer, null, "");
-    }
-
-    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
-        this.makeBlockString(writer, null, "");
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
-    }
-
-    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) throws IOException {
-    }
-
-    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        String tempTitleText = modelFormField.getTitle(context);
-        writer.append(tempTitleText);
-    }
-
-    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        renderFieldTitle(writer, context, modelFormField);
-    }
-
-    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        renderBeginningBoundaryComment(writer, "Form Widget", modelForm);
-    }
-
-    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        renderEndingBoundaryComment(writer, "Form Widget", modelForm);
-    }
-
-    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        renderEndingBoundaryComment(writer, "Form Widget", modelForm);
-    }
-
-    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<fo:table border=\"solid black\">");
-        List<ModelFormField> childFieldList = modelForm.getFieldList();
-        for (ModelFormField childField : childFieldList) {
-            int childFieldType = childField.getFieldInfo().getFieldType();
-            if (childFieldType == FieldInfo.HIDDEN || childFieldType == FieldInfo.IGNORED) {
-                continue;
-            }
-            writer.append("<fo:table-column");
-            String areaStyle = childField.getTitleAreaStyle();
-            if (UtilValidate.isNotEmpty(areaStyle)) {
-                writer.append(" ");
-                writer.append(FoScreenRenderer.getFoStyle(areaStyle));
-            }
-            writer.append("/>");
-            appendWhitespace(writer);
-        }
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</fo:table-body>");
-        writer.append("</fo:table>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<fo:table-header>");
-        writer.append("<fo:table-row>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</fo:table-row>");
-        writer.append("</fo:table-header>");
-        writer.append("<fo:table-body>");
-        // FIXME: this is an hack to avoid FOP rendering errors for empty lists (fo:table-body cannot be null)
-        writer.append("<fo:table-row><fo:table-cell><fo:block/></fo:table-cell></fo:table-row>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
-        writer.append("<fo:table-cell ");
-        if (positionSpan > 1) {
-            writer.append("number-columns-spanned=\"");
-            writer.append(Integer.toString(positionSpan));
-            writer.append("\" ");
-        }
-        writer.append("font-weight=\"bold\" text-align=\"center\" border=\"solid black\" padding=\"2pt\"");
-        writer.append(">");
-        writer.append("<fo:block>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
-        writer.append("</fo:block>");
-        writer.append("</fo:table-cell>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<fo:table-cell>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</fo:table-cell>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {
-    }
-
-    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<fo:table-row>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</fo:table-row>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
-        writer.append("<fo:table-cell ");
-        if (positionSpan > 1) {
-            writer.append("number-columns-spanned=\"");
-            writer.append(Integer.toString(positionSpan));
-            writer.append("\" ");
-        }
-        String areaStyle = modelFormField.getWidgetAreaStyle();
-        if (UtilValidate.isEmpty(areaStyle)) {
-            areaStyle = "tabletext";
-        }
-        writer.append(FoScreenRenderer.getFoStyle(areaStyle));
-        writer.append(">");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
-        writer.append("</fo:table-cell>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<fo:table-cell>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</fo:table-cell>");
-        appendWhitespace(writer);
-    }
-
-    // TODO: multi columns (position attribute) in single forms are still not implemented
-    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<fo:table>");
-        appendWhitespace(writer);
-        writer.append("<fo:table-column column-width=\"2in\"/>");
-        appendWhitespace(writer);
-        writer.append("<fo:table-column/>");
-        appendWhitespace(writer);
-        writer.append("<fo:table-body>");
-        appendWhitespace(writer);
-    }
-    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</fo:table-body>");
-        writer.append("</fo:table>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<fo:table-row>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</fo:table-row>");
-        appendWhitespace(writer);
-    }
-
-
-    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        writer.append("<fo:table-cell font-weight=\"bold\" text-align=\"right\" padding=\"3pt\">");
-        writer.append("<fo:block>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        writer.append("</fo:block>");
-        writer.append("</fo:table-cell>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-    }
-
-    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
-        writer.append("<fo:table-cell text-align=\"left\" padding=\"2pt\" padding-left=\"5pt\">");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
-        writer.append("</fo:table-cell>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        // TODO
-    }
-
-    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
-        ModelFormField modelFormField = textFindField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textFindField.getDefaultValue(context)));
-        appendWhitespace(writer);
-    }
-
-    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
-        ModelFormField modelFormField = rangeFindField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, rangeFindField.getDefaultValue(context)));
-        appendWhitespace(writer);
-    }
-
-    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
-        ModelFormField modelFormField = dateFindField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateFindField.getDefaultValue(context)));
-        appendWhitespace(writer);
-    }
-
-    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
-        ModelFormField modelFormField = lookupField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, lookupField.getDefaultValue(context)));
-        appendWhitespace(writer);
-    }
-
-    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
-        appendWhitespace(writer);
-    }
-
-    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
-        this.makeBlockString(writer, null, "");
-    }
-
-    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
-        // TODO
-        this.makeBlockString(writer, null, "");
-    }
-
-    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
-        // TODO
-    }
-
-    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
-        // TODO
-    }
-
-    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
-        // TODO
-        this.makeBlockString(writer, null, "");
-    }
-
-    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
-    }
-
-    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.fo;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.FieldInfo;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelFormField;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.html.HtmlWidgetRenderer;
+
+
+/**
+ * Widget Library - FO Form Renderer implementation
+ *
+ */
+public class FoFormRenderer extends HtmlWidgetRenderer implements FormStringRenderer {
+
+    public static final String module = FoFormRenderer.class.getName();
+
+    HttpServletRequest request;
+    HttpServletResponse response;
+
+    public FoFormRenderer() {}
+
+    public FoFormRenderer(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        this.request = request;
+        this.response = response;
+    }
+
+    private void makeBlockString(Appendable writer, String widgetStyle, String text) throws IOException {
+        writer.append("<fo:block");
+        if (UtilValidate.isNotEmpty(widgetStyle)) {
+            writer.append(" ");
+            writer.append(FoScreenRenderer.getFoStyle(widgetStyle));
+        }
+        writer.append(">");
+        writer.append(UtilFormatOut.encodeXmlValue(text));
+        writer.append("</fo:block>");
+    }
+
+    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
+        ModelFormField modelFormField = displayField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), displayField.getDescription(context));
+        appendWhitespace(writer);
+    }
+
+    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
+        ModelFormField modelFormField = hyperlinkField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), hyperlinkField.getDescription(context));
+        appendWhitespace(writer);
+    }
+
+    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
+        appendWhitespace(writer);
+    }
+
+    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
+        ModelFormField modelFormField = textareaField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textareaField.getDefaultValue(context)));
+        appendWhitespace(writer);
+    }
+
+    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
+        ModelFormField modelFormField = dateTimeField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateTimeField.getDefaultValue(context)));
+        appendWhitespace(writer);
+    }
+
+    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
+        ModelFormField modelFormField = dropDownField.getModelFormField();
+        String currentValue = modelFormField.getEntry(context);
+        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+        // if the current value should go first, display it
+        if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
+            String explicitDescription = dropDownField.getCurrentDescription(context);
+            if (UtilValidate.isNotEmpty(explicitDescription)) {
+                this.makeBlockString(writer, modelFormField.getWidgetStyle(), explicitDescription);
+            } else {
+                this.makeBlockString(writer, modelFormField.getWidgetStyle(), FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues));
+            }
+        } else {
+            boolean optionSelected = false;
+            for (ModelFormField.OptionValue optionValue : allOptionValues) {
+                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
+                if ((UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) ||
+                        (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey()))) {
+                    this.makeBlockString(writer, modelFormField.getWidgetStyle(), optionValue.getDescription());
+                    optionSelected = true;
+                    break;
+                }
+            }
+            if (!optionSelected) {
+                this.makeBlockString(writer, null, "");
+            }
+        }
+        appendWhitespace(writer);
+    }
+
+    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
+        this.makeBlockString(writer, null, "");
+    }
+
+    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
+        this.makeBlockString(writer, null, "");
+    }
+
+    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
+        this.makeBlockString(writer, null, "");
+    }
+
+    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
+        this.makeBlockString(writer, null, "");
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
+    }
+
+    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) throws IOException {
+    }
+
+    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        String tempTitleText = modelFormField.getTitle(context);
+        writer.append(tempTitleText);
+    }
+
+    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        renderFieldTitle(writer, context, modelFormField);
+    }
+
+    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+        renderBeginningBoundaryComment(writer, "Form Widget", modelForm);
+    }
+
+    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        renderEndingBoundaryComment(writer, "Form Widget", modelForm);
+    }
+
+    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        renderEndingBoundaryComment(writer, "Form Widget", modelForm);
+    }
+
+    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<fo:table border=\"solid black\">");
+        List<ModelFormField> childFieldList = modelForm.getFieldList();
+        for (ModelFormField childField : childFieldList) {
+            int childFieldType = childField.getFieldInfo().getFieldType();
+            if (childFieldType == FieldInfo.HIDDEN || childFieldType == FieldInfo.IGNORED) {
+                continue;
+            }
+            writer.append("<fo:table-column");
+            String areaStyle = childField.getTitleAreaStyle();
+            if (UtilValidate.isNotEmpty(areaStyle)) {
+                writer.append(" ");
+                writer.append(FoScreenRenderer.getFoStyle(areaStyle));
+            }
+            writer.append("/>");
+            appendWhitespace(writer);
+        }
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</fo:table-body>");
+        writer.append("</fo:table>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<fo:table-header>");
+        writer.append("<fo:table-row>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</fo:table-row>");
+        writer.append("</fo:table-header>");
+        writer.append("<fo:table-body>");
+        // FIXME: this is an hack to avoid FOP rendering errors for empty lists (fo:table-body cannot be null)
+        writer.append("<fo:table-row><fo:table-cell><fo:block/></fo:table-cell></fo:table-row>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
+        writer.append("<fo:table-cell ");
+        if (positionSpan > 1) {
+            writer.append("number-columns-spanned=\"");
+            writer.append(Integer.toString(positionSpan));
+            writer.append("\" ");
+        }
+        writer.append("font-weight=\"bold\" text-align=\"center\" border=\"solid black\" padding=\"2pt\"");
+        writer.append(">");
+        writer.append("<fo:block>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
+        writer.append("</fo:block>");
+        writer.append("</fo:table-cell>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<fo:table-cell>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</fo:table-cell>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {
+    }
+
+    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<fo:table-row>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</fo:table-row>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
+        writer.append("<fo:table-cell ");
+        if (positionSpan > 1) {
+            writer.append("number-columns-spanned=\"");
+            writer.append(Integer.toString(positionSpan));
+            writer.append("\" ");
+        }
+        String areaStyle = modelFormField.getWidgetAreaStyle();
+        if (UtilValidate.isEmpty(areaStyle)) {
+            areaStyle = "tabletext";
+        }
+        writer.append(FoScreenRenderer.getFoStyle(areaStyle));
+        writer.append(">");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
+        writer.append("</fo:table-cell>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<fo:table-cell>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</fo:table-cell>");
+        appendWhitespace(writer);
+    }
+
+    // TODO: multi columns (position attribute) in single forms are still not implemented
+    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<fo:table>");
+        appendWhitespace(writer);
+        writer.append("<fo:table-column column-width=\"2in\"/>");
+        appendWhitespace(writer);
+        writer.append("<fo:table-column/>");
+        appendWhitespace(writer);
+        writer.append("<fo:table-body>");
+        appendWhitespace(writer);
+    }
+    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</fo:table-body>");
+        writer.append("</fo:table>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<fo:table-row>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</fo:table-row>");
+        appendWhitespace(writer);
+    }
+
+
+    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        writer.append("<fo:table-cell font-weight=\"bold\" text-align=\"right\" padding=\"3pt\">");
+        writer.append("<fo:block>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        writer.append("</fo:block>");
+        writer.append("</fo:table-cell>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+    }
+
+    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
+        writer.append("<fo:table-cell text-align=\"left\" padding=\"2pt\" padding-left=\"5pt\">");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
+        writer.append("</fo:table-cell>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        // TODO
+    }
+
+    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
+        ModelFormField modelFormField = textFindField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textFindField.getDefaultValue(context)));
+        appendWhitespace(writer);
+    }
+
+    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
+        ModelFormField modelFormField = rangeFindField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, rangeFindField.getDefaultValue(context)));
+        appendWhitespace(writer);
+    }
+
+    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
+        ModelFormField modelFormField = dateFindField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateFindField.getDefaultValue(context)));
+        appendWhitespace(writer);
+    }
+
+    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
+        ModelFormField modelFormField = lookupField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, lookupField.getDefaultValue(context)));
+        appendWhitespace(writer);
+    }
+
+    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+        this.makeBlockString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
+        appendWhitespace(writer);
+    }
+
+    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
+        this.makeBlockString(writer, null, "");
+    }
+
+    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
+        // TODO
+        this.makeBlockString(writer, null, "");
+    }
+
+    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
+        // TODO
+    }
+
+    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
+        // TODO
+    }
+
+    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
+        // TODO
+        this.makeBlockString(writer, null, "");
+    }
+
+    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
+    }
+
+    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/fo/FoScreenRenderer.java
similarity index 96%
rename from framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/fo/FoScreenRenderer.java
index 882e013..3ffa1c9 100644
--- a/framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/fo/FoScreenRenderer.java
@@ -1,195 +1,195 @@
-/*******************************************************************************
- * 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.ofbiz.widget.fo;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.html.HtmlWidgetRenderer;
-import org.ofbiz.widget.screen.ModelScreenWidget;
-import org.ofbiz.widget.screen.ScreenStringRenderer;
-import org.ofbiz.widget.screen.ModelScreenWidget.ColumnContainer;
-import org.ofbiz.entity.GenericValue;
-
-/**
- * Widget Library - HTML Form Renderer implementation
- * @deprecated Use MacroScreenRenderer.
- */
-public class FoScreenRenderer extends HtmlWidgetRenderer implements ScreenStringRenderer {
-
-    public static final String module = FoScreenRenderer.class.getName();
-
-    public FoScreenRenderer() {}
-
-    // This is a util method to get the style from a property file
-    public static String getFoStyle(String styleName) {
-        String value = UtilProperties.getPropertyValue("fo-styles.properties", styleName);
-        if (value.equals(styleName)) {
-            return "";
-        }
-        return value;
-    }
-
-    public String getRendererName() {
-        return "xsl-fo";
-    }
-
-    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException {
-    }
-
-    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException {
-
-    }
-
-    public void renderSectionBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
-        if (section.isMainSection()) {
-            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        }
-        renderBeginningBoundaryComment(writer, section.isMainSection()?"Screen":"Section Widget", section);
-    }
-    public void renderSectionEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
-        renderEndingBoundaryComment(writer, section.isMainSection()?"Screen":"Section Widget", section);
-    }
-
-    public void renderContainerBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
-        writer.append("<fo:block");
-
-        String style = container.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append(" ");
-            writer.append(FoScreenRenderer.getFoStyle(style));
-        }
-        writer.append(">");
-        appendWhitespace(writer);
-    }
-    public void renderContainerEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
-        writer.append("</fo:block>");
-        appendWhitespace(writer);
-    }
-
-    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException {
-        String labelText = label.getText(context);
-        if (UtilValidate.isEmpty(labelText)) {
-            // nothing to render
-            return;
-        }
-        // open tag
-        String style = label.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append("<fo:inline ");
-            writer.append(FoScreenRenderer.getFoStyle(style));
-            writer.append(">");
-            // the text
-            writer.append(labelText);
-            // close tag
-            writer.append("</fo:inline>");
-        } else {
-            writer.append(labelText);
-        }
-        appendWhitespace(writer);
-    }
-
-    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.HorizontalSeparator separator) throws IOException {
-        writer.append("<fo:block>");
-        appendWhitespace(writer);
-        writer.append("<fo:leader leader-length=\"100%\" leader-pattern=\"rule\" rule-style=\"solid\" rule-thickness=\"0.1mm\" color=\"black\"/>");
-        appendWhitespace(writer);
-        writer.append("</fo:block>");
-        appendWhitespace(writer);
-    }
-
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenLink link) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenImage image) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderContentFrame(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderSubContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, ModelScreenWidget.Screenlet screenlet) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, ModelScreenWidget.Screenlet screenlet) throws GeneralException {
-        // TODO: not implemented
-    }
-
-    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Screenlet screenlet) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-
-    @Override
-    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ColumnContainer columnContainer) throws IOException {
-        // TODO: not implemented
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.fo;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.widget.model.ModelScreenWidget;
+import org.ofbiz.widget.model.ModelScreenWidget.ColumnContainer;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.html.HtmlWidgetRenderer;
+
+/**
+ * Widget Library - HTML Form Renderer implementation
+ * @deprecated Use MacroScreenRenderer.
+ */
+public class FoScreenRenderer extends HtmlWidgetRenderer implements ScreenStringRenderer {
+
+    public static final String module = FoScreenRenderer.class.getName();
+
+    public FoScreenRenderer() {}
+
+    // This is a util method to get the style from a property file
+    public static String getFoStyle(String styleName) {
+        String value = UtilProperties.getPropertyValue("fo-styles.properties", styleName);
+        if (value.equals(styleName)) {
+            return "";
+        }
+        return value;
+    }
+
+    public String getRendererName() {
+        return "xsl-fo";
+    }
+
+    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException {
+    }
+
+    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException {
+
+    }
+
+    public void renderSectionBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
+        if (section.isMainSection()) {
+            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+        }
+        renderBeginningBoundaryComment(writer, section.isMainSection()?"Screen":"Section Widget", section);
+    }
+    public void renderSectionEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
+        renderEndingBoundaryComment(writer, section.isMainSection()?"Screen":"Section Widget", section);
+    }
+
+    public void renderContainerBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
+        writer.append("<fo:block");
+
+        String style = container.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append(" ");
+            writer.append(FoScreenRenderer.getFoStyle(style));
+        }
+        writer.append(">");
+        appendWhitespace(writer);
+    }
+    public void renderContainerEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
+        writer.append("</fo:block>");
+        appendWhitespace(writer);
+    }
+
+    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException {
+        String labelText = label.getText(context);
+        if (UtilValidate.isEmpty(labelText)) {
+            // nothing to render
+            return;
+        }
+        // open tag
+        String style = label.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append("<fo:inline ");
+            writer.append(FoScreenRenderer.getFoStyle(style));
+            writer.append(">");
+            // the text
+            writer.append(labelText);
+            // close tag
+            writer.append("</fo:inline>");
+        } else {
+            writer.append(labelText);
+        }
+        appendWhitespace(writer);
+    }
+
+    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.HorizontalSeparator separator) throws IOException {
+        writer.append("<fo:block>");
+        appendWhitespace(writer);
+        writer.append("<fo:leader leader-length=\"100%\" leader-pattern=\"rule\" rule-style=\"solid\" rule-thickness=\"0.1mm\" color=\"black\"/>");
+        appendWhitespace(writer);
+        writer.append("</fo:block>");
+        appendWhitespace(writer);
+    }
+
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenLink link) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenImage image) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderContentFrame(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderSubContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, ModelScreenWidget.Screenlet screenlet) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, ModelScreenWidget.Screenlet screenlet) throws GeneralException {
+        // TODO: not implemented
+    }
+
+    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Screenlet screenlet) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+
+    @Override
+    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ColumnContainer columnContainer) throws IOException {
+        // TODO: not implemented
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java b/framework/widget/src/org/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
similarity index 94%
rename from framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
rename to framework/widget/src/org/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
index c76018c..ff649d0 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ScreenFopViewHandler.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/fo/ScreenFopViewHandler.java
@@ -1,141 +1,144 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.transform.stream.StreamSource;
-
-import org.apache.fop.apps.Fop;
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.util.EntityUtilProperties;
-import org.ofbiz.webapp.view.AbstractViewHandler;
-import org.ofbiz.webapp.view.ApacheFopWorker;
-import org.ofbiz.webapp.view.ViewHandlerException;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.MacroFormRenderer;
-import org.ofbiz.widget.html.HtmlScreenRenderer;
-
-/**
- * Uses XSL-FO formatted templates to generate PDF, PCL, POSTSCRIPT etc.  views
- * This handler will use JPublish to generate the XSL-FO
- */
-public class ScreenFopViewHandler extends AbstractViewHandler {
-    public static final String module = ScreenFopViewHandler.class.getName();
-    protected static final String DEFAULT_ERROR_TEMPLATE = "component://common/widget/CommonScreens.xml#FoError";
-
-    protected ServletContext servletContext = null;
-
-    /**
-     * @see org.ofbiz.webapp.view.ViewHandler#init(javax.servlet.ServletContext)
-     */
-    @Override
-    public void init(ServletContext context) throws ViewHandlerException {
-        this.servletContext = context;
-    }
-
-    /**
-     * @see org.ofbiz.webapp.view.ViewHandler#render(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
-     */
-    @Override
-    public void render(String name, String page, String info, String contentType, String encoding, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
-
-        Delegator delegator = (Delegator) request.getAttribute("delegator");
-        // render and obtain the XSL-FO
-        Writer writer = new StringWriter();
-        try {
-            ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(EntityUtilProperties.getPropertyValue("widget", getName() + ".name", delegator), EntityUtilProperties.getPropertyValue("widget", getName() + ".screenrenderer", delegator));
-            FormStringRenderer formStringRenderer = new MacroFormRenderer(EntityUtilProperties.getPropertyValue("widget", getName() + ".formrenderer", delegator), request, response);
-            // TODO: uncomment these lines when the renderers are implemented
-            //TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(UtilProperties.getPropertyValue("widget", getName() + ".treerenderer"), writer);
-            //MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(UtilProperties.getPropertyValue("widget", getName() + ".menurenderer"), writer);
-            ScreenRenderer screens = new ScreenRenderer(writer, null, screenStringRenderer);
-            screens.populateContextForRequest(request, response, servletContext);
-
-            // this is the object used to render forms from their definitions
-            screens.getContext().put("formStringRenderer", formStringRenderer);
-            screens.getContext().put("simpleEncoder", UtilCodec.getEncoder(EntityUtilProperties.getPropertyValue("widget", getName() + ".encoder", delegator)));
-            screens.render(page);
-        } catch (Exception e) {
-            renderError("Problems with the response writer/output stream", e, "[Not Yet Rendered]", request, response);
-            return;
-        }
-
-        // set the input source (XSL-FO) and generate the output stream of contentType
-        String screenOutString = writer.toString();
-        if (!screenOutString.startsWith("<?xml")) {
-            screenOutString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + screenOutString;
-        }
-        if (Debug.verboseOn()) Debug.logVerbose("XSL:FO Screen Output: " + screenOutString, module);
-
-        if (UtilValidate.isEmpty(contentType)) {
-            contentType = UtilProperties.getPropertyValue("widget", getName() + ".default.contenttype");
-        }
-        Reader reader = new StringReader(screenOutString);
-        StreamSource src = new StreamSource(reader);
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        try {
-            Fop fop = ApacheFopWorker.createFopInstance(out, contentType);
-            ApacheFopWorker.transform(src, null, fop);
-        } catch (Exception e) {
-            renderError("Unable to transform FO file", e, screenOutString, request, response);
-            return;
-        }
-        // set the content type and length
-        response.setContentType(contentType);
-        response.setContentLength(out.size());
-
-        // write to the browser
-        try {
-            out.writeTo(response.getOutputStream());
-            response.getOutputStream().flush();
-        } catch (IOException e) {
-            renderError("Unable to write to OutputStream", e, screenOutString, request, response);
-        }
-    }
-
-    protected void renderError(String msg, Exception e, String screenOutString, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
-        Debug.logError(msg + ": " + e + "; Screen XSL:FO text was:\n" + screenOutString, module);
-        try {
-            Writer writer = new StringWriter();
-            ScreenRenderer screens = new ScreenRenderer(writer, null, new HtmlScreenRenderer());
-            screens.populateContextForRequest(request, response, servletContext);
-            screens.getContext().put("errorMessage", msg + ": " + e);
-            screens.render(DEFAULT_ERROR_TEMPLATE);
-            response.setContentType("text/html");
-            response.getWriter().write(writer.toString());
-            writer.close();
-        } catch (Exception x) {
-            Debug.logError("Multiple errors rendering FOP", module);
-            throw new ViewHandlerException("Multiple errors rendering FOP", x);
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.fo;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.fop.apps.Fop;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.util.EntityUtilProperties;
+import org.ofbiz.webapp.view.AbstractViewHandler;
+import org.ofbiz.webapp.view.ApacheFopWorker;
+import org.ofbiz.webapp.view.ViewHandlerException;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.html.HtmlScreenRenderer;
+import org.ofbiz.widget.renderer.macro.MacroFormRenderer;
+import org.ofbiz.widget.renderer.macro.MacroScreenRenderer;
+
+/**
+ * Uses XSL-FO formatted templates to generate PDF, PCL, POSTSCRIPT etc.  views
+ * This handler will use JPublish to generate the XSL-FO
+ */
+public class ScreenFopViewHandler extends AbstractViewHandler {
+    public static final String module = ScreenFopViewHandler.class.getName();
+    protected static final String DEFAULT_ERROR_TEMPLATE = "component://common/widget/CommonScreens.xml#FoError";
+
+    protected ServletContext servletContext = null;
+
+    /**
+     * @see org.ofbiz.webapp.view.ViewHandler#init(javax.servlet.ServletContext)
+     */
+    @Override
+    public void init(ServletContext context) throws ViewHandlerException {
+        this.servletContext = context;
+    }
+
+    /**
+     * @see org.ofbiz.webapp.view.ViewHandler#render(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    @Override
+    public void render(String name, String page, String info, String contentType, String encoding, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
+
+        Delegator delegator = (Delegator) request.getAttribute("delegator");
+        // render and obtain the XSL-FO
+        Writer writer = new StringWriter();
+        try {
+            ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(EntityUtilProperties.getPropertyValue("widget", getName() + ".name", delegator), EntityUtilProperties.getPropertyValue("widget", getName() + ".screenrenderer", delegator));
+            FormStringRenderer formStringRenderer = new MacroFormRenderer(EntityUtilProperties.getPropertyValue("widget", getName() + ".formrenderer", delegator), request, response);
+            // TODO: uncomment these lines when the renderers are implemented
+            //TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(UtilProperties.getPropertyValue("widget", getName() + ".treerenderer"), writer);
+            //MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(UtilProperties.getPropertyValue("widget", getName() + ".menurenderer"), writer);
+            ScreenRenderer screens = new ScreenRenderer(writer, null, screenStringRenderer);
+            screens.populateContextForRequest(request, response, servletContext);
+
+            // this is the object used to render forms from their definitions
+            screens.getContext().put("formStringRenderer", formStringRenderer);
+            screens.getContext().put("simpleEncoder", UtilCodec.getEncoder(EntityUtilProperties.getPropertyValue("widget", getName() + ".encoder", delegator)));
+            screens.render(page);
+        } catch (Exception e) {
+            renderError("Problems with the response writer/output stream", e, "[Not Yet Rendered]", request, response);
+            return;
+        }
+
+        // set the input source (XSL-FO) and generate the output stream of contentType
+        String screenOutString = writer.toString();
+        if (!screenOutString.startsWith("<?xml")) {
+            screenOutString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + screenOutString;
+        }
+        if (Debug.verboseOn()) Debug.logVerbose("XSL:FO Screen Output: " + screenOutString, module);
+
+        if (UtilValidate.isEmpty(contentType)) {
+            contentType = UtilProperties.getPropertyValue("widget", getName() + ".default.contenttype");
+        }
+        Reader reader = new StringReader(screenOutString);
+        StreamSource src = new StreamSource(reader);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        try {
+            Fop fop = ApacheFopWorker.createFopInstance(out, contentType);
+            ApacheFopWorker.transform(src, null, fop);
+        } catch (Exception e) {
+            renderError("Unable to transform FO file", e, screenOutString, request, response);
+            return;
+        }
+        // set the content type and length
+        response.setContentType(contentType);
+        response.setContentLength(out.size());
+
+        // write to the browser
+        try {
+            out.writeTo(response.getOutputStream());
+            response.getOutputStream().flush();
+        } catch (IOException e) {
+            renderError("Unable to write to OutputStream", e, screenOutString, request, response);
+        }
+    }
+
+    protected void renderError(String msg, Exception e, String screenOutString, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
+        Debug.logError(msg + ": " + e + "; Screen XSL:FO text was:\n" + screenOutString, module);
+        try {
+            Writer writer = new StringWriter();
+            ScreenRenderer screens = new ScreenRenderer(writer, null, new HtmlScreenRenderer());
+            screens.populateContextForRequest(request, response, servletContext);
+            screens.getContext().put("errorMessage", msg + ": " + e);
+            screens.render(DEFAULT_ERROR_TEMPLATE);
+            response.setContentType("text/html");
+            response.getWriter().write(writer.toString());
+            writer.close();
+        } catch (Exception x) {
+            Debug.logError("Multiple errors rendering FOP", module);
+            throw new ViewHandlerException("Multiple errors rendering FOP", x);
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
similarity index 96%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
index 526da1c..18998c3 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
@@ -1,2823 +1,2823 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.base.util.template.FreeMarkerWorker;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.CommonWidgetModels;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.FormRenderer;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.MacroFormRenderer;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.ModelFormField;
-import org.ofbiz.widget.form.ModelFormField.CheckField;
-import org.ofbiz.widget.form.ModelFormField.ContainerField;
-import org.ofbiz.widget.form.ModelFormField.DateFindField;
-import org.ofbiz.widget.form.ModelFormField.DateTimeField;
-import org.ofbiz.widget.form.ModelFormField.DisplayEntityField;
-import org.ofbiz.widget.form.ModelFormField.DisplayField;
-import org.ofbiz.widget.form.ModelFormField.DropDownField;
-import org.ofbiz.widget.form.ModelFormField.FieldInfoWithOptions;
-import org.ofbiz.widget.form.ModelFormField.FileField;
-import org.ofbiz.widget.form.ModelFormField.HiddenField;
-import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
-import org.ofbiz.widget.form.ModelFormField.IgnoredField;
-import org.ofbiz.widget.form.ModelFormField.ImageField;
-import org.ofbiz.widget.form.ModelFormField.LookupField;
-import org.ofbiz.widget.form.ModelFormField.PasswordField;
-import org.ofbiz.widget.form.ModelFormField.RadioField;
-import org.ofbiz.widget.form.ModelFormField.RangeFindField;
-import org.ofbiz.widget.form.ModelFormField.ResetField;
-import org.ofbiz.widget.form.ModelFormField.SubmitField;
-import org.ofbiz.widget.form.ModelFormField.TextField;
-import org.ofbiz.widget.form.ModelFormField.TextFindField;
-import org.ofbiz.widget.form.ModelFormField.TextareaField;
-import org.ofbiz.widget.form.Paginator;
-import org.ofbiz.widget.form.UtilHelpText;
-
-import freemarker.template.TemplateException;
-
-/**
- * Widget Library - HTML Form Renderer implementation
- */
-public class HtmlFormRenderer extends HtmlWidgetRenderer implements FormStringRenderer {
-
-    public static final String module = HtmlFormRenderer.class.getName();
-
-    protected HttpServletRequest request;
-    protected HttpServletResponse response;
-    protected RequestHandler rh;
-    protected String lastFieldGroupId = "";
-    protected boolean renderPagination = true;
-    protected boolean javaScriptEnabled = false;
-    private UtilCodec.SimpleEncoder internalEncoder;
-
-    protected HtmlFormRenderer() {}
-
-    public HtmlFormRenderer(HttpServletRequest request, HttpServletResponse response) {
-        this.request = request;
-        this.response = response;
-        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-        this.rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-        this.javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
-        internalEncoder = UtilCodec.getEncoder("string");
-    }
-
-    public boolean getRenderPagination() {
-        return this.renderPagination;
-    }
-
-    public void setRenderPagination(boolean renderPagination) {
-        this.renderPagination = renderPagination;
-    }
-
-    public void appendOfbizUrl(Appendable writer, String location) throws IOException {
-        writer.append(this.rh.makeLink(this.request, this.response, location));
-    }
-
-    public void appendContentUrl(Appendable writer, String location) throws IOException {
-        ContentUrlTag.appendContentPrefix(this.request, writer);
-        writer.append(location);
-    }
-
-    public void appendTooltip(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        // render the tooltip, in other methods too
-        String tooltip = modelFormField.getTooltip(context);
-        if (UtilValidate.isNotEmpty(tooltip)) {
-            writer.append("<span class=\"");
-            String tooltipStyle = modelFormField.getTooltipStyle();
-            if (UtilValidate.isNotEmpty(tooltipStyle)) {
-                writer.append(tooltipStyle);
-            } else {
-                writer.append("tooltip");
-            }
-            writer.append("\">");
-            writer.append(tooltip);
-            writer.append("</span>");
-        }
-    }
-
-    public void addAsterisks(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-
-        boolean requiredField = modelFormField.getRequiredField();
-        if (requiredField) {
-            String requiredStyle = modelFormField.getRequiredFieldStyle();
-
-            if (UtilValidate.isEmpty(requiredStyle)) {
-               writer.append("*");
-            }
-        }
-    }
-
-    public void appendClassNames(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        String className = modelFormField.getWidgetStyle();
-        if (UtilValidate.isNotEmpty(className) || modelFormField.shouldBeRed(context)) {
-            writer.append(" class=\"");
-            writer.append(className);
-            // add a style of red if redWhen is true
-            if (modelFormField.shouldBeRed(context)) {
-                writer.append(" alert");
-            }
-            writer.append('"');
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderDisplayField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.DisplayField)
-     */
-    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
-        ModelFormField modelFormField = displayField.getModelFormField();
-
-        StringBuilder str = new StringBuilder();
-
-        String idName = modelFormField.getCurrentContainerId(context);
-
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle()) || modelFormField.shouldBeRed(context)) {
-            str.append("<span class=\"");
-            str.append(modelFormField.getWidgetStyle());
-            // add a style of red if this is a date/time field and redWhen is true
-            if (modelFormField.shouldBeRed(context)) {
-                str.append(" alert");
-            }
-            str.append('"');
-            if (UtilValidate.isNotEmpty(idName)) {
-                str.append(" id=\"");
-                str.append(idName+"_sp");
-                str.append('"');
-            }
-            str.append('>');
-        }
-
-        if (str.length() > 0) {
-            writer.append(str.toString());
-        }
-        String description = displayField.getDescription(context);
-        //Replace new lines with <br/>
-        description = description.replaceAll("\n", "<br/>");
-
-        if (UtilValidate.isEmpty(description)) {
-            this.renderFormatEmptySpace(writer, context, modelFormField.getModelForm());
-        } else {
-            writer.append(description);
-        }
-
-        if (str.length() > 0) {
-            writer.append("</span>");
-        }
-
-        ModelFormField.InPlaceEditor inPlaceEditor = displayField.getInPlaceEditor();
-        boolean ajaxEnabled = inPlaceEditor != null && this.javaScriptEnabled;
-
-        if (ajaxEnabled) {
-            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
-            StringBuilder url = new StringBuilder(inPlaceEditor.getUrl(context));
-            Map<String, Object> fieldMap = inPlaceEditor.getFieldMap(context);
-            if (fieldMap != null) {
-                url.append('?');
-                int count = 0;
-                for (Entry<String, Object> field: fieldMap.entrySet()) {
-                    count++;
-                    url.append(field.getKey()).append('=').append(field.getValue());
-                    if (count < fieldMap.size()) {
-                        url.append('&');
-                    }
-                }
-            }
-            writer.append("ajaxInPlaceEditDisplayField('");
-            writer.append(idName).append("', '").append(url).append("', {");
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getParamName())) {
-                writer.append("name: '").append(inPlaceEditor.getParamName()).append("'");
-            } else {
-                writer.append("name: '").append(modelFormField.getFieldName()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelControl())) {
-                writer.append(", cancelControl: ");
-                if (!"false".equals(inPlaceEditor.getCancelControl())) {
-                    writer.append("'");
-                }
-                writer.append(inPlaceEditor.getCancelControl());
-                if (!"false".equals(inPlaceEditor.getCancelControl())) {
-                    writer.append("'");
-                }
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelText())) {
-                writer.append(", cancel: '").append(inPlaceEditor.getCancelText()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getClickToEditText())) {
-                writer.append(", tooltip: '").append(inPlaceEditor.getClickToEditText()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getFieldPostCreation())) {
-                writer.append(", fieldPostCreation: ");
-                if (!"false".equals(inPlaceEditor.getFieldPostCreation())) {
-                    writer.append("'");
-                }
-                writer.append(inPlaceEditor.getFieldPostCreation());
-                if (!"false".equals(inPlaceEditor.getFieldPostCreation())) {
-                    writer.append("'");
-                }
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getFormClassName())) {
-                writer.append(", cssclass: '").append(inPlaceEditor.getFormClassName()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getHighlightColor())) {
-                writer.append(", highlightColor: '").append(inPlaceEditor.getHighlightColor()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getHighlightEndColor())) {
-                writer.append(", highlightEndColor: '").append(inPlaceEditor.getHighlightEndColor()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getHoverClassName())) {
-                writer.append(", hoverClassName: '").append(inPlaceEditor.getHoverClassName()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getHtmlResponse())) {
-                writer.append(", htmlResponse: ").append(inPlaceEditor.getHtmlResponse());
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingClassName())) {
-                writer.append(", loadingClassName: '").append(inPlaceEditor.getLoadingClassName()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingText())) {
-                writer.append(", indicator: '").append(inPlaceEditor.getLoadingText()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getOkControl())) {
-                writer.append(", submit: ");
-                if (!"false".equals(inPlaceEditor.getOkControl())) {
-                    writer.append("'");
-                }
-                writer.append(inPlaceEditor.getOkControl());
-                if (!"false".equals(inPlaceEditor.getOkControl())) {
-                    writer.append("'");
-                }
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getOkText())) {
-                writer.append(", okText: '").append(inPlaceEditor.getOkText()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getSavingClassName())) {
-                writer.append(", savingClassName: '").append(inPlaceEditor.getSavingClassName()).append("', ");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getSavingText())) {
-                writer.append(", savingText: '").append(inPlaceEditor.getSavingText()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getSubmitOnBlur())) {
-                writer.append(", submitOnBlur: ").append(inPlaceEditor.getSubmitOnBlur());
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextBeforeControls())) {
-                writer.append(", textBeforeControls: '").append(inPlaceEditor.getTextBeforeControls()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextAfterControls())) {
-                writer.append(", textAfterControls: '").append(inPlaceEditor.getTextAfterControls()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextBetweenControls())) {
-                writer.append(", textBetweenControls: '").append(inPlaceEditor.getTextBetweenControls()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getUpdateAfterRequestCall())) {
-                writer.append(", updateAfterRequestCall: ").append(inPlaceEditor.getUpdateAfterRequestCall());
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getRows())) {
-                writer.append(", rows: '").append(inPlaceEditor.getRows()).append("'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getCols())) {
-                writer.append(", cols: '").append(inPlaceEditor.getCols()).append("'");
-            }
-            writer.append("});");
-            writer.append("</script>");
-        }
-
-        if (displayField instanceof DisplayEntityField) {
-            this.makeHyperlinkString(writer, ((DisplayEntityField) displayField).getSubHyperlink(), context);
-        }
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderHyperlinkField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.HyperlinkField)
-     */
-    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
-        this.request.setAttribute("image", hyperlinkField.getImageLocation(context));
-        ModelFormField modelFormField = hyperlinkField.getModelFormField();
-        String description = encode(hyperlinkField.getDescription(context), modelFormField, context);
-        String confirmation = encode(hyperlinkField.getConfirmation(context), modelFormField, context);
-        WidgetWorker.makeHyperlinkByType(writer, hyperlinkField.getLinkType(), modelFormField.getWidgetStyle(), hyperlinkField.getUrlMode(), hyperlinkField.getTarget(context),
-                hyperlinkField.getParameterMap(context), description, hyperlinkField.getTargetWindow(context), confirmation, modelFormField,
-                this.request, this.response, context);
-        this.appendTooltip(writer, context, modelFormField);
-        //appendWhitespace(writer);
-    }
-
-    public void makeHyperlinkString(Appendable writer, ModelFormField.SubHyperlink subHyperlink, Map<String, Object> context) throws IOException {
-        if (subHyperlink == null) {
-            return;
-        }
-        if (subHyperlink.shouldUse(context)) {
-            writer.append(' ');
-            String description = encode(subHyperlink.getDescription(context), subHyperlink.getModelFormField(), context);
-            WidgetWorker.makeHyperlinkByType(writer, subHyperlink.getLinkType(), subHyperlink.getStyle(context), subHyperlink.getUrlMode(), subHyperlink.getTarget(context),
-                    subHyperlink.getParameterMap(context), description, subHyperlink.getTargetWindow(context), null, subHyperlink.getModelFormField(),
-                    this.request, this.response, context);
-        }
-    }
-
-    private String encode(String value, ModelFormField modelFormField, Map<String, Object> context) {
-        if (UtilValidate.isEmpty(value)) {
-            return value;
-        }
-        UtilCodec.SimpleEncoder encoder = (UtilCodec.SimpleEncoder)context.get("simpleEncoder");
-        if (modelFormField.getEncodeOutput() && encoder != null) {
-            value = encoder.encode(value);
-        } else {
-            value = internalEncoder.encode(value);
-        }
-        return value;
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.TextField)
-     */
-    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-
-        writer.append("<input type=\"text\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append('"');
-
-        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(textField.getSize()));
-        writer.append('"');
-
-        Integer maxlength = textField.getMaxlength();
-        if (maxlength != null) {
-            writer.append(" maxlength=\"");
-            writer.append(maxlength.toString());
-            writer.append('"');
-        }
-
-        String idName = modelFormField.getCurrentContainerId(context);
-        if (UtilValidate.isNotEmpty(idName)) {
-            writer.append(" id=\"");
-            writer.append(idName);
-            writer.append('"');
-        }
-
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
-            writer.append(" ");
-            writer.append(event);
-            writer.append("=\"");
-            writer.append(action);
-            writer.append('"');
-        }
-
-        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
-        boolean ajaxEnabled = updateAreas != null && this.javaScriptEnabled;
-        if (!textField.getClientAutocompleteField() || ajaxEnabled) {
-            writer.append(" autocomplete=\"off\"");
-        }
-
-        writer.append("/>");
-
-        this.addAsterisks(writer, context, modelFormField);
-
-        this.makeHyperlinkString(writer, textField.getSubHyperlink(), context);
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        if (ajaxEnabled) {
-            appendWhitespace(writer);
-            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
-            appendWhitespace(writer);
-            writer.append("ajaxAutoCompleter('").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context)).append("');");
-            appendWhitespace(writer);
-            writer.append("</script>");
-        }
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextareaField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.TextareaField)
-     */
-    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
-        ModelFormField modelFormField = textareaField.getModelFormField();
-
-        writer.append("<textarea");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append('"');
-
-        writer.append(" cols=\"");
-        writer.append(Integer.toString(textareaField.getCols()));
-        writer.append('"');
-
-        writer.append(" rows=\"");
-        writer.append(Integer.toString(textareaField.getRows()));
-        writer.append('"');
-
-        String idName = modelFormField.getCurrentContainerId(context);
-        if (UtilValidate.isNotEmpty(idName)) {
-            writer.append(" id=\"");
-            writer.append(idName);
-            writer.append('"');
-        } else if (textareaField.getVisualEditorEnable()) {
-            writer.append(" id=\"");
-            writer.append("htmlEditArea");
-            writer.append('"');
-        }
-
-        if (textareaField.isReadOnly()) {
-            writer.append(" readonly");
-        }
-
-        writer.append('>');
-
-        String value = modelFormField.getEntry(context, textareaField.getDefaultValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(value);
-        }
-
-        writer.append("</textarea>");
-
-        if (textareaField.getVisualEditorEnable()) {
-            writer.append("<script language=\"javascript\" src=\"/images/jquery/plugins/elrte-1.3/js/elrte.min.js\" type=\"text/javascript\"></script>");
-            writer.append("<link href=\"/images/jquery/plugins/elrte-1.3/css/elrte.min.css\" rel=\"stylesheet\" type=\"text/css\">");
-            writer.append("<script language=\"javascript\" type=\"text/javascript\"> var opts = { cssClass : 'el-rte', toolbar : ");
-            // define the toolsbar
-            String buttons = textareaField.getVisualEditorButtons(context);
-            if (UtilValidate.isNotEmpty(buttons)) {
-                writer.append(buttons);
-            } else {
-                writer.append("maxi");
-            }
-            writer.append(", doctype  : '<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">', //'<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\">'");
-            writer.append(", cssfiles : ['/images/jquery/plugins/elrte-1.3/css/elrte-inner.css'] ");
-            writer.append("}");
-            // load the wysiwyg editor
-            writer.append("jQuery('#");
-            if (UtilValidate.isNotEmpty(idName)) {
-                writer.append(idName);
-            } else {
-                writer.append("htmlEditArea");
-            }
-            writer.append("').elrte(opts);");
-            writer.append("</script>");
-        }
-
-        this.addAsterisks(writer, context, modelFormField);
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderDateTimeField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.DateTimeField)
-     */
-    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
-        String macroLibraryPath = UtilProperties.getPropertyValue("widget", "screen.formrenderer");
-        try {
-            MacroFormRenderer macroFormRenderer = new MacroFormRenderer(macroLibraryPath, this.request, this.response);
-            macroFormRenderer.renderDateTimeField(writer, context, dateTimeField);
-        } catch (TemplateException e) {
-            Debug.logError(e, "Error rendering screen thru ftl macro: renderDateTimeField", module);
-        } catch (IOException e) {
-            Debug.logError(e, "Error rendering screen thru ftl, macro: renderDateTimeField", module);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderDropDownField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.DropDownField)
-     */
-    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
-        ModelFormField modelFormField = dropDownField.getModelFormField();
-        ModelForm modelForm = modelFormField.getModelForm();
-        ModelFormField.AutoComplete autoComplete = dropDownField.getAutoComplete();
-        boolean ajaxEnabled = autoComplete != null && this.javaScriptEnabled;
-        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-
-        String currentValue = modelFormField.getEntry(context);
-        // Get the current value's description from the option value. If there
-        // is a localized version it will be there.
-        String currentDescription = null;
-        if (UtilValidate.isNotEmpty(currentValue)) {
-            for (ModelFormField.OptionValue optionValue : allOptionValues) {
-                if (encode(optionValue.getKey(), modelFormField, context).equals(currentValue)) {
-                    currentDescription = optionValue.getDescription();
-                    break;
-                }
-            }
-        }
-
-        if (ajaxEnabled) {
-            writer.append("<input type=\"text\"");
-        } else {
-            writer.append("<select");
-        }
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-
-        String idName = modelFormField.getCurrentContainerId(context);
-
-        if (ajaxEnabled) {
-            writer.append("_description\"");
-
-            String textFieldIdName = idName;
-            if (UtilValidate.isNotEmpty(textFieldIdName)) {
-                textFieldIdName += "_description";
-                writer.append(" id=\"");
-                writer.append(textFieldIdName);
-                writer.append('"');
-            }
-
-            if (UtilValidate.isNotEmpty(currentValue)) {
-                writer.append(" value=\"");
-                String explicitDescription = null;
-                if (currentDescription != null) {
-                    explicitDescription = currentDescription;
-                } else {
-                    explicitDescription = dropDownField.getCurrentDescription(context);
-                }
-                if (UtilValidate.isEmpty(explicitDescription)) {
-                    explicitDescription = FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues);
-                }
-                explicitDescription = encode(explicitDescription, modelFormField, context);
-                writer.append(explicitDescription);
-                writer.append('"');
-            }
-            writer.append("/>");
-
-            appendWhitespace(writer);
-            writer.append("<input type=\"hidden\" name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append('"');
-            if (UtilValidate.isNotEmpty(idName)) {
-                writer.append(" id=\"");
-                writer.append(idName);
-                writer.append('"');
-            }
-
-            if (UtilValidate.isNotEmpty(currentValue)) {
-                writer.append(" value=\"");
-                //String explicitDescription = dropDownField.getCurrentDescription(context);
-                writer.append(currentValue);
-                writer.append('"');
-            }
-
-            writer.append("/>");
-
-            appendWhitespace(writer);
-            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
-            appendWhitespace(writer);
-            writer.append("var data = {");
-            int count = 0;
-            for (ModelFormField.OptionValue optionValue: allOptionValues) {
-                count++;
-                writer.append(optionValue.getKey()).append(": ");
-                writer.append(" '").append(optionValue.getDescription()).append("'");
-                if (count != allOptionValues.size()) {
-                    writer.append(", ");
-                }
-            }
-            writer.append("};");
-            appendWhitespace(writer);
-            writer.append("ajaxAutoCompleteDropDown('").append(textFieldIdName).append("', '").append(idName).append("', data, {autoSelect: ").append(
-                    autoComplete.getAutoSelect()).append(", frequency: ").append(autoComplete.getFrequency()).append(", minChars: ").append(autoComplete.getMinChars()).append(
-                    ", choices: ").append(autoComplete.getChoices()).append(", partialSearch: ").append(autoComplete.getPartialSearch()).append(
-                    ", partialChars: ").append(autoComplete.getPartialChars()).append(", ignoreCase: ").append(autoComplete.getIgnoreCase()).append(
-                    ", fullSearch: ").append(autoComplete.getFullSearch()).append("});");
-            appendWhitespace(writer);
-            writer.append("</script>");
-        } else {
-            writer.append('"');
-
-            if (UtilValidate.isNotEmpty(idName)) {
-                writer.append(" id=\"");
-                writer.append(idName);
-                writer.append('"');
-            }
-
-            if (dropDownField.getAllowMultiple()) {
-                writer.append(" multiple=\"multiple\"");
-            }
-
-            int otherFieldSize = dropDownField.getOtherFieldSize();
-            String otherFieldName = dropDownField.getParameterNameOther(context);
-            if (otherFieldSize > 0) {
-                //writer.append(" onchange=\"alert('ONCHANGE, process_choice:' + process_choice)\"");
-                //writer.append(" onchange='test_js()' ");
-                writer.append(" onchange=\"process_choice(this,document.");
-                writer.append(modelForm.getName());
-                writer.append(".");
-                writer.append(otherFieldName);
-                writer.append(")\" ");
-            }
-
-            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
-                writer.append(" ");
-                writer.append(event);
-                writer.append("=\"");
-                writer.append(action);
-                writer.append('"');
-            }
-
-            writer.append(" size=\"").append(dropDownField.getSize()).append("\">");
-
-            // if the current value should go first, stick it in
-            if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
-                writer.append("<option");
-                writer.append(" selected=\"selected\"");
-                writer.append(" value=\"");
-                writer.append(currentValue);
-                writer.append("\">");
-                String explicitDescription = (currentDescription != null ? currentDescription : dropDownField.getCurrentDescription(context));
-                if (UtilValidate.isNotEmpty(explicitDescription)) {
-                    writer.append(encode(explicitDescription, modelFormField, context));
-                } else {
-                    String description = FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues);
-                    writer.append(encode(description, modelFormField, context));
-                }
-                writer.append("</option>");
-
-                // add a "separator" option
-                writer.append("<option value=\"");
-                writer.append(currentValue);
-                writer.append("\">---</option>");
-            }
-
-            // if allow empty is true, add an empty option
-            if (dropDownField.getAllowEmpty()) {
-                writer.append("<option value=\"\">&nbsp;</option>");
-            }
-
-            // list out all options according to the option list
-            for (ModelFormField.OptionValue optionValue: allOptionValues) {
-                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
-                writer.append("<option");
-                // if current value should be selected in the list, select it
-                if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) {
-                    writer.append(" selected=\"selected\"");
-                } else if (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey())) {
-                    writer.append(" selected=\"selected\"");
-                }
-                writer.append(" value=\"");
-                writer.append(encode(optionValue.getKey(), modelFormField, context));
-                writer.append("\">");
-                writer.append(encode(optionValue.getDescription(), modelFormField, context));
-                writer.append("</option>");
-            }
-
-            writer.append("</select>");
-
-
-            // Adapted from work by Yucca Korpela
-            // http://www.cs.tut.fi/~jkorpela/forms/combo.html
-            if (otherFieldSize > 0) {
-
-                String fieldName = modelFormField.getParameterName(context);
-                Map<String, Object> dataMap = UtilGenerics.checkMap(modelFormField.getMap(context));
-                if (dataMap == null) {
-                    dataMap = context;
-                }
-                Object otherValueObj = dataMap.get(otherFieldName);
-                String otherValue = (otherValueObj == null) ? "" : otherValueObj.toString();
-
-                writer.append("<noscript>");
-                writer.append("<input type='text' name='");
-                writer.append(otherFieldName);
-                writer.append("'/> ");
-                writer.append("</noscript>");
-                writer.append("\n<script type='text/javascript' language='JavaScript'><!--");
-                writer.append("\ndisa = ' disabled';");
-                writer.append("\nif (other_choice(document.");
-                writer.append(modelForm.getName());
-                writer.append(".");
-                writer.append(fieldName);
-                writer.append(")) disa = '';");
-                writer.append("\ndocument.write(\"<input type=");
-                writer.append("'text' name='");
-                writer.append(otherFieldName);
-                writer.append("' value='");
-                writer.append(otherValue);
-                writer.append("' size='");
-                writer.append(Integer.toString(otherFieldSize));
-                writer.append("' ");
-                writer.append("\" +disa+ \" onfocus='check_choice(document.");
-                writer.append(modelForm.getName());
-                writer.append(".");
-                writer.append(fieldName);
-                writer.append(")'/>\");");
-                writer.append("\nif (disa && document.styleSheets)");
-                writer.append(" document.");
-                writer.append(modelForm.getName());
-                writer.append(".");
-                writer.append(otherFieldName);
-                writer.append(".style.visibility  = 'hidden';");
-                writer.append("\n//--></script>");
-            }
-        }
-
-        this.makeHyperlinkString(writer, dropDownField.getSubHyperlink(), context);
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderCheckField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.CheckField)
-     */
-    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
-        ModelFormField modelFormField = checkField.getModelFormField();
-        String currentValue = modelFormField.getEntry(context);
-        Boolean allChecked = checkField.isAllChecked(context);
-
-        List<ModelFormField.OptionValue> allOptionValues = checkField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-
-        // list out all options according to the option list
-        for (ModelFormField.OptionValue optionValue: allOptionValues) {
-
-            writer.append("<input type=\"checkbox\"");
-
-            appendClassNames(writer, context, modelFormField);
-
-            // if current value should be selected in the list, select it
-            if (Boolean.TRUE.equals(allChecked)) {
-                writer.append(" checked=\"checked\"");
-            } else if (Boolean.FALSE.equals(allChecked)) {
-                // do nothing
-            } else if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey())) {
-                writer.append(" checked=\"checked\"");
-            }
-            writer.append(" name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append('"');
-            writer.append(" value=\"");
-            writer.append(encode(optionValue.getKey(), modelFormField, context));
-            writer.append("\"");
-
-            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
-                writer.append(" ");
-                writer.append(event);
-                writer.append("=\"");
-                writer.append(action);
-                writer.append('"');
-            }
-
-            writer.append("/>");
-
-            writer.append(encode(optionValue.getDescription(), modelFormField, context));
-        }
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderRadioField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.RadioField)
-     */
-    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
-        ModelFormField modelFormField = radioField.getModelFormField();
-        List<ModelFormField.OptionValue> allOptionValues = radioField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-        String currentValue = modelFormField.getEntry(context);
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-
-        // list out all options according to the option list
-        for (ModelFormField.OptionValue optionValue: allOptionValues) {
-
-            writer.append("<span");
-
-            appendClassNames(writer, context, modelFormField);
-
-            writer.append("><input type=\"radio\"");
-
-            // if current value should be selected in the list, select it
-            String noCurrentSelectedKey = radioField.getNoCurrentSelectedKey(context);
-            if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey())) {
-                writer.append(" checked=\"checked\"");
-            } else if (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey())) {
-                writer.append(" checked=\"checked\"");
-            }
-            writer.append(" name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append('"');
-            writer.append(" value=\"");
-            writer.append(encode(optionValue.getKey(), modelFormField, context));
-            writer.append("\"");
-
-            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
-                writer.append(" ");
-                writer.append(event);
-                writer.append("=\"");
-                writer.append(action);
-                writer.append('"');
-            }
-
-            writer.append("/>");
-
-            writer.append(encode(optionValue.getDescription(), modelFormField, context));
-            writer.append("</span>");
-        }
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderSubmitField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.SubmitField)
-     */
-    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
-        ModelFormField modelFormField = submitField.getModelFormField();
-        ModelForm modelForm = modelFormField.getModelForm();
-        String event = null;
-        String action = null;
-        String confirmation =  encode(submitField.getConfirmation(context), modelFormField, context);
-
-        if ("text-link".equals(submitField.getButtonType())) {
-            writer.append("<a");
-
-            appendClassNames(writer, context, modelFormField);
-            if (UtilValidate.isNotEmpty(confirmation)) {
-                writer.append(" onclick=\"return confirm('");
-                writer.append(confirmation);
-                writer.append("'); \" ");
-            }
-
-            writer.append(" href=\"javascript:document.");
-            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
-            writer.append(".submit()\">");
-
-            writer.append(encode(modelFormField.getTitle(context), modelFormField, context));
-
-            writer.append("</a>");
-        } else if ("image".equals(submitField.getButtonType())) {
-            writer.append("<input type=\"image\"");
-
-            appendClassNames(writer, context, modelFormField);
-
-            writer.append(" name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append('"');
-
-            String title = modelFormField.getTitle(context);
-            if (UtilValidate.isNotEmpty(title)) {
-                writer.append(" alt=\"");
-                writer.append(encode(title, modelFormField, context));
-                writer.append('"');
-            }
-
-            writer.append(" src=\"");
-            this.appendContentUrl(writer, submitField.getImageLocation(context));
-            writer.append('"');
-
-            event = modelFormField.getEvent();
-            action = modelFormField.getAction(context);
-            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
-                writer.append(" ");
-                writer.append(event);
-                writer.append("=\"");
-                writer.append(action);
-                writer.append('"');
-            }
-
-            if (UtilValidate.isNotEmpty(confirmation)) {
-                writer.append("onclick=\" return confirm('");
-                writer.append(confirmation);
-                writer.append("); \" ");
-            }
-
-            writer.append("/>");
-        } else {
-            // default to "button"
-
-            String formId = modelForm.getContainerId();
-            List<ModelForm.UpdateArea> updateAreas = modelForm.getOnSubmitUpdateAreas();
-            // This is here for backwards compatibility. Use on-event-update-area
-            // elements instead.
-            String backgroundSubmitRefreshTarget = submitField.getBackgroundSubmitRefreshTarget(context);
-            if (UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) {
-                if (updateAreas == null) {
-                    updateAreas = new LinkedList<ModelForm.UpdateArea>();
-                }
-                updateAreas.add(new ModelForm.UpdateArea("submit", formId, backgroundSubmitRefreshTarget));
-            }
-
-            boolean ajaxEnabled = (UtilValidate.isNotEmpty(updateAreas) || UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) && this.javaScriptEnabled;
-            if (ajaxEnabled) {
-                writer.append("<input type=\"button\"");
-            } else {
-                writer.append("<input type=\"submit\"");
-            }
-
-            appendClassNames(writer, context, modelFormField);
-
-            writer.append(" name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append('"');
-
-            String title = modelFormField.getTitle(context);
-            if (UtilValidate.isNotEmpty(title)) {
-                writer.append(" value=\"");
-                writer.append(encode(title, modelFormField, context));
-                writer.append('"');
-            }
-
-
-            event = modelFormField.getEvent();
-            action = modelFormField.getAction(context);
-            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
-                writer.append(" ");
-                writer.append(event);
-                writer.append("=\"");
-                writer.append(action);
-                writer.append('"');
-            } else {
-                //add single click JS onclick
-                // disabling for now, using form onSubmit action instead: writer.append(singleClickAction);
-            }
-
-            if (ajaxEnabled) {
-                writer.append(" onclick=\"");
-                if (UtilValidate.isNotEmpty(confirmation)) {
-                    writer.append("if  (confirm('");
-                    writer.append(confirmation);
-                    writer.append(");) ");
-                }
-                writer.append("ajaxSubmitFormUpdateAreas('");
-                writer.append(formId);
-                writer.append("', '").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context));
-                writer.append("')\"");
-            }
-
-            writer.append("/>");
-        }
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderResetField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.ResetField)
-     */
-    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
-        ModelFormField modelFormField = resetField.getModelFormField();
-
-        writer.append("<input type=\"reset\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append('"');
-
-        String title = modelFormField.getTitle(context);
-        if (UtilValidate.isNotEmpty(title)) {
-            writer.append(" value=\"");
-            writer.append(encode(title, modelFormField, context));
-            writer.append('"');
-        }
-
-        writer.append("/>");
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderHiddenField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.HiddenField)
-     */
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
-        ModelFormField modelFormField = hiddenField.getModelFormField();
-        String value = hiddenField.getValue(context);
-        this.renderHiddenField(writer, context, modelFormField, value);
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
-        writer.append("<input type=\"hidden\"");
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append('"');
-
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append("/>");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderIgnoredField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.IgnoredField)
-     */
-    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) throws IOException {
-        // do nothing, it's an ignored field; could add a comment or something if we wanted to
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFieldTitle(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
-     */
-    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        String tempTitleText = modelFormField.getTitle(context);
-        String titleText = UtilHttp.encodeAmpersands(tempTitleText);
-
-        if (UtilValidate.isNotEmpty(titleText)) {
-            // copied from MacroFormRenderer renderFieldTitle
-            String displayHelpText = UtilProperties.getPropertyValue("widget.properties", "widget.form.displayhelpText");
-            String helpText = null;
-            if ("Y".equals(displayHelpText)) {
-                Delegator delegator = WidgetWorker.getDelegator(context);
-                Locale locale = (Locale)context.get("locale");
-                String entityName = modelFormField.getEntityName();
-                String fieldName = modelFormField.getFieldName();
-                helpText = UtilHelpText.getEntityFieldDescription(entityName, fieldName, delegator, locale);
-            }
-            if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle()) || UtilValidate.isNotEmpty(helpText)) {
-                writer.append("<span");
-                if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())){
-                    writer.append(" class=\"");
-                    writer.append(modelFormField.getTitleStyle());
-                }
-                if (UtilValidate.isNotEmpty(helpText)){
-                    writer.append(" title=\"");
-                    writer.append(FreeMarkerWorker.encodeDoubleQuotes(helpText));
-                }
-                writer.append("\">");
-            }
-            if (" ".equals(titleText)) {
-                // If the title content is just a blank then render it colling renderFormatEmptySpace:
-                // the method will set its content to work fine in most browser
-                this.renderFormatEmptySpace(writer, context, modelFormField.getModelForm());
-            } else {
-                renderHyperlinkTitle(writer, context, modelFormField, titleText);
-            }
-
-            if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-                writer.append("</span>");
-            }
-
-            //appendWhitespace(writer);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFieldTitle(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
-     */
-    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        boolean requiredField = modelFormField.getRequiredField();
-        if (requiredField) {
-
-            String requiredStyle = modelFormField.getRequiredFieldStyle();
-            if (UtilValidate.isEmpty(requiredStyle)) {
-                requiredStyle = modelFormField.getTitleStyle();
-            }
-
-            if (UtilValidate.isNotEmpty(requiredStyle)) {
-                writer.append("<span class=\"");
-                writer.append(requiredStyle);
-                writer.append("\">");
-            }
-            renderHyperlinkTitle(writer, context, modelFormField, modelFormField.getTitle(context));
-            if (UtilValidate.isNotEmpty(requiredStyle)) {
-                writer.append("</span>");
-            }
-
-            //appendWhitespace(writer);
-        } else {
-            renderFieldTitle(writer, context, modelFormField);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        renderBeginningBoundaryComment(writer, "Form Widget - Form Element", modelForm);
-        writer.append("<form method=\"post\" ");
-        String targetType = modelForm.getTargetType();
-        String targ = modelForm.getTarget(context, targetType);
-        // The 'action' attribute is mandatory in a form definition,
-        // even if it is empty.
-        writer.append(" action=\"");
-        if (UtilValidate.isNotEmpty(targ)) {
-            //this.appendOfbizUrl(writer, "/" + targ);
-            WidgetWorker.buildHyperlinkUrl(writer, targ, targetType, null, null, false, false, true, request, response, context);
-        }
-        writer.append("\" ");
-
-        String formType = modelForm.getType();
-        if (formType.equals("upload")) {
-            writer.append(" enctype=\"multipart/form-data\"");
-        }
-
-        String targetWindow = modelForm.getTargetWindow(context);
-        if (UtilValidate.isNotEmpty(targetWindow)) {
-            writer.append(" target=\"");
-            writer.append(targetWindow);
-            writer.append("\"");
-        }
-
-        String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
-        if (UtilValidate.isNotEmpty(containerId)) {
-            writer.append(" id=\"");
-            writer.append(containerId);
-            writer.append("\"");
-        }
-
-        writer.append(" class=\"");
-        String containerStyle =  modelForm.getContainerStyle();
-        if (UtilValidate.isNotEmpty(containerStyle)) {
-            writer.append(containerStyle);
-        } else {
-            writer.append("basic-form");
-        }
-        writer.append("\"");
-
-        writer.append(" onsubmit=\"javascript:submitFormDisableSubmits(this)\"");
-
-        if (!modelForm.getClientAutocompleteFields()) {
-            writer.append(" autocomplete=\"off\"");
-        }
-
-        writer.append(" name=\"");
-        writer.append(FormRenderer.getCurrentContainerId(modelForm, context));
-        writer.append("\">");
-
-        boolean useRowSubmit = modelForm.getUseRowSubmit();
-        if (useRowSubmit) {
-            writer.append("<input type=\"hidden\" name=\"_useRowSubmit\" value=\"Y\"/>");
-        }
-
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</form>");
-        String focusFieldName = FormRenderer.getFocusFieldName(modelForm, context);
-        if (UtilValidate.isNotEmpty(focusFieldName)) {
-            appendWhitespace(writer);
-            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
-            appendWhitespace(writer);
-            writer.append("document.").append(FormRenderer.getCurrentFormName(modelForm, context)).append(".");
-            writer.append(focusFieldName).append(".focus();");
-            appendWhitespace(writer);
-            writer.append("</script>");
-        }
-        appendWhitespace(writer);
-        renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        for (ModelFormField submitField: modelForm.getMultiSubmitFields()) {
-            if (submitField != null) {
-
-                // Threw this in that as a hack to keep the submit button from expanding the first field
-                // Needs a more rugged solution
-                // WARNING: this method (renderMultiFormClose) must be called after the
-                // table that contains the list has been closed (to avoid validation errors) so
-                // we cannot call here the methods renderFormatItemRowCell*: for this reason
-                // they are now commented.
-
-                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
-                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);
-
-                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
-
-                submitField.renderFieldString(writer, context, this);
-
-                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);
-
-            }
-        }
-        writer.append("</form>");
-        appendWhitespace(writer);
-
-        // see if there is anything that needs to be added outside of the multi-form
-        Map<String, Object> wholeFormContext = UtilGenerics.checkMap(context.get("wholeFormContext"));
-        Appendable postMultiFormWriter = wholeFormContext != null ? (Appendable) wholeFormContext.get("postMultiFormWriter") : null;
-        if (postMultiFormWriter != null) {
-            writer.append(postMultiFormWriter.toString());
-            appendWhitespace(writer);
-        }
-
-        renderEndingBoundaryComment(writer, "Form Widget - Form Element (Multi)", modelForm);
-    }
-
-    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-
-        Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters"));
-        Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap"));
-        if (UtilValidate.isNotEmpty(queryStringMap)) {
-            inputFields.putAll(queryStringMap);
-        }
-        if (modelForm.getType().equals("multi")) {
-            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
-        }
-        String queryString = UtilHttp.urlEncodeArgs(inputFields);
-        context.put("_QBESTRING_", queryString);
-
-        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        renderBeginningBoundaryComment(writer, "Form Widget", modelForm);
-
-        if (this.renderPagination) {
-            this.renderNextPrev(writer, context, modelForm);
-        }
-        writer.append(" <table cellspacing=\"0\" class=\"");
-        if (UtilValidate.isNotEmpty(modelForm.getDefaultTableStyle())) {
-            writer.append(FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context));
-        } else {
-            writer.append("basic-table form-widget-table dark-grid");
-        }
-        writer.append("\">");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append(" </table>");
-
-        appendWhitespace(writer);
-        if (this.renderPagination) {
-            this.renderNextPrev(writer, context, modelForm);
-        }
-        renderEndingBoundaryComment(writer, "Form Widget - Formal List Wrapper", modelForm);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("  <tr");
-        String headerStyle = FlexibleStringExpander.expandString(modelForm.getHeaderRowStyle(), context);
-        writer.append(" class=\"");
-        if (UtilValidate.isNotEmpty(headerStyle)) {
-            writer.append(headerStyle);
-        } else {
-            writer.append("header-row");
-        }
-        writer.append("\">");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("  </tr>");
-
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, org.ofbiz.widget.form.ModelFormField, int positionSpan)
-     */
-    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
-        writer.append("   <td");
-        String areaStyle = modelFormField.getTitleAreaStyle();
-        if (positionSpan > 1) {
-            writer.append(" colspan=\"");
-            writer.append(Integer.toString(positionSpan));
-            writer.append("\"");
-        }
-        if (UtilValidate.isNotEmpty(areaStyle)) {
-            writer.append(" class=\"");
-            writer.append(areaStyle);
-            writer.append("\"");
-        }
-        writer.append(">");
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, org.ofbiz.widget.form.ModelFormField)
-     */
-    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
-        writer.append("</td>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("   <td");
-        String areaStyle = modelForm.getFormTitleAreaStyle();
-        if (UtilValidate.isNotEmpty(areaStyle)) {
-            writer.append(" class=\"");
-            writer.append(areaStyle);
-            writer.append("\"");
-        }
-        writer.append(">");
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowFormCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</td>");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowFormCellTitleSeparator(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, boolean)
-     */
-    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {
-
-        String titleStyle = modelFormField.getTitleStyle();
-        if (UtilValidate.isNotEmpty(titleStyle)) {
-            writer.append("<span class=\"");
-            writer.append(titleStyle);
-            writer.append("\">");
-        }
-        if (isLast) {
-            writer.append(" - ");
-        } else {
-            writer.append(" - ");
-        }
-        if (UtilValidate.isNotEmpty(titleStyle)) {
-            writer.append("</span>");
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        Integer itemIndex = (Integer)context.get("itemIndex");
-
-        writer.append("  <tr");
-        if (itemIndex!=null) {
-
-            String altRowStyles = modelForm.getStyleAltRowStyle(context);
-            if (itemIndex.intValue() % 2 == 0) {
-                String evenRowStyle = modelForm.getEvenRowStyle();
-                if (UtilValidate.isNotEmpty(evenRowStyle)) {
-                    writer.append(" class=\"");
-                    writer.append(evenRowStyle);
-                    if (UtilValidate.isNotEmpty(altRowStyles)) {
-                        writer.append(altRowStyles);
-                    }
-                    writer.append("\"");
-                } else {
-                    if (UtilValidate.isNotEmpty(altRowStyles)) {
-                        writer.append(" class=\"");
-                        writer.append(altRowStyles);
-                        writer.append("\"");
-                    }
-                }
-            } else {
-                String oddRowStyle = FlexibleStringExpander.expandString(modelForm.getOddRowStyle(), context);
-                if (UtilValidate.isNotEmpty(oddRowStyle)) {
-                    writer.append(" class=\"");
-                    writer.append(oddRowStyle);
-                    if (UtilValidate.isNotEmpty(altRowStyles)) {
-                        writer.append(altRowStyles);
-                    }
-                    writer.append("\"");
-                } else {
-                    if (UtilValidate.isNotEmpty(altRowStyles)) {
-                        writer.append(" class=\"");
-                        writer.append(altRowStyles);
-                        writer.append("\"");
-                    }
-                }
-            }
-        }
-        writer.append(">");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("  </tr>");
-
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, org.ofbiz.widget.form.ModelFormField)
-     */
-    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
-        writer.append("   <td");
-        String areaStyle = modelFormField.getWidgetAreaStyle();
-        if (positionSpan > 1) {
-            writer.append(" colspan=\"");
-            writer.append(Integer.toString(positionSpan));
-            writer.append("\"");
-        }
-        if (UtilValidate.isNotEmpty(areaStyle)) {
-            writer.append(" class=\"");
-            writer.append(areaStyle);
-            writer.append("\"");
-        }
-        writer.append(">");
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm, org.ofbiz.widget.form.ModelFormField)
-     */
-    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
-        writer.append("</td>");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowFormCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("   <td");
-        String areaStyle = modelForm.getFormWidgetAreaStyle();
-        if (UtilValidate.isNotEmpty(areaStyle)) {
-            writer.append(" class=\"");
-            writer.append(areaStyle);
-            writer.append("\"");
-        }
-        writer.append(">");
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowFormCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</td>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append(" <table cellspacing=\"0\"");
-        if (UtilValidate.isNotEmpty(modelForm.getDefaultTableStyle())) {
-            writer.append(" class=\"").append(FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context)).append("\"");
-        }
-        writer.append(">");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append(" </table>");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("  <tr>");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelForm)
-     */
-    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("  </tr>");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowTitleCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
-     */
-    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        writer.append("   <td");
-        String areaStyle = modelFormField.getTitleAreaStyle();
-        if (UtilValidate.isNotEmpty(areaStyle)) {
-            writer.append(" class=\"");
-            writer.append(areaStyle);
-            writer.append("\"");
-        } else {
-            writer.append(" class=\"label\"");
-        }
-        writer.append(">");
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowTitleCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
-     */
-    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        writer.append("</td>");
-        appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowSpacerCell(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField)
-     */
-    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        // Embedded styling - bad idea
-        //writer.append("<td>&nbsp;</td>");
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowWidgetCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField, int)
-     */
-    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
-//        writer.append("<td width=\"");
-//        if (nextPositionInRow != null || modelFormField.getPosition() > 1) {
-//            writer.append("30");
-//        } else {
-//            writer.append("80");
-//        }
-//        writer.append("%\"");
-        writer.append("   <td");
-        if (positionSpan > 0) {
-            writer.append(" colspan=\"");
-            // do a span of 1 for this column, plus 3 columns for each spanned
-            //position or each blank position that this will be filling in
-            writer.append(Integer.toString(1 + (positionSpan * 3)));
-            writer.append("\"");
-        }
-        String areaStyle = modelFormField.getWidgetAreaStyle();
-        if (UtilValidate.isNotEmpty(areaStyle)) {
-            writer.append(" class=\"");
-            writer.append(areaStyle);
-            writer.append("\"");
-        }
-        writer.append(">");
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowWidgetCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField, int)
-     */
-    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
-        writer.append("</td>");
-        appendWhitespace(writer);
-    }
-
-    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("&nbsp;");
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.TextFindField)
-     */
-    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
-
-        ModelFormField modelFormField = textFindField.getModelFormField();
-
-        String defaultOption = textFindField.getDefaultOption();
-        Locale locale = (Locale)context.get("locale");
-        if (!textFindField.getHideOptions()) {
-            String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
-            String opBeginsWith = UtilProperties.getMessage("conditional", "begins_with", locale);
-            String opContains = UtilProperties.getMessage("conditional", "contains", locale);
-            String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
-            String opNotEqual = UtilProperties.getMessage("conditional", "not_equal", locale);
-            writer.append(" <select name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append("_op\" class=\"selectBox\">");
-            writer.append("<option value=\"equals\"").append(("equals".equals(defaultOption)? " selected": "")).append(">").append(opEquals).append("</option>");
-            writer.append("<option value=\"like\"").append(("like".equals(defaultOption)? " selected": "")).append(">").append(opBeginsWith).append("</option>");
-            writer.append("<option value=\"contains\"").append(("contains".equals(defaultOption)? " selected": "")).append(">").append(opContains).append("</option>");
-            writer.append("<option value=\"empty\"").append(("empty".equals(defaultOption)? " selected": "")).append(">").append(opIsEmpty).append("</option>");
-            writer.append("<option value=\"notEqual\"").append(("notEqual".equals(defaultOption)? " selected": "")).append(">").append(opNotEqual).append("</option>");
-            writer.append("</select>");
-        } else {
-            writer.append(" <input type=\"hidden\" name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append("_op\" value=\"").append(defaultOption).append("\"/>");
-        }
-
-        writer.append("<input type=\"text\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append('"');
-
-        String value = modelFormField.getEntry(context, textFindField.getDefaultValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(textFindField.getSize()));
-        writer.append('"');
-
-        Integer maxlength = textFindField.getMaxlength();
-        if (maxlength != null) {
-            writer.append(" maxlength=\"");
-            writer.append(maxlength.toString());
-            writer.append('"');
-        }
-
-        if (!textFindField.getClientAutocompleteField()) {
-            writer.append(" autocomplete=\"off\"");
-        }
-
-        writer.append("/>");
-
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            writer.append(" <span class=\"");
-            writer.append(modelFormField.getTitleStyle());
-            writer.append("\">");
-        }
-
-        String ignoreCase = UtilProperties.getMessage("conditional", "ignore_case", locale);
-        boolean ignCase = textFindField.getIgnoreCase();
-
-        if (!textFindField.getHideIgnoreCase()) {
-            writer.append(" <input type=\"checkbox\" name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append("_ic\" value=\"Y\"").append((ignCase ? " checked=\"checked\"" : "")).append("/>");
-            writer.append(ignoreCase);
-        } else {
-            writer.append("<input type=\"hidden\" name=\"");
-            writer.append(modelFormField.getParameterName(context));
-            writer.append("_ic\" value=\"").append((ignCase ? "Y" : "")).append("\"/>");
-        }
-
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            writer.append("</span>");
-        }
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderRangeFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.RangeFindField)
-     */
-    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
-
-        ModelFormField modelFormField = rangeFindField.getModelFormField();
-        Locale locale = (Locale)context.get("locale");
-        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
-        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
-        String opGreaterThanEquals = UtilProperties.getMessage("conditional", "greater_than_equals", locale);
-        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
-        String opLessThanEquals = UtilProperties.getMessage("conditional", "less_than_equals", locale);
-        //String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
-
-        writer.append("<input type=\"text\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append("_fld0_value\"");
-
-        String value = modelFormField.getEntry(context, rangeFindField.getDefaultValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(rangeFindField.getSize()));
-        writer.append('"');
-
-        Integer maxlength = rangeFindField.getMaxlength();
-        if (maxlength != null) {
-            writer.append(" maxlength=\"");
-            writer.append(maxlength.toString());
-            writer.append('"');
-        }
-
-        if (!rangeFindField.getClientAutocompleteField()) {
-            writer.append(" autocomplete=\"off\"");
-        }
-
-        writer.append("/>");
-
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            writer.append(" <span class=\"");
-            writer.append(modelFormField.getTitleStyle());
-            writer.append("\">");
-        }
-
-        String defaultOptionFrom = rangeFindField.getDefaultOptionFrom();
-        writer.append(" <select name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append("_fld0_op\" class=\"selectBox\">");
-        writer.append("<option value=\"equals\"").append(("equals".equals(defaultOptionFrom)? " selected": "")).append(">").append(opEquals).append("</option>");
-        writer.append("<option value=\"greaterThan\"").append(("greaterThan".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThan).append("</option>");
-        writer.append("<option value=\"greaterThanEqualTo\"").append(("greaterThanEqualTo".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThanEquals).append("</option>");
-        writer.append("</select>");
-
-        writer.append("</span>");
-
-        writer.append(" <br/> ");
-
-        writer.append("<input type=\"text\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append("_fld1_value\"");
-
-        value = modelFormField.getEntry(context);
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(rangeFindField.getSize()));
-        writer.append('"');
-
-        if (maxlength != null) {
-            writer.append(" maxlength=\"");
-            writer.append(maxlength.toString());
-            writer.append('"');
-        }
-
-        if (!rangeFindField.getClientAutocompleteField()) {
-            writer.append(" autocomplete=\"off\"");
-        }
-
-        writer.append("/>");
-
-        String defaultOptionThru = rangeFindField.getDefaultOptionThru();
-        writer.append(" <select name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append("_fld1_op\" class=\"selectBox\">");
-        writer.append("<option value=\"lessThan\"").append(("lessThan".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThan).append("</option>");
-        writer.append("<option value=\"lessThanEqualTo\"").append(("lessThanEqualTo".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThanEquals).append("</option>");
-        writer.append("</select>");
-
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            writer.append("</span>");
-        }
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderDateFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.DateFindField)
-     */
-    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
-        ModelFormField modelFormField = dateFindField.getModelFormField();
-
-        Locale locale = (Locale)context.get("locale");
-        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
-        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
-        String opSameDay = UtilProperties.getMessage("conditional", "same_day", locale);
-        String opGreaterThanFromDayStart = UtilProperties.getMessage("conditional",
-                                                "greater_than_from_day_start", locale);
-        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
-        String opUpToDay = UtilProperties.getMessage("conditional", "up_to_day", locale);
-        String opUpThruDay = UtilProperties.getMessage("conditional", "up_thru_day", locale);
-        String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
-
-        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        }
-        String localizedInputTitle = "", localizedIconTitle = "";
-
-        writer.append("<input type=\"text\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append("_fld0_value\"");
-
-        // the default values for a timestamp
-        int size = 25;
-        int maxlength = 30;
-
-        if ("date".equals(dateFindField.getType())) {
-            size = maxlength = 10;
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatDate");
-            }
-        } else if ("time".equals(dateFindField.getType())) {
-            size = maxlength = 8;
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatTime");
-            }
-        } else {
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatDateTime");
-            }
-        }
-        writer.append(" title=\"");
-        writer.append(localizedInputTitle);
-        writer.append('"');
-
-        String value = modelFormField.getEntry(context, dateFindField.getDefaultValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            if (value.length() > maxlength) {
-                value = value.substring(0, maxlength);
-            }
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(size));
-        writer.append('"');
-
-        writer.append(" maxlength=\"");
-        writer.append(Integer.toString(maxlength));
-        writer.append('"');
-
-        writer.append("/>");
-
-        // search for a localized label for the icon
-        if (uiLabelMap != null) {
-            localizedIconTitle = uiLabelMap.get("CommonViewCalendar");
-        }
-        ModelForm modelForm = modelFormField.getModelForm();
-        // add calendar pop-up button and seed data IF this is not a "time" type date-find
-        if (!"time".equals(dateFindField.getType())) {
-            if ("date".equals(dateFindField.getType())) {
-                writer.append("<a href=\"javascript:call_cal_notime(document.");
-            } else {
-                writer.append("<a href=\"javascript:call_cal(document.");
-            }
-            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
-            writer.append('.');
-            writer.append(modelFormField.getParameterName(context));
-            writer.append("_fld0_value,'");
-            writer.append(UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context))));
-            writer.append("');\">");
-
-            writer.append("<img src=\"");
-            this.appendContentUrl(writer, "/images/cal.gif");
-            writer.append("\" width=\"16\" height=\"16\" border=\"0\" alt=\"");
-            writer.append(localizedIconTitle);
-            writer.append("\" title=\"");
-            writer.append(localizedIconTitle);
-            writer.append("\"/></a>");
-        }
-
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            writer.append(" <span class=\"");
-            writer.append(modelFormField.getTitleStyle());
-            writer.append("\">");
-        }
-
-        String defaultOptionFrom = dateFindField.getDefaultOptionFrom();
-        writer.append(" <select name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append("_fld0_op\" class=\"selectBox\">");
-        writer.append("<option value=\"equals\"").append(("equals".equals(defaultOptionFrom)? " selected": "")).append(">").append(opEquals).append("</option>");
-        writer.append("<option value=\"sameDay\"").append(("sameDay".equals(defaultOptionFrom)? " selected": "")).append(">").append(opSameDay).append("</option>");
-        writer.append("<option value=\"greaterThanFromDayStart\"").append(("greaterThanFromDayStart".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThanFromDayStart).append("</option>");
-        writer.append("<option value=\"greaterThan\"").append(("greaterThan".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThan).append("</option>");
-        writer.append("</select>");
-
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            writer.append(" </span>");
-        }
-
-        writer.append(" <br/> ");
-
-        writer.append("<input type=\"text\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append("_fld1_value\"");
-
-        writer.append(" title=\"");
-        writer.append(localizedInputTitle);
-        writer.append('"');
-
-        value = modelFormField.getEntry(context);
-        if (UtilValidate.isNotEmpty(value)) {
-            if (value.length() > maxlength) {
-                value = value.substring(0, maxlength);
-            }
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(size));
-        writer.append('"');
-
-        writer.append(" maxlength=\"");
-        writer.append(Integer.toString(maxlength));
-        writer.append('"');
-
-        writer.append("/>");
-
-        // add calendar pop-up button and seed data IF this is not a "time" type date-find
-        if (!"time".equals(dateFindField.getType())) {
-            if ("date".equals(dateFindField.getType())) {
-                writer.append("<a href=\"javascript:call_cal_notime(document.");
-            } else {
-                writer.append("<a href=\"javascript:call_cal(document.");
-            }
-            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
-            writer.append('.');
-            writer.append(modelFormField.getParameterName(context));
-            writer.append("_fld1_value,'");
-            writer.append(UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context))));
-            writer.append("');\">");
-
-            writer.append("<img src=\"");
-            this.appendContentUrl(writer, "/images/cal.gif");
-            writer.append("\" width=\"16\" height=\"16\" border=\"0\" alt=\"");
-            writer.append(localizedIconTitle);
-            writer.append("\" title=\"");
-            writer.append(localizedIconTitle);
-            writer.append("\"/></a>");
-        }
-
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            writer.append(" <span class=\"");
-            writer.append(modelFormField.getTitleStyle());
-            writer.append("\">");
-        }
-
-        String defaultOptionThru = dateFindField.getDefaultOptionThru();
-        writer.append(" <select name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append("_fld1_op\" class=\"selectBox\">");
-        writer.append("<option value=\"lessThan\"").append(("lessThan".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThan).append("</option>");
-        writer.append("<option value=\"upToDay\"").append(("upToDay".equals(defaultOptionThru)? " selected": "")).append(">").append(opUpToDay).append("</option>");
-        writer.append("<option value=\"upThruDay\"").append(("upThruDay".equals(defaultOptionThru)? " selected": "")).append(">").append(opUpThruDay).append("</option>");
-        writer.append("<option value=\"empty\"").append(("empty".equals(defaultOptionThru)? " selected": "")).append(">").append(opIsEmpty).append("</option>");
-        writer.append("</select>");
-
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            writer.append("</span>");
-        }
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderLookupField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.LookupField)
-     */
-    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
-        ModelFormField modelFormField = lookupField.getModelFormField();
-
-        writer.append("<input type=\"text\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append('"');
-
-        String value = modelFormField.getEntry(context, lookupField.getDefaultValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(lookupField.getSize()));
-        writer.append('"');
-
-        Integer maxlength = lookupField.getMaxlength();
-        if (maxlength != null) {
-            writer.append(" maxlength=\"");
-            writer.append(maxlength.toString());
-            writer.append('"');
-        }
-
-        String idName = modelFormField.getCurrentContainerId(context);
-        if (UtilValidate.isNotEmpty(idName)) {
-            writer.append(" id=\"");
-            writer.append(idName);
-            writer.append('"');
-        }
-
-        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
-        boolean ajaxEnabled = updateAreas != null && this.javaScriptEnabled;
-        if (!lookupField.getClientAutocompleteField() || ajaxEnabled) {
-            writer.append(" autocomplete=\"off\"");
-        }
-
-        writer.append("/>");
-        ModelForm modelForm = modelFormField.getModelForm();
-        // add lookup pop-up button
-        String descriptionFieldName = lookupField.getDescriptionFieldName();
-        if (UtilValidate.isNotEmpty(descriptionFieldName)) {
-            writer.append("<a href=\"javascript:call_fieldlookup3(document.");
-            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
-            writer.append('.');
-            writer.append(modelFormField.getParameterName(context));
-            writer.append(",'");
-            writer.append(descriptionFieldName);
-            writer.append(",'");
-        } else {
-            writer.append("<a href=\"javascript:call_fieldlookup2(document.");
-            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
-            writer.append('.');
-            writer.append(modelFormField.getParameterName(context));
-            writer.append(",'");
-        }
-        writer.append(appendExternalLoginKey(lookupField.getFormName(context)));
-        writer.append("'");
-        List<String> targetParameterList = lookupField.getTargetParameterList();
-        for (String targetParameter: targetParameterList) {
-            // named like: document.${formName}.${targetParameter}.value
-            writer.append(", document.");
-            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
-            writer.append(".");
-            writer.append(targetParameter);
-            writer.append(".value");
-        }
-        writer.append(");\">");
-        writer.append("<img src=\"");
-        this.appendContentUrl(writer, "/images/fieldlookup.gif");
-        writer.append("\" width=\"15\" height=\"14\" border=\"0\" alt=\"Lookup\"/></a>");
-
-        this.addAsterisks(writer, context, modelFormField);
-
-        this.makeHyperlinkString(writer, lookupField.getSubHyperlink(), context);
-        this.appendTooltip(writer, context, modelFormField);
-
-        if (ajaxEnabled) {
-            appendWhitespace(writer);
-            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
-            appendWhitespace(writer);
-            writer.append("ajaxAutoCompleter('").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context)).append("');");
-            appendWhitespace(writer);
-            writer.append("</script>");
-        }
-        appendWhitespace(writer);
-
-        //appendWhitespace(writer);
-    }
-
-    protected String appendExternalLoginKey(String target) {
-        String result = target;
-        String sessionId = ";jsessionid=" + request.getSession().getId();
-        int questionIndex = target.indexOf("?");
-        if (questionIndex == -1) {
-            result += sessionId;
-        } else {
-            result = result.replace("?", sessionId + "?");
-        }
-        return result;
-    }
-
-    private int getActualPageSize(Map<String, Object> context) {
-        Integer value = (Integer) context.get("actualPageSize");
-        return value != null ? value.intValue() : (getHighIndex(context) - getLowIndex(context));
-    }
-
-    private int getHighIndex(Map<String, Object> context) {
-        Integer value = (Integer) context.get("highIndex");
-        return value != null ? value.intValue() : 0;
-    }
-
-    private int getListSize(Map<String, Object> context) {
-        Integer value = (Integer) context.get("listSize");
-        return value != null ? value.intValue() : 0;
-    }
-
-    private int getLowIndex(Map<String, Object> context) {
-        Integer value = (Integer) context.get("lowIndex");
-        return value != null ? value.intValue() : 0;
-    }
-
-    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        boolean ajaxEnabled = false;
-        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnPaginateUpdateAreas();
-        String targetService = modelForm.getPaginateTarget(context);
-        if (this.javaScriptEnabled) {
-            if (UtilValidate.isNotEmpty(updateAreas)) {
-                ajaxEnabled = true;
-            }
-        }
-        if (targetService == null) {
-            targetService = "${targetService}";
-        }
-        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
-            Debug.logWarning("Cannot paginate because TargetService is empty for the form: " + modelForm.getName(), module);
-            return;
-        }
-
-        // get the parameterized pagination index and size fields
-        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
-        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
-        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
-
-        int viewIndex = Paginator.getViewIndex(modelForm, context);
-        int viewSize = Paginator.getViewSize(modelForm, context);
-        int listSize = getListSize(context);
-
-        int lowIndex = getLowIndex(context);
-        int highIndex = getHighIndex(context);
-        int actualPageSize = getActualPageSize(context);
-
-        // if this is all there seems to be (if listSize < 0, then size is unknown)
-        if (actualPageSize >= listSize && listSize >= 0) return;
-
-        // needed for the "Page" and "rows" labels
-        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-        String pageLabel = "";
-        String commonDisplaying = "";
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        } else {
-            pageLabel = uiLabelMap.get("CommonPage");
-            Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize));
-            commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale"));
-        }
-
-        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
-        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber)) viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
-        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber)) viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;
-
-        String str = (String) context.get("_QBESTRING_");
-
-        // strip legacy viewIndex/viewSize params from the query string
-        String queryString = UtilHttp.stripViewParamsFromQueryString(str, "" + paginatorNumber);
-
-        // strip parametrized index/size params from the query string
-        HashSet<String> paramNames = new HashSet<String>();
-        paramNames.add(viewIndexParam);
-        paramNames.add(viewSizeParam);
-        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);
-
-        String anchor = "";
-        String paginateAnchor = modelForm.getPaginateTargetAnchor();
-        if (paginateAnchor != null) anchor = "#" + paginateAnchor;
-
-        // Create separate url path String and request parameters String,
-        // add viewIndex/viewSize parameters to request parameter String
-        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
-        StringBuilder prepLinkBuffer = new StringBuilder();
-        String prepLinkQueryString = UtilHttp.getQueryStringFromTarget(targetService);
-        if (prepLinkQueryString != null) {
-            prepLinkBuffer.append(prepLinkQueryString);
-        }
-        if (prepLinkBuffer.indexOf("?") < 0) {
-            prepLinkBuffer.append("?");
-        } else if (prepLinkBuffer.indexOf("?", prepLinkBuffer.length() - 1) > 0) {
-            prepLinkBuffer.append("&amp;");
-        }
-        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
-            prepLinkBuffer.append(queryString).append("&amp;");
-        }
-        prepLinkBuffer.append(viewSizeParam).append("=").append(viewSize).append("&amp;").append(viewIndexParam).append("=");
-        String prepLinkText = prepLinkBuffer.toString();
-        if (ajaxEnabled) {
-            // Prepare params for prototype.js
-            prepLinkText = prepLinkText.replace("?", "");
-            prepLinkText = prepLinkText.replace("&amp;", "&");
-        }
-
-        writer.append("<div class=\"").append(modelForm.getPaginateStyle()).append("\">");
-        appendWhitespace(writer);
-        writer.append(" <ul>");
-        appendWhitespace(writer);
-
-        String linkText;
-
-        // First button
-        writer.append("  <li class=\"").append(modelForm.getPaginateFirstStyle());
-        if (viewIndex > 0) {
-            writer.append("\"><a href=\"");
-            if (ajaxEnabled) {
-                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + 0 + anchor, context)).append("')");
-            } else {
-                linkText = prepLinkText + 0 + anchor;
-                appendOfbizUrl(writer, urlPath + linkText);
-            }
-            writer.append("\">").append(modelForm.getPaginateFirstLabel(context)).append("</a>");
-        } else {
-            // disabled button
-            writer.append("-disabled\">").append(modelForm.getPaginateFirstLabel(context));
-        }
-        writer.append("</li>");
-        appendWhitespace(writer);
-
-        // Previous button
-        writer.append("  <li class=\"").append(modelForm.getPaginatePreviousStyle());
-        if (viewIndex > 0) {
-            writer.append("\"><a href=\"");
-            if (ajaxEnabled) {
-                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex - 1) + anchor, context)).append("')");
-            } else {
-                linkText = prepLinkText + (viewIndex - 1) + anchor;
-                appendOfbizUrl(writer, urlPath + linkText);
-            }
-            writer.append("\">").append(modelForm.getPaginatePreviousLabel(context)).append("</a>");
-        } else {
-            // disabled button
-            writer.append("-disabled\">").append(modelForm.getPaginatePreviousLabel(context));
-        }
-        writer.append("</li>");
-        appendWhitespace(writer);
-
-        // Page select dropdown
-        if (listSize > 0 && this.javaScriptEnabled) {
-            writer.append("  <li>").append(pageLabel).append(" <select name=\"page\" size=\"1\" onchange=\"");
-            if (ajaxEnabled) {
-                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + "' + this.value", context)).append(")");
-            } else {
-                linkText = prepLinkText;
-                if (linkText.startsWith("/")) {
-                    linkText = linkText.substring(1);
-                }
-                writer.append("location.href = '");
-                appendOfbizUrl(writer, urlPath + linkText);
-                writer.append("' + this.value;");
-            }
-            writer.append("\">");
-            // actual value
-            int page = 0;
-            for (int i = 0; i < listSize;) {
-                if (page == viewIndex) {
-                    writer.append("<option selected value=\"");
-                } else {
-                    writer.append("<option value=\"");
-                }
-                writer.append(Integer.toString(page));
-                writer.append("\">");
-                writer.append(Integer.toString(1 + page));
-                writer.append("</option>");
-                // increment page and calculate next index
-                page++;
-                i = page * viewSize;
-            }
-            writer.append("</select></li>");
-        }
-
-        //  show row count
-        writer.append("<li>");
-        writer.append(commonDisplaying);
-        writer.append("</li>");
-        appendWhitespace(writer);
-
-        // Next button
-        writer.append("  <li class=\"").append(modelForm.getPaginateNextStyle());
-        if (highIndex < listSize) {
-            writer.append("\"><a href=\"");
-            if (ajaxEnabled) {
-                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex + 1) + anchor, context)).append("')");
-            } else {
-                linkText = prepLinkText + (viewIndex + 1) + anchor;
-                appendOfbizUrl(writer, urlPath + linkText);
-            }
-            writer.append("\">").append(modelForm.getPaginateNextLabel(context)).append("</a>");
-        } else {
-            // disabled button
-            writer.append("-disabled\">").append(modelForm.getPaginateNextLabel(context));
-        }
-        writer.append("</li>");
-        appendWhitespace(writer);
-
-        // Last button
-        writer.append("  <li class=\"").append(modelForm.getPaginateLastStyle());
-        if (highIndex < listSize) {
-            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
-            writer.append("\"><a href=\"");
-            if (ajaxEnabled) {
-                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + lastIndex + anchor, context)).append("')");
-            } else {
-                linkText = prepLinkText + lastIndex + anchor;
-                appendOfbizUrl(writer, urlPath + linkText);
-            }
-            writer.append("\">").append(modelForm.getPaginateLastLabel(context)).append("</a>");
-        } else {
-            // disabled button
-            writer.append("-disabled\">").append(modelForm.getPaginateLastLabel(context));
-        }
-        writer.append("</li>");
-        appendWhitespace(writer);
-
-        writer.append(" </ul>");
-        appendWhitespace(writer);
-        writer.append("</div>");
-        appendWhitespace(writer);
-    }
-
-    public void renderSortField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
-        boolean ajaxEnabled = false;
-        ModelForm modelForm = modelFormField.getModelForm();
-        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnPaginateUpdateAreas();
-        String targetService = modelForm.getPaginateTarget(context);
-        if (this.javaScriptEnabled) {
-            if (UtilValidate.isNotEmpty(updateAreas)) {
-                ajaxEnabled = true;
-            }
-        }
-        if (targetService == null) {
-            targetService = "${targetService}";
-        }
-        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
-            Debug.logWarning("Cannot sort because TargetService is empty for the form: " + modelForm.getName(), module);
-            return;
-        }
-
-        String str = (String) context.get("_QBESTRING_");
-        String oldSortField = modelForm.getSortField(context);
-        String sortFieldStyle = modelFormField.getSortFieldStyle();
-
-        // if the entry-name is defined use this instead of field name
-        String columnField = modelFormField.getEntryName();
-        if (UtilValidate.isEmpty(columnField)) {
-            columnField = modelFormField.getFieldName();
-        }
-
-        // switch beetween asc/desc order
-        String newSortField = columnField;
-        if (UtilValidate.isNotEmpty(oldSortField)) {
-            if (oldSortField.equals(columnField)) {
-                newSortField = "-" + columnField;
-                sortFieldStyle = modelFormField.getSortFieldStyleDesc();
-            } else if (oldSortField.equals("-" + columnField)) {
-                newSortField = columnField;
-                sortFieldStyle = modelFormField.getSortFieldStyleAsc();
-            }
-        }
-
-        //  strip sortField param from the query string
-        HashSet<String> paramName = new HashSet<String>();
-        paramName.add("sortField");
-        String queryString = UtilHttp.stripNamedParamsFromQueryString(str, paramName);
-        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
-        StringBuilder prepLinkBuffer = new StringBuilder();
-        String prepLinkQueryString = UtilHttp.getQueryStringFromTarget(targetService);
-        if (prepLinkQueryString != null) {
-            prepLinkBuffer.append(prepLinkQueryString);
-        }
-        if (prepLinkBuffer.indexOf("?") < 0) {
-            prepLinkBuffer.append("?");
-        } else if (prepLinkBuffer.indexOf("?", prepLinkBuffer.length() - 1) > 0) {
-            prepLinkBuffer.append("&amp;");
-        }
-        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
-            prepLinkBuffer.append(queryString).append("&amp;");
-        }
-        prepLinkBuffer.append("sortField").append("=").append(newSortField);
-        String prepLinkText = prepLinkBuffer.toString();
-        if (ajaxEnabled) {
-            prepLinkText = prepLinkText.replace("?", "");
-            prepLinkText = prepLinkText.replace("&amp;", "&");
-        }
-
-        writer.append("<a");
-        if (UtilValidate.isNotEmpty(sortFieldStyle)) {
-            writer.append(" class=\"");
-            writer.append(sortFieldStyle);
-            writer.append("\"");
-        }
-
-        writer.append(" href=\"");
-        if (ajaxEnabled) {
-            writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText, context)).append("')");
-        } else {
-            appendOfbizUrl(writer, urlPath + prepLinkText);
-        }
-        writer.append("\">").append(titleText).append("</a>");
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderFileField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.FileField)
-     */
-    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-
-        writer.append("<input type=\"file\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append('"');
-
-        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(textField.getSize()));
-        writer.append('"');
-
-        Integer maxlength = textField.getMaxlength();
-        if (maxlength != null) {
-            writer.append(" maxlength=\"");
-            writer.append(maxlength.toString());
-            writer.append('"');
-        }
-
-        if (!textField.getClientAutocompleteField()) {
-            writer.append(" autocomplete=\"off\"");
-        }
-
-        writer.append("/>");
-
-        this.makeHyperlinkString(writer, textField.getSubHyperlink(), context);
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderPasswordField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.PasswordField)
-     */
-    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
-        ModelFormField modelFormField = passwordField.getModelFormField();
-
-        writer.append("<input type=\"password\"");
-
-        appendClassNames(writer, context, modelFormField);
-
-        writer.append(" name=\"");
-        writer.append(modelFormField.getParameterName(context));
-        writer.append('"');
-
-        String value = modelFormField.getEntry(context, passwordField.getDefaultValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" value=\"");
-            writer.append(value);
-            writer.append('"');
-        }
-
-        writer.append(" size=\"");
-        writer.append(Integer.toString(passwordField.getSize()));
-        writer.append('"');
-
-        Integer maxlength = passwordField.getMaxlength();
-        if (maxlength != null) {
-            writer.append(" maxlength=\"");
-            writer.append(maxlength.toString());
-            writer.append('"');
-        }
-
-        String idName = modelFormField.getCurrentContainerId(context);
-        if (UtilValidate.isNotEmpty(idName)) {
-            writer.append(" id=\"");
-            writer.append(idName);
-            writer.append('"');
-        }
-
-        if (!passwordField.getClientAutocompleteField()) {
-            writer.append(" autocomplete=\"off\"");
-        }
-
-        writer.append("/>");
-
-        this.addAsterisks(writer, context, modelFormField);
-
-        this.makeHyperlinkString(writer, passwordField.getSubHyperlink(), context);
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.form.FormStringRenderer#renderImageField(java.io.Writer, java.util.Map, org.ofbiz.widget.form.ModelFormField.ImageField)
-     */
-    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
-        ModelFormField modelFormField = imageField.getModelFormField();
-
-        writer.append("<img ");
-
-        String value = modelFormField.getEntry(context, imageField.getValue(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" src=\"");
-            appendContentUrl(writer, value);
-            writer.append('"');
-        }
-        
-        value = modelFormField.getEntry(context, imageField.getStyle(context));
-        if (UtilValidate.isNotEmpty(value)) {
-            writer.append(" class=\"");
-            appendContentUrl(writer, value);
-            writer.append('"');
-        }
-
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
-            writer.append(" ");
-            writer.append(event);
-            writer.append("=\"");
-            writer.append(action);
-            writer.append('"');
-        }
-
-        writer.append("/>");
-
-        this.makeHyperlinkString(writer, imageField.getSubHyperlink(), context);
-
-        this.appendTooltip(writer, context, modelFormField);
-
-        //appendWhitespace(writer);
-    }
-
-    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
-        String style = fieldGroup.getStyle();
-        String id = fieldGroup.getId();
-        FlexibleStringExpander titleNotExpanded = FlexibleStringExpander.getInstance(fieldGroup.getTitle());
-        String title = titleNotExpanded.expandString(context);
-        Boolean collapsed = fieldGroup.initiallyCollapsed();
-        String collapsibleAreaId = fieldGroup.getId() + "_body";
-
-        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id) || UtilValidate.isNotEmpty(title)) {
-
-            writer.append("<div class=\"fieldgroup");
-            if (UtilValidate.isNotEmpty(style)) {
-                writer.append(" ");
-                writer.append(style);
-            }
-            writer.append("\"");
-            if (UtilValidate.isNotEmpty(id)) {
-                writer.append(" id=\"");
-                writer.append(id);
-                writer.append("\"");
-            }
-            writer.append(">");
-
-            writer.append("<div class=\"fieldgroup-title-bar\"><table><tr><td class=\"collapse\">");
-
-            if (fieldGroup.collapsible()) {
-                String expandToolTip = null;
-                String collapseToolTip = null;
-                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-                //Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
-                if (uiLabelMap != null) {
-                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
-                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
-                }
-
-                writer.append("<ul><li class=\"");
-                if (collapsed) {
-                    writer.append("collapsed\"><a ");
-                    writer.append("onclick=\"javascript:toggleCollapsiblePanel(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
-                } else {
-                    writer.append("expanded\"><a ");
-                    writer.append("onclick=\"javascript:toggleCollapsiblePanel(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
-                }
-                writer.append(">&nbsp&nbsp&nbsp</a></li></ul>");
-
-                appendWhitespace(writer);
-            }
-            writer.append("</td><td>");
-
-            if (UtilValidate.isNotEmpty(title)) {
-                writer.append("<div class=\"title\">");
-                writer.append(title);
-                writer.append("</div>");
-            }
-
-            writer.append("</td></tr></table></div>");
-
-            writer.append("<div id=\"").append(collapsibleAreaId).append("\" class=\"fieldgroup-body\"");
-            if (fieldGroup.collapsible() && collapsed) {
-                writer.append(" style=\"display: none;\"");
-            }
-            writer.append(">");
-        }
-    }
-
-    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
-        String style = fieldGroup.getStyle();
-        String id = fieldGroup.getId();
-        String title = fieldGroup.getTitle();
-        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id) || UtilValidate.isNotEmpty(title)) {
-            writer.append("</div>");
-            writer.append("</div>");
-        }
-    }
-
-    // TODO: Remove embedded styling
-    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
-        writer.append(" <table width=\"100%\">  <tr>");
-        String style = banner.getStyle(context);
-        String leftStyle = banner.getLeftTextStyle(context);
-        if (UtilValidate.isEmpty(leftStyle)) leftStyle = style;
-        String rightStyle = banner.getRightTextStyle(context);
-        if (UtilValidate.isEmpty(rightStyle)) rightStyle = style;
-
-        String leftText = banner.getLeftText(context);
-        if (UtilValidate.isNotEmpty(leftText)) {
-            writer.append("   <td align=\"left\">");
-            if (UtilValidate.isNotEmpty(leftStyle)) {
-               writer.append("<div");
-               writer.append(" class=\"");
-               writer.append(leftStyle);
-               writer.append("\"");
-               writer.append(">");
-            }
-            writer.append(leftText);
-            if (UtilValidate.isNotEmpty(leftStyle)) {
-                writer.append("</div>");
-            }
-            writer.append("</td>");
-        }
-
-        String text = banner.getText(context);
-        if (UtilValidate.isNotEmpty(text)) {
-            writer.append("   <td align=\"center\">");
-            if (UtilValidate.isNotEmpty(style)) {
-               writer.append("<div");
-               writer.append(" class=\"");
-               writer.append(style);
-               writer.append("\"");
-               writer.append(">");
-            }
-            writer.append(text);
-            if (UtilValidate.isNotEmpty(style)) {
-                writer.append("</div>");
-            }
-            writer.append("</td>");
-        }
-
-        String rightText = banner.getRightText(context);
-        if (UtilValidate.isNotEmpty(rightText)) {
-            writer.append("   <td align=\"right\">");
-            if (UtilValidate.isNotEmpty(rightStyle)) {
-               writer.append("<div");
-               writer.append(" class=\"");
-               writer.append(rightStyle);
-               writer.append("\"");
-               writer.append(">");
-            }
-            writer.append(rightText);
-            if (UtilValidate.isNotEmpty(rightStyle)) {
-                writer.append("</div>");
-            }
-            writer.append("</td>");
-        }
-        writer.append("</tr> </table>");
-    }
-
-    /**
-     * Renders a link for the column header fields when there is a header-link="" specified in the <field > tag, using
-     * style from header-link-style="".  Also renders a selectAll checkbox in multi forms.
-     * @param writer
-     * @param context
-     * @param modelFormField
-     * @param titleText
-     */
-    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
-        if (UtilValidate.isNotEmpty(modelFormField.getHeaderLink())) {
-            StringBuilder targetBuffer = new StringBuilder();
-            FlexibleStringExpander target = FlexibleStringExpander.getInstance(modelFormField.getHeaderLink());
-            String fullTarget = target.expandString(context);
-            targetBuffer.append(fullTarget);
-            String targetType = CommonWidgetModels.Link.DEFAULT_URL_MODE;
-            if (UtilValidate.isNotEmpty(targetBuffer.toString()) && targetBuffer.toString().toLowerCase().startsWith("javascript:")) {
-                targetType="plain";
-            }
-            WidgetWorker.makeHyperlinkString(writer, modelFormField.getHeaderLinkStyle(), targetType, targetBuffer.toString(), null, titleText, null, modelFormField, this.request, this.response, null, null);
-        } else if (modelFormField.isSortField()) {
-            renderSortField (writer, context, modelFormField, titleText);
-        } else if (modelFormField.isRowSubmit()) {
-            if (UtilValidate.isNotEmpty(titleText)) writer.append(titleText).append("<br/>");
-            writer.append("<input type=\"checkbox\" name=\"selectAll\" value=\"Y\" onclick=\"javascript:toggleAll(this, '");
-            writer.append(modelFormField.getModelForm().getName());
-            writer.append("');\"/>");
-        } else {
-             writer.append(titleText);
-        }
-    }
-
-    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
-        writer.append("<div ");
-        String id = containerField.getModelFormField().getIdName();
-        if (UtilValidate.isNotEmpty(id)) {
-            writer.append("id=\"");
-            writer.append(id);
-            writer.append("\" ");
-        }
-        String className = containerField.getModelFormField().getWidgetStyle();
-        if (UtilValidate.isNotEmpty(className)) {
-            writer.append("class=\"");
-            writer.append(className);
-            writer.append("\" ");
-        }
-        writer.append("/>");
-    }
-
-    /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea objects. See
-     * <code>selectall.js</code>.
-     * @param updateAreas
-     * @param extraParams Renderer-supplied additional target parameters
-     * @param context
-     * @return Parameter string or empty string if no UpdateArea objects were found
-     */
-    public String createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas, String extraParams, Map<String, ? extends Object> context) {
-        if (updateAreas == null) {
-            return "";
-        }
-        StringBuilder ajaxUrl = new StringBuilder();
-        boolean firstLoop = true;
-        for (ModelForm.UpdateArea updateArea : updateAreas) {
-            if (firstLoop) {
-                firstLoop = false;
-            } else {
-                ajaxUrl.append(",");
-            }
-            String targetUrl = updateArea.getAreaTarget(context);
-            String ajaxParams = getAjaxParamsFromTarget(targetUrl);
-            if (UtilValidate.isNotEmpty(extraParams)) {
-                if (ajaxParams.length() > 0 && !extraParams.startsWith("&")) {
-                    ajaxParams += "&";
-                }
-                ajaxParams += extraParams;
-            }
-            ajaxUrl.append(updateArea.getAreaId()).append(",");
-            try {
-                appendOfbizUrl(ajaxUrl, UtilHttp.removeQueryStringFromTarget(targetUrl));
-            } catch (IOException e) {
-                throw UtilMisc.initCause(new InternalError(e.getMessage()), e);
-            }
-            ajaxUrl.append(",").append(ajaxParams);
-        }
-        return ajaxUrl.toString();
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.base.util.template.FreeMarkerWorker;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.webapp.control.RequestHandler;
+import org.ofbiz.webapp.taglib.ContentUrlTag;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.CommonWidgetModels;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelFormField;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayEntityField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.FormRenderer;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.Paginator;
+import org.ofbiz.widget.renderer.UtilHelpText;
+import org.ofbiz.widget.renderer.macro.MacroFormRenderer;
+
+import freemarker.template.TemplateException;
+
+/**
+ * Widget Library - HTML Form Renderer implementation
+ */
+public class HtmlFormRenderer extends HtmlWidgetRenderer implements FormStringRenderer {
+
+    public static final String module = HtmlFormRenderer.class.getName();
+
+    protected HttpServletRequest request;
+    protected HttpServletResponse response;
+    protected RequestHandler rh;
+    protected String lastFieldGroupId = "";
+    protected boolean renderPagination = true;
+    protected boolean javaScriptEnabled = false;
+    private UtilCodec.SimpleEncoder internalEncoder;
+
+    protected HtmlFormRenderer() {}
+
+    public HtmlFormRenderer(HttpServletRequest request, HttpServletResponse response) {
+        this.request = request;
+        this.response = response;
+        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+        this.rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+        this.javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
+        internalEncoder = UtilCodec.getEncoder("string");
+    }
+
+    public boolean getRenderPagination() {
+        return this.renderPagination;
+    }
+
+    public void setRenderPagination(boolean renderPagination) {
+        this.renderPagination = renderPagination;
+    }
+
+    public void appendOfbizUrl(Appendable writer, String location) throws IOException {
+        writer.append(this.rh.makeLink(this.request, this.response, location));
+    }
+
+    public void appendContentUrl(Appendable writer, String location) throws IOException {
+        ContentUrlTag.appendContentPrefix(this.request, writer);
+        writer.append(location);
+    }
+
+    public void appendTooltip(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        // render the tooltip, in other methods too
+        String tooltip = modelFormField.getTooltip(context);
+        if (UtilValidate.isNotEmpty(tooltip)) {
+            writer.append("<span class=\"");
+            String tooltipStyle = modelFormField.getTooltipStyle();
+            if (UtilValidate.isNotEmpty(tooltipStyle)) {
+                writer.append(tooltipStyle);
+            } else {
+                writer.append("tooltip");
+            }
+            writer.append("\">");
+            writer.append(tooltip);
+            writer.append("</span>");
+        }
+    }
+
+    public void addAsterisks(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+
+        boolean requiredField = modelFormField.getRequiredField();
+        if (requiredField) {
+            String requiredStyle = modelFormField.getRequiredFieldStyle();
+
+            if (UtilValidate.isEmpty(requiredStyle)) {
+               writer.append("*");
+            }
+        }
+    }
+
+    public void appendClassNames(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        String className = modelFormField.getWidgetStyle();
+        if (UtilValidate.isNotEmpty(className) || modelFormField.shouldBeRed(context)) {
+            writer.append(" class=\"");
+            writer.append(className);
+            // add a style of red if redWhen is true
+            if (modelFormField.shouldBeRed(context)) {
+                writer.append(" alert");
+            }
+            writer.append('"');
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderDisplayField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.DisplayField)
+     */
+    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
+        ModelFormField modelFormField = displayField.getModelFormField();
+
+        StringBuilder str = new StringBuilder();
+
+        String idName = modelFormField.getCurrentContainerId(context);
+
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle()) || modelFormField.shouldBeRed(context)) {
+            str.append("<span class=\"");
+            str.append(modelFormField.getWidgetStyle());
+            // add a style of red if this is a date/time field and redWhen is true
+            if (modelFormField.shouldBeRed(context)) {
+                str.append(" alert");
+            }
+            str.append('"');
+            if (UtilValidate.isNotEmpty(idName)) {
+                str.append(" id=\"");
+                str.append(idName+"_sp");
+                str.append('"');
+            }
+            str.append('>');
+        }
+
+        if (str.length() > 0) {
+            writer.append(str.toString());
+        }
+        String description = displayField.getDescription(context);
+        //Replace new lines with <br/>
+        description = description.replaceAll("\n", "<br/>");
+
+        if (UtilValidate.isEmpty(description)) {
+            this.renderFormatEmptySpace(writer, context, modelFormField.getModelForm());
+        } else {
+            writer.append(description);
+        }
+
+        if (str.length() > 0) {
+            writer.append("</span>");
+        }
+
+        ModelFormField.InPlaceEditor inPlaceEditor = displayField.getInPlaceEditor();
+        boolean ajaxEnabled = inPlaceEditor != null && this.javaScriptEnabled;
+
+        if (ajaxEnabled) {
+            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
+            StringBuilder url = new StringBuilder(inPlaceEditor.getUrl(context));
+            Map<String, Object> fieldMap = inPlaceEditor.getFieldMap(context);
+            if (fieldMap != null) {
+                url.append('?');
+                int count = 0;
+                for (Entry<String, Object> field: fieldMap.entrySet()) {
+                    count++;
+                    url.append(field.getKey()).append('=').append(field.getValue());
+                    if (count < fieldMap.size()) {
+                        url.append('&');
+                    }
+                }
+            }
+            writer.append("ajaxInPlaceEditDisplayField('");
+            writer.append(idName).append("', '").append(url).append("', {");
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getParamName())) {
+                writer.append("name: '").append(inPlaceEditor.getParamName()).append("'");
+            } else {
+                writer.append("name: '").append(modelFormField.getFieldName()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelControl())) {
+                writer.append(", cancelControl: ");
+                if (!"false".equals(inPlaceEditor.getCancelControl())) {
+                    writer.append("'");
+                }
+                writer.append(inPlaceEditor.getCancelControl());
+                if (!"false".equals(inPlaceEditor.getCancelControl())) {
+                    writer.append("'");
+                }
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelText())) {
+                writer.append(", cancel: '").append(inPlaceEditor.getCancelText()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getClickToEditText())) {
+                writer.append(", tooltip: '").append(inPlaceEditor.getClickToEditText()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getFieldPostCreation())) {
+                writer.append(", fieldPostCreation: ");
+                if (!"false".equals(inPlaceEditor.getFieldPostCreation())) {
+                    writer.append("'");
+                }
+                writer.append(inPlaceEditor.getFieldPostCreation());
+                if (!"false".equals(inPlaceEditor.getFieldPostCreation())) {
+                    writer.append("'");
+                }
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getFormClassName())) {
+                writer.append(", cssclass: '").append(inPlaceEditor.getFormClassName()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getHighlightColor())) {
+                writer.append(", highlightColor: '").append(inPlaceEditor.getHighlightColor()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getHighlightEndColor())) {
+                writer.append(", highlightEndColor: '").append(inPlaceEditor.getHighlightEndColor()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getHoverClassName())) {
+                writer.append(", hoverClassName: '").append(inPlaceEditor.getHoverClassName()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getHtmlResponse())) {
+                writer.append(", htmlResponse: ").append(inPlaceEditor.getHtmlResponse());
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingClassName())) {
+                writer.append(", loadingClassName: '").append(inPlaceEditor.getLoadingClassName()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingText())) {
+                writer.append(", indicator: '").append(inPlaceEditor.getLoadingText()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getOkControl())) {
+                writer.append(", submit: ");
+                if (!"false".equals(inPlaceEditor.getOkControl())) {
+                    writer.append("'");
+                }
+                writer.append(inPlaceEditor.getOkControl());
+                if (!"false".equals(inPlaceEditor.getOkControl())) {
+                    writer.append("'");
+                }
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getOkText())) {
+                writer.append(", okText: '").append(inPlaceEditor.getOkText()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getSavingClassName())) {
+                writer.append(", savingClassName: '").append(inPlaceEditor.getSavingClassName()).append("', ");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getSavingText())) {
+                writer.append(", savingText: '").append(inPlaceEditor.getSavingText()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getSubmitOnBlur())) {
+                writer.append(", submitOnBlur: ").append(inPlaceEditor.getSubmitOnBlur());
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextBeforeControls())) {
+                writer.append(", textBeforeControls: '").append(inPlaceEditor.getTextBeforeControls()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextAfterControls())) {
+                writer.append(", textAfterControls: '").append(inPlaceEditor.getTextAfterControls()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getTextBetweenControls())) {
+                writer.append(", textBetweenControls: '").append(inPlaceEditor.getTextBetweenControls()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getUpdateAfterRequestCall())) {
+                writer.append(", updateAfterRequestCall: ").append(inPlaceEditor.getUpdateAfterRequestCall());
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getRows())) {
+                writer.append(", rows: '").append(inPlaceEditor.getRows()).append("'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getCols())) {
+                writer.append(", cols: '").append(inPlaceEditor.getCols()).append("'");
+            }
+            writer.append("});");
+            writer.append("</script>");
+        }
+
+        if (displayField instanceof DisplayEntityField) {
+            this.makeHyperlinkString(writer, ((DisplayEntityField) displayField).getSubHyperlink(), context);
+        }
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderHyperlinkField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.HyperlinkField)
+     */
+    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
+        this.request.setAttribute("image", hyperlinkField.getImageLocation(context));
+        ModelFormField modelFormField = hyperlinkField.getModelFormField();
+        String description = encode(hyperlinkField.getDescription(context), modelFormField, context);
+        String confirmation = encode(hyperlinkField.getConfirmation(context), modelFormField, context);
+        WidgetWorker.makeHyperlinkByType(writer, hyperlinkField.getLinkType(), modelFormField.getWidgetStyle(), hyperlinkField.getUrlMode(), hyperlinkField.getTarget(context),
+                hyperlinkField.getParameterMap(context), description, hyperlinkField.getTargetWindow(context), confirmation, modelFormField,
+                this.request, this.response, context);
+        this.appendTooltip(writer, context, modelFormField);
+        //appendWhitespace(writer);
+    }
+
+    public void makeHyperlinkString(Appendable writer, ModelFormField.SubHyperlink subHyperlink, Map<String, Object> context) throws IOException {
+        if (subHyperlink == null) {
+            return;
+        }
+        if (subHyperlink.shouldUse(context)) {
+            writer.append(' ');
+            String description = encode(subHyperlink.getDescription(context), subHyperlink.getModelFormField(), context);
+            WidgetWorker.makeHyperlinkByType(writer, subHyperlink.getLinkType(), subHyperlink.getStyle(context), subHyperlink.getUrlMode(), subHyperlink.getTarget(context),
+                    subHyperlink.getParameterMap(context), description, subHyperlink.getTargetWindow(context), null, subHyperlink.getModelFormField(),
+                    this.request, this.response, context);
+        }
+    }
+
+    private String encode(String value, ModelFormField modelFormField, Map<String, Object> context) {
+        if (UtilValidate.isEmpty(value)) {
+            return value;
+        }
+        UtilCodec.SimpleEncoder encoder = (UtilCodec.SimpleEncoder)context.get("simpleEncoder");
+        if (modelFormField.getEncodeOutput() && encoder != null) {
+            value = encoder.encode(value);
+        } else {
+            value = internalEncoder.encode(value);
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.TextField)
+     */
+    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+
+        writer.append("<input type=\"text\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append('"');
+
+        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(textField.getSize()));
+        writer.append('"');
+
+        Integer maxlength = textField.getMaxlength();
+        if (maxlength != null) {
+            writer.append(" maxlength=\"");
+            writer.append(maxlength.toString());
+            writer.append('"');
+        }
+
+        String idName = modelFormField.getCurrentContainerId(context);
+        if (UtilValidate.isNotEmpty(idName)) {
+            writer.append(" id=\"");
+            writer.append(idName);
+            writer.append('"');
+        }
+
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
+            writer.append(" ");
+            writer.append(event);
+            writer.append("=\"");
+            writer.append(action);
+            writer.append('"');
+        }
+
+        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
+        boolean ajaxEnabled = updateAreas != null && this.javaScriptEnabled;
+        if (!textField.getClientAutocompleteField() || ajaxEnabled) {
+            writer.append(" autocomplete=\"off\"");
+        }
+
+        writer.append("/>");
+
+        this.addAsterisks(writer, context, modelFormField);
+
+        this.makeHyperlinkString(writer, textField.getSubHyperlink(), context);
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        if (ajaxEnabled) {
+            appendWhitespace(writer);
+            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
+            appendWhitespace(writer);
+            writer.append("ajaxAutoCompleter('").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context)).append("');");
+            appendWhitespace(writer);
+            writer.append("</script>");
+        }
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextareaField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.TextareaField)
+     */
+    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
+        ModelFormField modelFormField = textareaField.getModelFormField();
+
+        writer.append("<textarea");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append('"');
+
+        writer.append(" cols=\"");
+        writer.append(Integer.toString(textareaField.getCols()));
+        writer.append('"');
+
+        writer.append(" rows=\"");
+        writer.append(Integer.toString(textareaField.getRows()));
+        writer.append('"');
+
+        String idName = modelFormField.getCurrentContainerId(context);
+        if (UtilValidate.isNotEmpty(idName)) {
+            writer.append(" id=\"");
+            writer.append(idName);
+            writer.append('"');
+        } else if (textareaField.getVisualEditorEnable()) {
+            writer.append(" id=\"");
+            writer.append("htmlEditArea");
+            writer.append('"');
+        }
+
+        if (textareaField.isReadOnly()) {
+            writer.append(" readonly");
+        }
+
+        writer.append('>');
+
+        String value = modelFormField.getEntry(context, textareaField.getDefaultValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(value);
+        }
+
+        writer.append("</textarea>");
+
+        if (textareaField.getVisualEditorEnable()) {
+            writer.append("<script language=\"javascript\" src=\"/images/jquery/plugins/elrte-1.3/js/elrte.min.js\" type=\"text/javascript\"></script>");
+            writer.append("<link href=\"/images/jquery/plugins/elrte-1.3/css/elrte.min.css\" rel=\"stylesheet\" type=\"text/css\">");
+            writer.append("<script language=\"javascript\" type=\"text/javascript\"> var opts = { cssClass : 'el-rte', toolbar : ");
+            // define the toolsbar
+            String buttons = textareaField.getVisualEditorButtons(context);
+            if (UtilValidate.isNotEmpty(buttons)) {
+                writer.append(buttons);
+            } else {
+                writer.append("maxi");
+            }
+            writer.append(", doctype  : '<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">', //'<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\">'");
+            writer.append(", cssfiles : ['/images/jquery/plugins/elrte-1.3/css/elrte-inner.css'] ");
+            writer.append("}");
+            // load the wysiwyg editor
+            writer.append("jQuery('#");
+            if (UtilValidate.isNotEmpty(idName)) {
+                writer.append(idName);
+            } else {
+                writer.append("htmlEditArea");
+            }
+            writer.append("').elrte(opts);");
+            writer.append("</script>");
+        }
+
+        this.addAsterisks(writer, context, modelFormField);
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderDateTimeField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.DateTimeField)
+     */
+    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
+        String macroLibraryPath = UtilProperties.getPropertyValue("widget", "screen.formrenderer");
+        try {
+            MacroFormRenderer macroFormRenderer = new MacroFormRenderer(macroLibraryPath, this.request, this.response);
+            macroFormRenderer.renderDateTimeField(writer, context, dateTimeField);
+        } catch (TemplateException e) {
+            Debug.logError(e, "Error rendering screen thru ftl macro: renderDateTimeField", module);
+        } catch (IOException e) {
+            Debug.logError(e, "Error rendering screen thru ftl, macro: renderDateTimeField", module);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderDropDownField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.DropDownField)
+     */
+    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
+        ModelFormField modelFormField = dropDownField.getModelFormField();
+        ModelForm modelForm = modelFormField.getModelForm();
+        ModelFormField.AutoComplete autoComplete = dropDownField.getAutoComplete();
+        boolean ajaxEnabled = autoComplete != null && this.javaScriptEnabled;
+        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+
+        String currentValue = modelFormField.getEntry(context);
+        // Get the current value's description from the option value. If there
+        // is a localized version it will be there.
+        String currentDescription = null;
+        if (UtilValidate.isNotEmpty(currentValue)) {
+            for (ModelFormField.OptionValue optionValue : allOptionValues) {
+                if (encode(optionValue.getKey(), modelFormField, context).equals(currentValue)) {
+                    currentDescription = optionValue.getDescription();
+                    break;
+                }
+            }
+        }
+
+        if (ajaxEnabled) {
+            writer.append("<input type=\"text\"");
+        } else {
+            writer.append("<select");
+        }
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+
+        String idName = modelFormField.getCurrentContainerId(context);
+
+        if (ajaxEnabled) {
+            writer.append("_description\"");
+
+            String textFieldIdName = idName;
+            if (UtilValidate.isNotEmpty(textFieldIdName)) {
+                textFieldIdName += "_description";
+                writer.append(" id=\"");
+                writer.append(textFieldIdName);
+                writer.append('"');
+            }
+
+            if (UtilValidate.isNotEmpty(currentValue)) {
+                writer.append(" value=\"");
+                String explicitDescription = null;
+                if (currentDescription != null) {
+                    explicitDescription = currentDescription;
+                } else {
+                    explicitDescription = dropDownField.getCurrentDescription(context);
+                }
+                if (UtilValidate.isEmpty(explicitDescription)) {
+                    explicitDescription = FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues);
+                }
+                explicitDescription = encode(explicitDescription, modelFormField, context);
+                writer.append(explicitDescription);
+                writer.append('"');
+            }
+            writer.append("/>");
+
+            appendWhitespace(writer);
+            writer.append("<input type=\"hidden\" name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append('"');
+            if (UtilValidate.isNotEmpty(idName)) {
+                writer.append(" id=\"");
+                writer.append(idName);
+                writer.append('"');
+            }
+
+            if (UtilValidate.isNotEmpty(currentValue)) {
+                writer.append(" value=\"");
+                //String explicitDescription = dropDownField.getCurrentDescription(context);
+                writer.append(currentValue);
+                writer.append('"');
+            }
+
+            writer.append("/>");
+
+            appendWhitespace(writer);
+            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
+            appendWhitespace(writer);
+            writer.append("var data = {");
+            int count = 0;
+            for (ModelFormField.OptionValue optionValue: allOptionValues) {
+                count++;
+                writer.append(optionValue.getKey()).append(": ");
+                writer.append(" '").append(optionValue.getDescription()).append("'");
+                if (count != allOptionValues.size()) {
+                    writer.append(", ");
+                }
+            }
+            writer.append("};");
+            appendWhitespace(writer);
+            writer.append("ajaxAutoCompleteDropDown('").append(textFieldIdName).append("', '").append(idName).append("', data, {autoSelect: ").append(
+                    autoComplete.getAutoSelect()).append(", frequency: ").append(autoComplete.getFrequency()).append(", minChars: ").append(autoComplete.getMinChars()).append(
+                    ", choices: ").append(autoComplete.getChoices()).append(", partialSearch: ").append(autoComplete.getPartialSearch()).append(
+                    ", partialChars: ").append(autoComplete.getPartialChars()).append(", ignoreCase: ").append(autoComplete.getIgnoreCase()).append(
+                    ", fullSearch: ").append(autoComplete.getFullSearch()).append("});");
+            appendWhitespace(writer);
+            writer.append("</script>");
+        } else {
+            writer.append('"');
+
+            if (UtilValidate.isNotEmpty(idName)) {
+                writer.append(" id=\"");
+                writer.append(idName);
+                writer.append('"');
+            }
+
+            if (dropDownField.getAllowMultiple()) {
+                writer.append(" multiple=\"multiple\"");
+            }
+
+            int otherFieldSize = dropDownField.getOtherFieldSize();
+            String otherFieldName = dropDownField.getParameterNameOther(context);
+            if (otherFieldSize > 0) {
+                //writer.append(" onchange=\"alert('ONCHANGE, process_choice:' + process_choice)\"");
+                //writer.append(" onchange='test_js()' ");
+                writer.append(" onchange=\"process_choice(this,document.");
+                writer.append(modelForm.getName());
+                writer.append(".");
+                writer.append(otherFieldName);
+                writer.append(")\" ");
+            }
+
+            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
+                writer.append(" ");
+                writer.append(event);
+                writer.append("=\"");
+                writer.append(action);
+                writer.append('"');
+            }
+
+            writer.append(" size=\"").append(dropDownField.getSize()).append("\">");
+
+            // if the current value should go first, stick it in
+            if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
+                writer.append("<option");
+                writer.append(" selected=\"selected\"");
+                writer.append(" value=\"");
+                writer.append(currentValue);
+                writer.append("\">");
+                String explicitDescription = (currentDescription != null ? currentDescription : dropDownField.getCurrentDescription(context));
+                if (UtilValidate.isNotEmpty(explicitDescription)) {
+                    writer.append(encode(explicitDescription, modelFormField, context));
+                } else {
+                    String description = FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues);
+                    writer.append(encode(description, modelFormField, context));
+                }
+                writer.append("</option>");
+
+                // add a "separator" option
+                writer.append("<option value=\"");
+                writer.append(currentValue);
+                writer.append("\">---</option>");
+            }
+
+            // if allow empty is true, add an empty option
+            if (dropDownField.getAllowEmpty()) {
+                writer.append("<option value=\"\">&nbsp;</option>");
+            }
+
+            // list out all options according to the option list
+            for (ModelFormField.OptionValue optionValue: allOptionValues) {
+                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
+                writer.append("<option");
+                // if current value should be selected in the list, select it
+                if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) {
+                    writer.append(" selected=\"selected\"");
+                } else if (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey())) {
+                    writer.append(" selected=\"selected\"");
+                }
+                writer.append(" value=\"");
+                writer.append(encode(optionValue.getKey(), modelFormField, context));
+                writer.append("\">");
+                writer.append(encode(optionValue.getDescription(), modelFormField, context));
+                writer.append("</option>");
+            }
+
+            writer.append("</select>");
+
+
+            // Adapted from work by Yucca Korpela
+            // http://www.cs.tut.fi/~jkorpela/forms/combo.html
+            if (otherFieldSize > 0) {
+
+                String fieldName = modelFormField.getParameterName(context);
+                Map<String, Object> dataMap = UtilGenerics.checkMap(modelFormField.getMap(context));
+                if (dataMap == null) {
+                    dataMap = context;
+                }
+                Object otherValueObj = dataMap.get(otherFieldName);
+                String otherValue = (otherValueObj == null) ? "" : otherValueObj.toString();
+
+                writer.append("<noscript>");
+                writer.append("<input type='text' name='");
+                writer.append(otherFieldName);
+                writer.append("'/> ");
+                writer.append("</noscript>");
+                writer.append("\n<script type='text/javascript' language='JavaScript'><!--");
+                writer.append("\ndisa = ' disabled';");
+                writer.append("\nif (other_choice(document.");
+                writer.append(modelForm.getName());
+                writer.append(".");
+                writer.append(fieldName);
+                writer.append(")) disa = '';");
+                writer.append("\ndocument.write(\"<input type=");
+                writer.append("'text' name='");
+                writer.append(otherFieldName);
+                writer.append("' value='");
+                writer.append(otherValue);
+                writer.append("' size='");
+                writer.append(Integer.toString(otherFieldSize));
+                writer.append("' ");
+                writer.append("\" +disa+ \" onfocus='check_choice(document.");
+                writer.append(modelForm.getName());
+                writer.append(".");
+                writer.append(fieldName);
+                writer.append(")'/>\");");
+                writer.append("\nif (disa && document.styleSheets)");
+                writer.append(" document.");
+                writer.append(modelForm.getName());
+                writer.append(".");
+                writer.append(otherFieldName);
+                writer.append(".style.visibility  = 'hidden';");
+                writer.append("\n//--></script>");
+            }
+        }
+
+        this.makeHyperlinkString(writer, dropDownField.getSubHyperlink(), context);
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderCheckField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.CheckField)
+     */
+    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
+        ModelFormField modelFormField = checkField.getModelFormField();
+        String currentValue = modelFormField.getEntry(context);
+        Boolean allChecked = checkField.isAllChecked(context);
+
+        List<ModelFormField.OptionValue> allOptionValues = checkField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+
+        // list out all options according to the option list
+        for (ModelFormField.OptionValue optionValue: allOptionValues) {
+
+            writer.append("<input type=\"checkbox\"");
+
+            appendClassNames(writer, context, modelFormField);
+
+            // if current value should be selected in the list, select it
+            if (Boolean.TRUE.equals(allChecked)) {
+                writer.append(" checked=\"checked\"");
+            } else if (Boolean.FALSE.equals(allChecked)) {
+                // do nothing
+            } else if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey())) {
+                writer.append(" checked=\"checked\"");
+            }
+            writer.append(" name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append('"');
+            writer.append(" value=\"");
+            writer.append(encode(optionValue.getKey(), modelFormField, context));
+            writer.append("\"");
+
+            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
+                writer.append(" ");
+                writer.append(event);
+                writer.append("=\"");
+                writer.append(action);
+                writer.append('"');
+            }
+
+            writer.append("/>");
+
+            writer.append(encode(optionValue.getDescription(), modelFormField, context));
+        }
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderRadioField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.RadioField)
+     */
+    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
+        ModelFormField modelFormField = radioField.getModelFormField();
+        List<ModelFormField.OptionValue> allOptionValues = radioField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+        String currentValue = modelFormField.getEntry(context);
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+
+        // list out all options according to the option list
+        for (ModelFormField.OptionValue optionValue: allOptionValues) {
+
+            writer.append("<span");
+
+            appendClassNames(writer, context, modelFormField);
+
+            writer.append("><input type=\"radio\"");
+
+            // if current value should be selected in the list, select it
+            String noCurrentSelectedKey = radioField.getNoCurrentSelectedKey(context);
+            if (UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey())) {
+                writer.append(" checked=\"checked\"");
+            } else if (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey())) {
+                writer.append(" checked=\"checked\"");
+            }
+            writer.append(" name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append('"');
+            writer.append(" value=\"");
+            writer.append(encode(optionValue.getKey(), modelFormField, context));
+            writer.append("\"");
+
+            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
+                writer.append(" ");
+                writer.append(event);
+                writer.append("=\"");
+                writer.append(action);
+                writer.append('"');
+            }
+
+            writer.append("/>");
+
+            writer.append(encode(optionValue.getDescription(), modelFormField, context));
+            writer.append("</span>");
+        }
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderSubmitField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.SubmitField)
+     */
+    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
+        ModelFormField modelFormField = submitField.getModelFormField();
+        ModelForm modelForm = modelFormField.getModelForm();
+        String event = null;
+        String action = null;
+        String confirmation =  encode(submitField.getConfirmation(context), modelFormField, context);
+
+        if ("text-link".equals(submitField.getButtonType())) {
+            writer.append("<a");
+
+            appendClassNames(writer, context, modelFormField);
+            if (UtilValidate.isNotEmpty(confirmation)) {
+                writer.append(" onclick=\"return confirm('");
+                writer.append(confirmation);
+                writer.append("'); \" ");
+            }
+
+            writer.append(" href=\"javascript:document.");
+            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
+            writer.append(".submit()\">");
+
+            writer.append(encode(modelFormField.getTitle(context), modelFormField, context));
+
+            writer.append("</a>");
+        } else if ("image".equals(submitField.getButtonType())) {
+            writer.append("<input type=\"image\"");
+
+            appendClassNames(writer, context, modelFormField);
+
+            writer.append(" name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append('"');
+
+            String title = modelFormField.getTitle(context);
+            if (UtilValidate.isNotEmpty(title)) {
+                writer.append(" alt=\"");
+                writer.append(encode(title, modelFormField, context));
+                writer.append('"');
+            }
+
+            writer.append(" src=\"");
+            this.appendContentUrl(writer, submitField.getImageLocation(context));
+            writer.append('"');
+
+            event = modelFormField.getEvent();
+            action = modelFormField.getAction(context);
+            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
+                writer.append(" ");
+                writer.append(event);
+                writer.append("=\"");
+                writer.append(action);
+                writer.append('"');
+            }
+
+            if (UtilValidate.isNotEmpty(confirmation)) {
+                writer.append("onclick=\" return confirm('");
+                writer.append(confirmation);
+                writer.append("); \" ");
+            }
+
+            writer.append("/>");
+        } else {
+            // default to "button"
+
+            String formId = modelForm.getContainerId();
+            List<ModelForm.UpdateArea> updateAreas = modelForm.getOnSubmitUpdateAreas();
+            // This is here for backwards compatibility. Use on-event-update-area
+            // elements instead.
+            String backgroundSubmitRefreshTarget = submitField.getBackgroundSubmitRefreshTarget(context);
+            if (UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) {
+                if (updateAreas == null) {
+                    updateAreas = new LinkedList<ModelForm.UpdateArea>();
+                }
+                updateAreas.add(new ModelForm.UpdateArea("submit", formId, backgroundSubmitRefreshTarget));
+            }
+
+            boolean ajaxEnabled = (UtilValidate.isNotEmpty(updateAreas) || UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) && this.javaScriptEnabled;
+            if (ajaxEnabled) {
+                writer.append("<input type=\"button\"");
+            } else {
+                writer.append("<input type=\"submit\"");
+            }
+
+            appendClassNames(writer, context, modelFormField);
+
+            writer.append(" name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append('"');
+
+            String title = modelFormField.getTitle(context);
+            if (UtilValidate.isNotEmpty(title)) {
+                writer.append(" value=\"");
+                writer.append(encode(title, modelFormField, context));
+                writer.append('"');
+            }
+
+
+            event = modelFormField.getEvent();
+            action = modelFormField.getAction(context);
+            if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
+                writer.append(" ");
+                writer.append(event);
+                writer.append("=\"");
+                writer.append(action);
+                writer.append('"');
+            } else {
+                //add single click JS onclick
+                // disabling for now, using form onSubmit action instead: writer.append(singleClickAction);
+            }
+
+            if (ajaxEnabled) {
+                writer.append(" onclick=\"");
+                if (UtilValidate.isNotEmpty(confirmation)) {
+                    writer.append("if  (confirm('");
+                    writer.append(confirmation);
+                    writer.append(");) ");
+                }
+                writer.append("ajaxSubmitFormUpdateAreas('");
+                writer.append(formId);
+                writer.append("', '").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context));
+                writer.append("')\"");
+            }
+
+            writer.append("/>");
+        }
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderResetField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.ResetField)
+     */
+    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
+        ModelFormField modelFormField = resetField.getModelFormField();
+
+        writer.append("<input type=\"reset\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append('"');
+
+        String title = modelFormField.getTitle(context);
+        if (UtilValidate.isNotEmpty(title)) {
+            writer.append(" value=\"");
+            writer.append(encode(title, modelFormField, context));
+            writer.append('"');
+        }
+
+        writer.append("/>");
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderHiddenField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.HiddenField)
+     */
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
+        ModelFormField modelFormField = hiddenField.getModelFormField();
+        String value = hiddenField.getValue(context);
+        this.renderHiddenField(writer, context, modelFormField, value);
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
+        writer.append("<input type=\"hidden\"");
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append('"');
+
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append("/>");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderIgnoredField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.IgnoredField)
+     */
+    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) throws IOException {
+        // do nothing, it's an ignored field; could add a comment or something if we wanted to
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFieldTitle(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField)
+     */
+    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        String tempTitleText = modelFormField.getTitle(context);
+        String titleText = UtilHttp.encodeAmpersands(tempTitleText);
+
+        if (UtilValidate.isNotEmpty(titleText)) {
+            // copied from MacroFormRenderer renderFieldTitle
+            String displayHelpText = UtilProperties.getPropertyValue("widget.properties", "widget.form.displayhelpText");
+            String helpText = null;
+            if ("Y".equals(displayHelpText)) {
+                Delegator delegator = WidgetWorker.getDelegator(context);
+                Locale locale = (Locale)context.get("locale");
+                String entityName = modelFormField.getEntityName();
+                String fieldName = modelFormField.getFieldName();
+                helpText = UtilHelpText.getEntityFieldDescription(entityName, fieldName, delegator, locale);
+            }
+            if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle()) || UtilValidate.isNotEmpty(helpText)) {
+                writer.append("<span");
+                if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())){
+                    writer.append(" class=\"");
+                    writer.append(modelFormField.getTitleStyle());
+                }
+                if (UtilValidate.isNotEmpty(helpText)){
+                    writer.append(" title=\"");
+                    writer.append(FreeMarkerWorker.encodeDoubleQuotes(helpText));
+                }
+                writer.append("\">");
+            }
+            if (" ".equals(titleText)) {
+                // If the title content is just a blank then render it colling renderFormatEmptySpace:
+                // the method will set its content to work fine in most browser
+                this.renderFormatEmptySpace(writer, context, modelFormField.getModelForm());
+            } else {
+                renderHyperlinkTitle(writer, context, modelFormField, titleText);
+            }
+
+            if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+                writer.append("</span>");
+            }
+
+            //appendWhitespace(writer);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFieldTitle(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField)
+     */
+    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        boolean requiredField = modelFormField.getRequiredField();
+        if (requiredField) {
+
+            String requiredStyle = modelFormField.getRequiredFieldStyle();
+            if (UtilValidate.isEmpty(requiredStyle)) {
+                requiredStyle = modelFormField.getTitleStyle();
+            }
+
+            if (UtilValidate.isNotEmpty(requiredStyle)) {
+                writer.append("<span class=\"");
+                writer.append(requiredStyle);
+                writer.append("\">");
+            }
+            renderHyperlinkTitle(writer, context, modelFormField, modelFormField.getTitle(context));
+            if (UtilValidate.isNotEmpty(requiredStyle)) {
+                writer.append("</span>");
+            }
+
+            //appendWhitespace(writer);
+        } else {
+            renderFieldTitle(writer, context, modelFormField);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+        renderBeginningBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        writer.append("<form method=\"post\" ");
+        String targetType = modelForm.getTargetType();
+        String targ = modelForm.getTarget(context, targetType);
+        // The 'action' attribute is mandatory in a form definition,
+        // even if it is empty.
+        writer.append(" action=\"");
+        if (UtilValidate.isNotEmpty(targ)) {
+            //this.appendOfbizUrl(writer, "/" + targ);
+            WidgetWorker.buildHyperlinkUrl(writer, targ, targetType, null, null, false, false, true, request, response, context);
+        }
+        writer.append("\" ");
+
+        String formType = modelForm.getType();
+        if (formType.equals("upload")) {
+            writer.append(" enctype=\"multipart/form-data\"");
+        }
+
+        String targetWindow = modelForm.getTargetWindow(context);
+        if (UtilValidate.isNotEmpty(targetWindow)) {
+            writer.append(" target=\"");
+            writer.append(targetWindow);
+            writer.append("\"");
+        }
+
+        String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
+        if (UtilValidate.isNotEmpty(containerId)) {
+            writer.append(" id=\"");
+            writer.append(containerId);
+            writer.append("\"");
+        }
+
+        writer.append(" class=\"");
+        String containerStyle =  modelForm.getContainerStyle();
+        if (UtilValidate.isNotEmpty(containerStyle)) {
+            writer.append(containerStyle);
+        } else {
+            writer.append("basic-form");
+        }
+        writer.append("\"");
+
+        writer.append(" onsubmit=\"javascript:submitFormDisableSubmits(this)\"");
+
+        if (!modelForm.getClientAutocompleteFields()) {
+            writer.append(" autocomplete=\"off\"");
+        }
+
+        writer.append(" name=\"");
+        writer.append(FormRenderer.getCurrentContainerId(modelForm, context));
+        writer.append("\">");
+
+        boolean useRowSubmit = modelForm.getUseRowSubmit();
+        if (useRowSubmit) {
+            writer.append("<input type=\"hidden\" name=\"_useRowSubmit\" value=\"Y\"/>");
+        }
+
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</form>");
+        String focusFieldName = FormRenderer.getFocusFieldName(modelForm, context);
+        if (UtilValidate.isNotEmpty(focusFieldName)) {
+            appendWhitespace(writer);
+            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
+            appendWhitespace(writer);
+            writer.append("document.").append(FormRenderer.getCurrentFormName(modelForm, context)).append(".");
+            writer.append(focusFieldName).append(".focus();");
+            appendWhitespace(writer);
+            writer.append("</script>");
+        }
+        appendWhitespace(writer);
+        renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        for (ModelFormField submitField: modelForm.getMultiSubmitFields()) {
+            if (submitField != null) {
+
+                // Threw this in that as a hack to keep the submit button from expanding the first field
+                // Needs a more rugged solution
+                // WARNING: this method (renderMultiFormClose) must be called after the
+                // table that contains the list has been closed (to avoid validation errors) so
+                // we cannot call here the methods renderFormatItemRowCell*: for this reason
+                // they are now commented.
+
+                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
+                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);
+
+                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
+
+                submitField.renderFieldString(writer, context, this);
+
+                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);
+
+            }
+        }
+        writer.append("</form>");
+        appendWhitespace(writer);
+
+        // see if there is anything that needs to be added outside of the multi-form
+        Map<String, Object> wholeFormContext = UtilGenerics.checkMap(context.get("wholeFormContext"));
+        Appendable postMultiFormWriter = wholeFormContext != null ? (Appendable) wholeFormContext.get("postMultiFormWriter") : null;
+        if (postMultiFormWriter != null) {
+            writer.append(postMultiFormWriter.toString());
+            appendWhitespace(writer);
+        }
+
+        renderEndingBoundaryComment(writer, "Form Widget - Form Element (Multi)", modelForm);
+    }
+
+    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+
+        Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters"));
+        Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap"));
+        if (UtilValidate.isNotEmpty(queryStringMap)) {
+            inputFields.putAll(queryStringMap);
+        }
+        if (modelForm.getType().equals("multi")) {
+            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
+        }
+        String queryString = UtilHttp.urlEncodeArgs(inputFields);
+        context.put("_QBESTRING_", queryString);
+
+        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+        renderBeginningBoundaryComment(writer, "Form Widget", modelForm);
+
+        if (this.renderPagination) {
+            this.renderNextPrev(writer, context, modelForm);
+        }
+        writer.append(" <table cellspacing=\"0\" class=\"");
+        if (UtilValidate.isNotEmpty(modelForm.getDefaultTableStyle())) {
+            writer.append(FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context));
+        } else {
+            writer.append("basic-table form-widget-table dark-grid");
+        }
+        writer.append("\">");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append(" </table>");
+
+        appendWhitespace(writer);
+        if (this.renderPagination) {
+            this.renderNextPrev(writer, context, modelForm);
+        }
+        renderEndingBoundaryComment(writer, "Form Widget - Formal List Wrapper", modelForm);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("  <tr");
+        String headerStyle = FlexibleStringExpander.expandString(modelForm.getHeaderRowStyle(), context);
+        writer.append(" class=\"");
+        if (UtilValidate.isNotEmpty(headerStyle)) {
+            writer.append(headerStyle);
+        } else {
+            writer.append("header-row");
+        }
+        writer.append("\">");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("  </tr>");
+
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm, org.ofbiz.widget.model.ModelFormField, int positionSpan)
+     */
+    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
+        writer.append("   <td");
+        String areaStyle = modelFormField.getTitleAreaStyle();
+        if (positionSpan > 1) {
+            writer.append(" colspan=\"");
+            writer.append(Integer.toString(positionSpan));
+            writer.append("\"");
+        }
+        if (UtilValidate.isNotEmpty(areaStyle)) {
+            writer.append(" class=\"");
+            writer.append(areaStyle);
+            writer.append("\"");
+        }
+        writer.append(">");
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm, org.ofbiz.widget.model.ModelFormField)
+     */
+    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
+        writer.append("</td>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("   <td");
+        String areaStyle = modelForm.getFormTitleAreaStyle();
+        if (UtilValidate.isNotEmpty(areaStyle)) {
+            writer.append(" class=\"");
+            writer.append(areaStyle);
+            writer.append("\"");
+        }
+        writer.append(">");
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowFormCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</td>");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatHeaderRowFormCellTitleSeparator(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm, boolean)
+     */
+    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {
+
+        String titleStyle = modelFormField.getTitleStyle();
+        if (UtilValidate.isNotEmpty(titleStyle)) {
+            writer.append("<span class=\"");
+            writer.append(titleStyle);
+            writer.append("\">");
+        }
+        if (isLast) {
+            writer.append(" - ");
+        } else {
+            writer.append(" - ");
+        }
+        if (UtilValidate.isNotEmpty(titleStyle)) {
+            writer.append("</span>");
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        Integer itemIndex = (Integer)context.get("itemIndex");
+
+        writer.append("  <tr");
+        if (itemIndex!=null) {
+
+            String altRowStyles = modelForm.getStyleAltRowStyle(context);
+            if (itemIndex.intValue() % 2 == 0) {
+                String evenRowStyle = modelForm.getEvenRowStyle();
+                if (UtilValidate.isNotEmpty(evenRowStyle)) {
+                    writer.append(" class=\"");
+                    writer.append(evenRowStyle);
+                    if (UtilValidate.isNotEmpty(altRowStyles)) {
+                        writer.append(altRowStyles);
+                    }
+                    writer.append("\"");
+                } else {
+                    if (UtilValidate.isNotEmpty(altRowStyles)) {
+                        writer.append(" class=\"");
+                        writer.append(altRowStyles);
+                        writer.append("\"");
+                    }
+                }
+            } else {
+                String oddRowStyle = FlexibleStringExpander.expandString(modelForm.getOddRowStyle(), context);
+                if (UtilValidate.isNotEmpty(oddRowStyle)) {
+                    writer.append(" class=\"");
+                    writer.append(oddRowStyle);
+                    if (UtilValidate.isNotEmpty(altRowStyles)) {
+                        writer.append(altRowStyles);
+                    }
+                    writer.append("\"");
+                } else {
+                    if (UtilValidate.isNotEmpty(altRowStyles)) {
+                        writer.append(" class=\"");
+                        writer.append(altRowStyles);
+                        writer.append("\"");
+                    }
+                }
+            }
+        }
+        writer.append(">");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("  </tr>");
+
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm, org.ofbiz.widget.model.ModelFormField)
+     */
+    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
+        writer.append("   <td");
+        String areaStyle = modelFormField.getWidgetAreaStyle();
+        if (positionSpan > 1) {
+            writer.append(" colspan=\"");
+            writer.append(Integer.toString(positionSpan));
+            writer.append("\"");
+        }
+        if (UtilValidate.isNotEmpty(areaStyle)) {
+            writer.append(" class=\"");
+            writer.append(areaStyle);
+            writer.append("\"");
+        }
+        writer.append(">");
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm, org.ofbiz.widget.model.ModelFormField)
+     */
+    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
+        writer.append("</td>");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowFormCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("   <td");
+        String areaStyle = modelForm.getFormWidgetAreaStyle();
+        if (UtilValidate.isNotEmpty(areaStyle)) {
+            writer.append(" class=\"");
+            writer.append(areaStyle);
+            writer.append("\"");
+        }
+        writer.append(">");
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatItemRowFormCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</td>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append(" <table cellspacing=\"0\"");
+        if (UtilValidate.isNotEmpty(modelForm.getDefaultTableStyle())) {
+            writer.append(" class=\"").append(FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context)).append("\"");
+        }
+        writer.append(">");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append(" </table>");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("  <tr>");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowClose(java.io.Writer, java.util.Map, org.ofbiz.widget.form.model.ModelForm)
+     */
+    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("  </tr>");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowTitleCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField)
+     */
+    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        writer.append("   <td");
+        String areaStyle = modelFormField.getTitleAreaStyle();
+        if (UtilValidate.isNotEmpty(areaStyle)) {
+            writer.append(" class=\"");
+            writer.append(areaStyle);
+            writer.append("\"");
+        } else {
+            writer.append(" class=\"label\"");
+        }
+        writer.append(">");
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowTitleCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField)
+     */
+    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        writer.append("</td>");
+        appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowSpacerCell(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField)
+     */
+    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        // Embedded styling - bad idea
+        //writer.append("<td>&nbsp;</td>");
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowWidgetCellOpen(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField, int)
+     */
+    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
+//        writer.append("<td width=\"");
+//        if (nextPositionInRow != null || modelFormField.getPosition() > 1) {
+//            writer.append("30");
+//        } else {
+//            writer.append("80");
+//        }
+//        writer.append("%\"");
+        writer.append("   <td");
+        if (positionSpan > 0) {
+            writer.append(" colspan=\"");
+            // do a span of 1 for this column, plus 3 columns for each spanned
+            //position or each blank position that this will be filling in
+            writer.append(Integer.toString(1 + (positionSpan * 3)));
+            writer.append("\"");
+        }
+        String areaStyle = modelFormField.getWidgetAreaStyle();
+        if (UtilValidate.isNotEmpty(areaStyle)) {
+            writer.append(" class=\"");
+            writer.append(areaStyle);
+            writer.append("\"");
+        }
+        writer.append(">");
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFormatFieldRowWidgetCellClose(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField, int)
+     */
+    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
+        writer.append("</td>");
+        appendWhitespace(writer);
+    }
+
+    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("&nbsp;");
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderTextFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.TextFindField)
+     */
+    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
+
+        ModelFormField modelFormField = textFindField.getModelFormField();
+
+        String defaultOption = textFindField.getDefaultOption();
+        Locale locale = (Locale)context.get("locale");
+        if (!textFindField.getHideOptions()) {
+            String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
+            String opBeginsWith = UtilProperties.getMessage("conditional", "begins_with", locale);
+            String opContains = UtilProperties.getMessage("conditional", "contains", locale);
+            String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
+            String opNotEqual = UtilProperties.getMessage("conditional", "not_equal", locale);
+            writer.append(" <select name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append("_op\" class=\"selectBox\">");
+            writer.append("<option value=\"equals\"").append(("equals".equals(defaultOption)? " selected": "")).append(">").append(opEquals).append("</option>");
+            writer.append("<option value=\"like\"").append(("like".equals(defaultOption)? " selected": "")).append(">").append(opBeginsWith).append("</option>");
+            writer.append("<option value=\"contains\"").append(("contains".equals(defaultOption)? " selected": "")).append(">").append(opContains).append("</option>");
+            writer.append("<option value=\"empty\"").append(("empty".equals(defaultOption)? " selected": "")).append(">").append(opIsEmpty).append("</option>");
+            writer.append("<option value=\"notEqual\"").append(("notEqual".equals(defaultOption)? " selected": "")).append(">").append(opNotEqual).append("</option>");
+            writer.append("</select>");
+        } else {
+            writer.append(" <input type=\"hidden\" name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append("_op\" value=\"").append(defaultOption).append("\"/>");
+        }
+
+        writer.append("<input type=\"text\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append('"');
+
+        String value = modelFormField.getEntry(context, textFindField.getDefaultValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(textFindField.getSize()));
+        writer.append('"');
+
+        Integer maxlength = textFindField.getMaxlength();
+        if (maxlength != null) {
+            writer.append(" maxlength=\"");
+            writer.append(maxlength.toString());
+            writer.append('"');
+        }
+
+        if (!textFindField.getClientAutocompleteField()) {
+            writer.append(" autocomplete=\"off\"");
+        }
+
+        writer.append("/>");
+
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            writer.append(" <span class=\"");
+            writer.append(modelFormField.getTitleStyle());
+            writer.append("\">");
+        }
+
+        String ignoreCase = UtilProperties.getMessage("conditional", "ignore_case", locale);
+        boolean ignCase = textFindField.getIgnoreCase();
+
+        if (!textFindField.getHideIgnoreCase()) {
+            writer.append(" <input type=\"checkbox\" name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append("_ic\" value=\"Y\"").append((ignCase ? " checked=\"checked\"" : "")).append("/>");
+            writer.append(ignoreCase);
+        } else {
+            writer.append("<input type=\"hidden\" name=\"");
+            writer.append(modelFormField.getParameterName(context));
+            writer.append("_ic\" value=\"").append((ignCase ? "Y" : "")).append("\"/>");
+        }
+
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            writer.append("</span>");
+        }
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderRangeFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.RangeFindField)
+     */
+    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
+
+        ModelFormField modelFormField = rangeFindField.getModelFormField();
+        Locale locale = (Locale)context.get("locale");
+        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
+        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
+        String opGreaterThanEquals = UtilProperties.getMessage("conditional", "greater_than_equals", locale);
+        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
+        String opLessThanEquals = UtilProperties.getMessage("conditional", "less_than_equals", locale);
+        //String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
+
+        writer.append("<input type=\"text\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append("_fld0_value\"");
+
+        String value = modelFormField.getEntry(context, rangeFindField.getDefaultValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(rangeFindField.getSize()));
+        writer.append('"');
+
+        Integer maxlength = rangeFindField.getMaxlength();
+        if (maxlength != null) {
+            writer.append(" maxlength=\"");
+            writer.append(maxlength.toString());
+            writer.append('"');
+        }
+
+        if (!rangeFindField.getClientAutocompleteField()) {
+            writer.append(" autocomplete=\"off\"");
+        }
+
+        writer.append("/>");
+
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            writer.append(" <span class=\"");
+            writer.append(modelFormField.getTitleStyle());
+            writer.append("\">");
+        }
+
+        String defaultOptionFrom = rangeFindField.getDefaultOptionFrom();
+        writer.append(" <select name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append("_fld0_op\" class=\"selectBox\">");
+        writer.append("<option value=\"equals\"").append(("equals".equals(defaultOptionFrom)? " selected": "")).append(">").append(opEquals).append("</option>");
+        writer.append("<option value=\"greaterThan\"").append(("greaterThan".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThan).append("</option>");
+        writer.append("<option value=\"greaterThanEqualTo\"").append(("greaterThanEqualTo".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThanEquals).append("</option>");
+        writer.append("</select>");
+
+        writer.append("</span>");
+
+        writer.append(" <br/> ");
+
+        writer.append("<input type=\"text\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append("_fld1_value\"");
+
+        value = modelFormField.getEntry(context);
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(rangeFindField.getSize()));
+        writer.append('"');
+
+        if (maxlength != null) {
+            writer.append(" maxlength=\"");
+            writer.append(maxlength.toString());
+            writer.append('"');
+        }
+
+        if (!rangeFindField.getClientAutocompleteField()) {
+            writer.append(" autocomplete=\"off\"");
+        }
+
+        writer.append("/>");
+
+        String defaultOptionThru = rangeFindField.getDefaultOptionThru();
+        writer.append(" <select name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append("_fld1_op\" class=\"selectBox\">");
+        writer.append("<option value=\"lessThan\"").append(("lessThan".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThan).append("</option>");
+        writer.append("<option value=\"lessThanEqualTo\"").append(("lessThanEqualTo".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThanEquals).append("</option>");
+        writer.append("</select>");
+
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            writer.append("</span>");
+        }
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderDateFindField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.DateFindField)
+     */
+    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
+        ModelFormField modelFormField = dateFindField.getModelFormField();
+
+        Locale locale = (Locale)context.get("locale");
+        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
+        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
+        String opSameDay = UtilProperties.getMessage("conditional", "same_day", locale);
+        String opGreaterThanFromDayStart = UtilProperties.getMessage("conditional",
+                                                "greater_than_from_day_start", locale);
+        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
+        String opUpToDay = UtilProperties.getMessage("conditional", "up_to_day", locale);
+        String opUpThruDay = UtilProperties.getMessage("conditional", "up_thru_day", locale);
+        String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
+
+        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        }
+        String localizedInputTitle = "", localizedIconTitle = "";
+
+        writer.append("<input type=\"text\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append("_fld0_value\"");
+
+        // the default values for a timestamp
+        int size = 25;
+        int maxlength = 30;
+
+        if ("date".equals(dateFindField.getType())) {
+            size = maxlength = 10;
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatDate");
+            }
+        } else if ("time".equals(dateFindField.getType())) {
+            size = maxlength = 8;
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatTime");
+            }
+        } else {
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatDateTime");
+            }
+        }
+        writer.append(" title=\"");
+        writer.append(localizedInputTitle);
+        writer.append('"');
+
+        String value = modelFormField.getEntry(context, dateFindField.getDefaultValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            if (value.length() > maxlength) {
+                value = value.substring(0, maxlength);
+            }
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(size));
+        writer.append('"');
+
+        writer.append(" maxlength=\"");
+        writer.append(Integer.toString(maxlength));
+        writer.append('"');
+
+        writer.append("/>");
+
+        // search for a localized label for the icon
+        if (uiLabelMap != null) {
+            localizedIconTitle = uiLabelMap.get("CommonViewCalendar");
+        }
+        ModelForm modelForm = modelFormField.getModelForm();
+        // add calendar pop-up button and seed data IF this is not a "time" type date-find
+        if (!"time".equals(dateFindField.getType())) {
+            if ("date".equals(dateFindField.getType())) {
+                writer.append("<a href=\"javascript:call_cal_notime(document.");
+            } else {
+                writer.append("<a href=\"javascript:call_cal(document.");
+            }
+            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
+            writer.append('.');
+            writer.append(modelFormField.getParameterName(context));
+            writer.append("_fld0_value,'");
+            writer.append(UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context))));
+            writer.append("');\">");
+
+            writer.append("<img src=\"");
+            this.appendContentUrl(writer, "/images/cal.gif");
+            writer.append("\" width=\"16\" height=\"16\" border=\"0\" alt=\"");
+            writer.append(localizedIconTitle);
+            writer.append("\" title=\"");
+            writer.append(localizedIconTitle);
+            writer.append("\"/></a>");
+        }
+
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            writer.append(" <span class=\"");
+            writer.append(modelFormField.getTitleStyle());
+            writer.append("\">");
+        }
+
+        String defaultOptionFrom = dateFindField.getDefaultOptionFrom();
+        writer.append(" <select name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append("_fld0_op\" class=\"selectBox\">");
+        writer.append("<option value=\"equals\"").append(("equals".equals(defaultOptionFrom)? " selected": "")).append(">").append(opEquals).append("</option>");
+        writer.append("<option value=\"sameDay\"").append(("sameDay".equals(defaultOptionFrom)? " selected": "")).append(">").append(opSameDay).append("</option>");
+        writer.append("<option value=\"greaterThanFromDayStart\"").append(("greaterThanFromDayStart".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThanFromDayStart).append("</option>");
+        writer.append("<option value=\"greaterThan\"").append(("greaterThan".equals(defaultOptionFrom)? " selected": "")).append(">").append(opGreaterThan).append("</option>");
+        writer.append("</select>");
+
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            writer.append(" </span>");
+        }
+
+        writer.append(" <br/> ");
+
+        writer.append("<input type=\"text\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append("_fld1_value\"");
+
+        writer.append(" title=\"");
+        writer.append(localizedInputTitle);
+        writer.append('"');
+
+        value = modelFormField.getEntry(context);
+        if (UtilValidate.isNotEmpty(value)) {
+            if (value.length() > maxlength) {
+                value = value.substring(0, maxlength);
+            }
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(size));
+        writer.append('"');
+
+        writer.append(" maxlength=\"");
+        writer.append(Integer.toString(maxlength));
+        writer.append('"');
+
+        writer.append("/>");
+
+        // add calendar pop-up button and seed data IF this is not a "time" type date-find
+        if (!"time".equals(dateFindField.getType())) {
+            if ("date".equals(dateFindField.getType())) {
+                writer.append("<a href=\"javascript:call_cal_notime(document.");
+            } else {
+                writer.append("<a href=\"javascript:call_cal(document.");
+            }
+            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
+            writer.append('.');
+            writer.append(modelFormField.getParameterName(context));
+            writer.append("_fld1_value,'");
+            writer.append(UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context))));
+            writer.append("');\">");
+
+            writer.append("<img src=\"");
+            this.appendContentUrl(writer, "/images/cal.gif");
+            writer.append("\" width=\"16\" height=\"16\" border=\"0\" alt=\"");
+            writer.append(localizedIconTitle);
+            writer.append("\" title=\"");
+            writer.append(localizedIconTitle);
+            writer.append("\"/></a>");
+        }
+
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            writer.append(" <span class=\"");
+            writer.append(modelFormField.getTitleStyle());
+            writer.append("\">");
+        }
+
+        String defaultOptionThru = dateFindField.getDefaultOptionThru();
+        writer.append(" <select name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append("_fld1_op\" class=\"selectBox\">");
+        writer.append("<option value=\"lessThan\"").append(("lessThan".equals(defaultOptionThru)? " selected": "")).append(">").append(opLessThan).append("</option>");
+        writer.append("<option value=\"upToDay\"").append(("upToDay".equals(defaultOptionThru)? " selected": "")).append(">").append(opUpToDay).append("</option>");
+        writer.append("<option value=\"upThruDay\"").append(("upThruDay".equals(defaultOptionThru)? " selected": "")).append(">").append(opUpThruDay).append("</option>");
+        writer.append("<option value=\"empty\"").append(("empty".equals(defaultOptionThru)? " selected": "")).append(">").append(opIsEmpty).append("</option>");
+        writer.append("</select>");
+
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            writer.append("</span>");
+        }
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderLookupField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.LookupField)
+     */
+    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
+        ModelFormField modelFormField = lookupField.getModelFormField();
+
+        writer.append("<input type=\"text\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append('"');
+
+        String value = modelFormField.getEntry(context, lookupField.getDefaultValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(lookupField.getSize()));
+        writer.append('"');
+
+        Integer maxlength = lookupField.getMaxlength();
+        if (maxlength != null) {
+            writer.append(" maxlength=\"");
+            writer.append(maxlength.toString());
+            writer.append('"');
+        }
+
+        String idName = modelFormField.getCurrentContainerId(context);
+        if (UtilValidate.isNotEmpty(idName)) {
+            writer.append(" id=\"");
+            writer.append(idName);
+            writer.append('"');
+        }
+
+        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
+        boolean ajaxEnabled = updateAreas != null && this.javaScriptEnabled;
+        if (!lookupField.getClientAutocompleteField() || ajaxEnabled) {
+            writer.append(" autocomplete=\"off\"");
+        }
+
+        writer.append("/>");
+        ModelForm modelForm = modelFormField.getModelForm();
+        // add lookup pop-up button
+        String descriptionFieldName = lookupField.getDescriptionFieldName();
+        if (UtilValidate.isNotEmpty(descriptionFieldName)) {
+            writer.append("<a href=\"javascript:call_fieldlookup3(document.");
+            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
+            writer.append('.');
+            writer.append(modelFormField.getParameterName(context));
+            writer.append(",'");
+            writer.append(descriptionFieldName);
+            writer.append(",'");
+        } else {
+            writer.append("<a href=\"javascript:call_fieldlookup2(document.");
+            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
+            writer.append('.');
+            writer.append(modelFormField.getParameterName(context));
+            writer.append(",'");
+        }
+        writer.append(appendExternalLoginKey(lookupField.getFormName(context)));
+        writer.append("'");
+        List<String> targetParameterList = lookupField.getTargetParameterList();
+        for (String targetParameter: targetParameterList) {
+            // named like: document.${formName}.${targetParameter}.value
+            writer.append(", document.");
+            writer.append(FormRenderer.getCurrentFormName(modelForm, context));
+            writer.append(".");
+            writer.append(targetParameter);
+            writer.append(".value");
+        }
+        writer.append(");\">");
+        writer.append("<img src=\"");
+        this.appendContentUrl(writer, "/images/fieldlookup.gif");
+        writer.append("\" width=\"15\" height=\"14\" border=\"0\" alt=\"Lookup\"/></a>");
+
+        this.addAsterisks(writer, context, modelFormField);
+
+        this.makeHyperlinkString(writer, lookupField.getSubHyperlink(), context);
+        this.appendTooltip(writer, context, modelFormField);
+
+        if (ajaxEnabled) {
+            appendWhitespace(writer);
+            writer.append("<script language=\"JavaScript\" type=\"text/javascript\">");
+            appendWhitespace(writer);
+            writer.append("ajaxAutoCompleter('").append(createAjaxParamsFromUpdateAreas(updateAreas, null, context)).append("');");
+            appendWhitespace(writer);
+            writer.append("</script>");
+        }
+        appendWhitespace(writer);
+
+        //appendWhitespace(writer);
+    }
+
+    protected String appendExternalLoginKey(String target) {
+        String result = target;
+        String sessionId = ";jsessionid=" + request.getSession().getId();
+        int questionIndex = target.indexOf("?");
+        if (questionIndex == -1) {
+            result += sessionId;
+        } else {
+            result = result.replace("?", sessionId + "?");
+        }
+        return result;
+    }
+
+    private int getActualPageSize(Map<String, Object> context) {
+        Integer value = (Integer) context.get("actualPageSize");
+        return value != null ? value.intValue() : (getHighIndex(context) - getLowIndex(context));
+    }
+
+    private int getHighIndex(Map<String, Object> context) {
+        Integer value = (Integer) context.get("highIndex");
+        return value != null ? value.intValue() : 0;
+    }
+
+    private int getListSize(Map<String, Object> context) {
+        Integer value = (Integer) context.get("listSize");
+        return value != null ? value.intValue() : 0;
+    }
+
+    private int getLowIndex(Map<String, Object> context) {
+        Integer value = (Integer) context.get("lowIndex");
+        return value != null ? value.intValue() : 0;
+    }
+
+    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        boolean ajaxEnabled = false;
+        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnPaginateUpdateAreas();
+        String targetService = modelForm.getPaginateTarget(context);
+        if (this.javaScriptEnabled) {
+            if (UtilValidate.isNotEmpty(updateAreas)) {
+                ajaxEnabled = true;
+            }
+        }
+        if (targetService == null) {
+            targetService = "${targetService}";
+        }
+        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
+            Debug.logWarning("Cannot paginate because TargetService is empty for the form: " + modelForm.getName(), module);
+            return;
+        }
+
+        // get the parameterized pagination index and size fields
+        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
+        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
+        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
+
+        int viewIndex = Paginator.getViewIndex(modelForm, context);
+        int viewSize = Paginator.getViewSize(modelForm, context);
+        int listSize = getListSize(context);
+
+        int lowIndex = getLowIndex(context);
+        int highIndex = getHighIndex(context);
+        int actualPageSize = getActualPageSize(context);
+
+        // if this is all there seems to be (if listSize < 0, then size is unknown)
+        if (actualPageSize >= listSize && listSize >= 0) return;
+
+        // needed for the "Page" and "rows" labels
+        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+        String pageLabel = "";
+        String commonDisplaying = "";
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        } else {
+            pageLabel = uiLabelMap.get("CommonPage");
+            Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize));
+            commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale"));
+        }
+
+        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
+        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber)) viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
+        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber)) viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;
+
+        String str = (String) context.get("_QBESTRING_");
+
+        // strip legacy viewIndex/viewSize params from the query string
+        String queryString = UtilHttp.stripViewParamsFromQueryString(str, "" + paginatorNumber);
+
+        // strip parametrized index/size params from the query string
+        HashSet<String> paramNames = new HashSet<String>();
+        paramNames.add(viewIndexParam);
+        paramNames.add(viewSizeParam);
+        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);
+
+        String anchor = "";
+        String paginateAnchor = modelForm.getPaginateTargetAnchor();
+        if (paginateAnchor != null) anchor = "#" + paginateAnchor;
+
+        // Create separate url path String and request parameters String,
+        // add viewIndex/viewSize parameters to request parameter String
+        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
+        StringBuilder prepLinkBuffer = new StringBuilder();
+        String prepLinkQueryString = UtilHttp.getQueryStringFromTarget(targetService);
+        if (prepLinkQueryString != null) {
+            prepLinkBuffer.append(prepLinkQueryString);
+        }
+        if (prepLinkBuffer.indexOf("?") < 0) {
+            prepLinkBuffer.append("?");
+        } else if (prepLinkBuffer.indexOf("?", prepLinkBuffer.length() - 1) > 0) {
+            prepLinkBuffer.append("&amp;");
+        }
+        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
+            prepLinkBuffer.append(queryString).append("&amp;");
+        }
+        prepLinkBuffer.append(viewSizeParam).append("=").append(viewSize).append("&amp;").append(viewIndexParam).append("=");
+        String prepLinkText = prepLinkBuffer.toString();
+        if (ajaxEnabled) {
+            // Prepare params for prototype.js
+            prepLinkText = prepLinkText.replace("?", "");
+            prepLinkText = prepLinkText.replace("&amp;", "&");
+        }
+
+        writer.append("<div class=\"").append(modelForm.getPaginateStyle()).append("\">");
+        appendWhitespace(writer);
+        writer.append(" <ul>");
+        appendWhitespace(writer);
+
+        String linkText;
+
+        // First button
+        writer.append("  <li class=\"").append(modelForm.getPaginateFirstStyle());
+        if (viewIndex > 0) {
+            writer.append("\"><a href=\"");
+            if (ajaxEnabled) {
+                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + 0 + anchor, context)).append("')");
+            } else {
+                linkText = prepLinkText + 0 + anchor;
+                appendOfbizUrl(writer, urlPath + linkText);
+            }
+            writer.append("\">").append(modelForm.getPaginateFirstLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            writer.append("-disabled\">").append(modelForm.getPaginateFirstLabel(context));
+        }
+        writer.append("</li>");
+        appendWhitespace(writer);
+
+        // Previous button
+        writer.append("  <li class=\"").append(modelForm.getPaginatePreviousStyle());
+        if (viewIndex > 0) {
+            writer.append("\"><a href=\"");
+            if (ajaxEnabled) {
+                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex - 1) + anchor, context)).append("')");
+            } else {
+                linkText = prepLinkText + (viewIndex - 1) + anchor;
+                appendOfbizUrl(writer, urlPath + linkText);
+            }
+            writer.append("\">").append(modelForm.getPaginatePreviousLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            writer.append("-disabled\">").append(modelForm.getPaginatePreviousLabel(context));
+        }
+        writer.append("</li>");
+        appendWhitespace(writer);
+
+        // Page select dropdown
+        if (listSize > 0 && this.javaScriptEnabled) {
+            writer.append("  <li>").append(pageLabel).append(" <select name=\"page\" size=\"1\" onchange=\"");
+            if (ajaxEnabled) {
+                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + "' + this.value", context)).append(")");
+            } else {
+                linkText = prepLinkText;
+                if (linkText.startsWith("/")) {
+                    linkText = linkText.substring(1);
+                }
+                writer.append("location.href = '");
+                appendOfbizUrl(writer, urlPath + linkText);
+                writer.append("' + this.value;");
+            }
+            writer.append("\">");
+            // actual value
+            int page = 0;
+            for (int i = 0; i < listSize;) {
+                if (page == viewIndex) {
+                    writer.append("<option selected value=\"");
+                } else {
+                    writer.append("<option value=\"");
+                }
+                writer.append(Integer.toString(page));
+                writer.append("\">");
+                writer.append(Integer.toString(1 + page));
+                writer.append("</option>");
+                // increment page and calculate next index
+                page++;
+                i = page * viewSize;
+            }
+            writer.append("</select></li>");
+        }
+
+        //  show row count
+        writer.append("<li>");
+        writer.append(commonDisplaying);
+        writer.append("</li>");
+        appendWhitespace(writer);
+
+        // Next button
+        writer.append("  <li class=\"").append(modelForm.getPaginateNextStyle());
+        if (highIndex < listSize) {
+            writer.append("\"><a href=\"");
+            if (ajaxEnabled) {
+                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex + 1) + anchor, context)).append("')");
+            } else {
+                linkText = prepLinkText + (viewIndex + 1) + anchor;
+                appendOfbizUrl(writer, urlPath + linkText);
+            }
+            writer.append("\">").append(modelForm.getPaginateNextLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            writer.append("-disabled\">").append(modelForm.getPaginateNextLabel(context));
+        }
+        writer.append("</li>");
+        appendWhitespace(writer);
+
+        // Last button
+        writer.append("  <li class=\"").append(modelForm.getPaginateLastStyle());
+        if (highIndex < listSize) {
+            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
+            writer.append("\"><a href=\"");
+            if (ajaxEnabled) {
+                writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + lastIndex + anchor, context)).append("')");
+            } else {
+                linkText = prepLinkText + lastIndex + anchor;
+                appendOfbizUrl(writer, urlPath + linkText);
+            }
+            writer.append("\">").append(modelForm.getPaginateLastLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            writer.append("-disabled\">").append(modelForm.getPaginateLastLabel(context));
+        }
+        writer.append("</li>");
+        appendWhitespace(writer);
+
+        writer.append(" </ul>");
+        appendWhitespace(writer);
+        writer.append("</div>");
+        appendWhitespace(writer);
+    }
+
+    public void renderSortField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
+        boolean ajaxEnabled = false;
+        ModelForm modelForm = modelFormField.getModelForm();
+        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnPaginateUpdateAreas();
+        String targetService = modelForm.getPaginateTarget(context);
+        if (this.javaScriptEnabled) {
+            if (UtilValidate.isNotEmpty(updateAreas)) {
+                ajaxEnabled = true;
+            }
+        }
+        if (targetService == null) {
+            targetService = "${targetService}";
+        }
+        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
+            Debug.logWarning("Cannot sort because TargetService is empty for the form: " + modelForm.getName(), module);
+            return;
+        }
+
+        String str = (String) context.get("_QBESTRING_");
+        String oldSortField = modelForm.getSortField(context);
+        String sortFieldStyle = modelFormField.getSortFieldStyle();
+
+        // if the entry-name is defined use this instead of field name
+        String columnField = modelFormField.getEntryName();
+        if (UtilValidate.isEmpty(columnField)) {
+            columnField = modelFormField.getFieldName();
+        }
+
+        // switch beetween asc/desc order
+        String newSortField = columnField;
+        if (UtilValidate.isNotEmpty(oldSortField)) {
+            if (oldSortField.equals(columnField)) {
+                newSortField = "-" + columnField;
+                sortFieldStyle = modelFormField.getSortFieldStyleDesc();
+            } else if (oldSortField.equals("-" + columnField)) {
+                newSortField = columnField;
+                sortFieldStyle = modelFormField.getSortFieldStyleAsc();
+            }
+        }
+
+        //  strip sortField param from the query string
+        HashSet<String> paramName = new HashSet<String>();
+        paramName.add("sortField");
+        String queryString = UtilHttp.stripNamedParamsFromQueryString(str, paramName);
+        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
+        StringBuilder prepLinkBuffer = new StringBuilder();
+        String prepLinkQueryString = UtilHttp.getQueryStringFromTarget(targetService);
+        if (prepLinkQueryString != null) {
+            prepLinkBuffer.append(prepLinkQueryString);
+        }
+        if (prepLinkBuffer.indexOf("?") < 0) {
+            prepLinkBuffer.append("?");
+        } else if (prepLinkBuffer.indexOf("?", prepLinkBuffer.length() - 1) > 0) {
+            prepLinkBuffer.append("&amp;");
+        }
+        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
+            prepLinkBuffer.append(queryString).append("&amp;");
+        }
+        prepLinkBuffer.append("sortField").append("=").append(newSortField);
+        String prepLinkText = prepLinkBuffer.toString();
+        if (ajaxEnabled) {
+            prepLinkText = prepLinkText.replace("?", "");
+            prepLinkText = prepLinkText.replace("&amp;", "&");
+        }
+
+        writer.append("<a");
+        if (UtilValidate.isNotEmpty(sortFieldStyle)) {
+            writer.append(" class=\"");
+            writer.append(sortFieldStyle);
+            writer.append("\"");
+        }
+
+        writer.append(" href=\"");
+        if (ajaxEnabled) {
+            writer.append("javascript:ajaxUpdateAreas('").append(createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText, context)).append("')");
+        } else {
+            appendOfbizUrl(writer, urlPath + prepLinkText);
+        }
+        writer.append("\">").append(titleText).append("</a>");
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderFileField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.FileField)
+     */
+    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+
+        writer.append("<input type=\"file\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append('"');
+
+        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(textField.getSize()));
+        writer.append('"');
+
+        Integer maxlength = textField.getMaxlength();
+        if (maxlength != null) {
+            writer.append(" maxlength=\"");
+            writer.append(maxlength.toString());
+            writer.append('"');
+        }
+
+        if (!textField.getClientAutocompleteField()) {
+            writer.append(" autocomplete=\"off\"");
+        }
+
+        writer.append("/>");
+
+        this.makeHyperlinkString(writer, textField.getSubHyperlink(), context);
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderPasswordField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.PasswordField)
+     */
+    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
+        ModelFormField modelFormField = passwordField.getModelFormField();
+
+        writer.append("<input type=\"password\"");
+
+        appendClassNames(writer, context, modelFormField);
+
+        writer.append(" name=\"");
+        writer.append(modelFormField.getParameterName(context));
+        writer.append('"');
+
+        String value = modelFormField.getEntry(context, passwordField.getDefaultValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" value=\"");
+            writer.append(value);
+            writer.append('"');
+        }
+
+        writer.append(" size=\"");
+        writer.append(Integer.toString(passwordField.getSize()));
+        writer.append('"');
+
+        Integer maxlength = passwordField.getMaxlength();
+        if (maxlength != null) {
+            writer.append(" maxlength=\"");
+            writer.append(maxlength.toString());
+            writer.append('"');
+        }
+
+        String idName = modelFormField.getCurrentContainerId(context);
+        if (UtilValidate.isNotEmpty(idName)) {
+            writer.append(" id=\"");
+            writer.append(idName);
+            writer.append('"');
+        }
+
+        if (!passwordField.getClientAutocompleteField()) {
+            writer.append(" autocomplete=\"off\"");
+        }
+
+        writer.append("/>");
+
+        this.addAsterisks(writer, context, modelFormField);
+
+        this.makeHyperlinkString(writer, passwordField.getSubHyperlink(), context);
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.form.FormStringRenderer#renderImageField(java.io.Writer, java.util.Map, org.ofbiz.widget.model.ModelFormField.ImageField)
+     */
+    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
+        ModelFormField modelFormField = imageField.getModelFormField();
+
+        writer.append("<img ");
+
+        String value = modelFormField.getEntry(context, imageField.getValue(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" src=\"");
+            appendContentUrl(writer, value);
+            writer.append('"');
+        }
+        
+        value = modelFormField.getEntry(context, imageField.getStyle(context));
+        if (UtilValidate.isNotEmpty(value)) {
+            writer.append(" class=\"");
+            appendContentUrl(writer, value);
+            writer.append('"');
+        }
+
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        if (UtilValidate.isNotEmpty(event) && UtilValidate.isNotEmpty(action)) {
+            writer.append(" ");
+            writer.append(event);
+            writer.append("=\"");
+            writer.append(action);
+            writer.append('"');
+        }
+
+        writer.append("/>");
+
+        this.makeHyperlinkString(writer, imageField.getSubHyperlink(), context);
+
+        this.appendTooltip(writer, context, modelFormField);
+
+        //appendWhitespace(writer);
+    }
+
+    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
+        String style = fieldGroup.getStyle();
+        String id = fieldGroup.getId();
+        FlexibleStringExpander titleNotExpanded = FlexibleStringExpander.getInstance(fieldGroup.getTitle());
+        String title = titleNotExpanded.expandString(context);
+        Boolean collapsed = fieldGroup.initiallyCollapsed();
+        String collapsibleAreaId = fieldGroup.getId() + "_body";
+
+        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id) || UtilValidate.isNotEmpty(title)) {
+
+            writer.append("<div class=\"fieldgroup");
+            if (UtilValidate.isNotEmpty(style)) {
+                writer.append(" ");
+                writer.append(style);
+            }
+            writer.append("\"");
+            if (UtilValidate.isNotEmpty(id)) {
+                writer.append(" id=\"");
+                writer.append(id);
+                writer.append("\"");
+            }
+            writer.append(">");
+
+            writer.append("<div class=\"fieldgroup-title-bar\"><table><tr><td class=\"collapse\">");
+
+            if (fieldGroup.collapsible()) {
+                String expandToolTip = null;
+                String collapseToolTip = null;
+                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+                //Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
+                if (uiLabelMap != null) {
+                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
+                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
+                }
+
+                writer.append("<ul><li class=\"");
+                if (collapsed) {
+                    writer.append("collapsed\"><a ");
+                    writer.append("onclick=\"javascript:toggleCollapsiblePanel(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
+                } else {
+                    writer.append("expanded\"><a ");
+                    writer.append("onclick=\"javascript:toggleCollapsiblePanel(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
+                }
+                writer.append(">&nbsp&nbsp&nbsp</a></li></ul>");
+
+                appendWhitespace(writer);
+            }
+            writer.append("</td><td>");
+
+            if (UtilValidate.isNotEmpty(title)) {
+                writer.append("<div class=\"title\">");
+                writer.append(title);
+                writer.append("</div>");
+            }
+
+            writer.append("</td></tr></table></div>");
+
+            writer.append("<div id=\"").append(collapsibleAreaId).append("\" class=\"fieldgroup-body\"");
+            if (fieldGroup.collapsible() && collapsed) {
+                writer.append(" style=\"display: none;\"");
+            }
+            writer.append(">");
+        }
+    }
+
+    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
+        String style = fieldGroup.getStyle();
+        String id = fieldGroup.getId();
+        String title = fieldGroup.getTitle();
+        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id) || UtilValidate.isNotEmpty(title)) {
+            writer.append("</div>");
+            writer.append("</div>");
+        }
+    }
+
+    // TODO: Remove embedded styling
+    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
+        writer.append(" <table width=\"100%\">  <tr>");
+        String style = banner.getStyle(context);
+        String leftStyle = banner.getLeftTextStyle(context);
+        if (UtilValidate.isEmpty(leftStyle)) leftStyle = style;
+        String rightStyle = banner.getRightTextStyle(context);
+        if (UtilValidate.isEmpty(rightStyle)) rightStyle = style;
+
+        String leftText = banner.getLeftText(context);
+        if (UtilValidate.isNotEmpty(leftText)) {
+            writer.append("   <td align=\"left\">");
+            if (UtilValidate.isNotEmpty(leftStyle)) {
+               writer.append("<div");
+               writer.append(" class=\"");
+               writer.append(leftStyle);
+               writer.append("\"");
+               writer.append(">");
+            }
+            writer.append(leftText);
+            if (UtilValidate.isNotEmpty(leftStyle)) {
+                writer.append("</div>");
+            }
+            writer.append("</td>");
+        }
+
+        String text = banner.getText(context);
+        if (UtilValidate.isNotEmpty(text)) {
+            writer.append("   <td align=\"center\">");
+            if (UtilValidate.isNotEmpty(style)) {
+               writer.append("<div");
+               writer.append(" class=\"");
+               writer.append(style);
+               writer.append("\"");
+               writer.append(">");
+            }
+            writer.append(text);
+            if (UtilValidate.isNotEmpty(style)) {
+                writer.append("</div>");
+            }
+            writer.append("</td>");
+        }
+
+        String rightText = banner.getRightText(context);
+        if (UtilValidate.isNotEmpty(rightText)) {
+            writer.append("   <td align=\"right\">");
+            if (UtilValidate.isNotEmpty(rightStyle)) {
+               writer.append("<div");
+               writer.append(" class=\"");
+               writer.append(rightStyle);
+               writer.append("\"");
+               writer.append(">");
+            }
+            writer.append(rightText);
+            if (UtilValidate.isNotEmpty(rightStyle)) {
+                writer.append("</div>");
+            }
+            writer.append("</td>");
+        }
+        writer.append("</tr> </table>");
+    }
+
+    /**
+     * Renders a link for the column header fields when there is a header-link="" specified in the <field > tag, using
+     * style from header-link-style="".  Also renders a selectAll checkbox in multi forms.
+     * @param writer
+     * @param context
+     * @param modelFormField
+     * @param titleText
+     */
+    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
+        if (UtilValidate.isNotEmpty(modelFormField.getHeaderLink())) {
+            StringBuilder targetBuffer = new StringBuilder();
+            FlexibleStringExpander target = FlexibleStringExpander.getInstance(modelFormField.getHeaderLink());
+            String fullTarget = target.expandString(context);
+            targetBuffer.append(fullTarget);
+            String targetType = CommonWidgetModels.Link.DEFAULT_URL_MODE;
+            if (UtilValidate.isNotEmpty(targetBuffer.toString()) && targetBuffer.toString().toLowerCase().startsWith("javascript:")) {
+                targetType="plain";
+            }
+            WidgetWorker.makeHyperlinkString(writer, modelFormField.getHeaderLinkStyle(), targetType, targetBuffer.toString(), null, titleText, null, modelFormField, this.request, this.response, null, null);
+        } else if (modelFormField.isSortField()) {
+            renderSortField (writer, context, modelFormField, titleText);
+        } else if (modelFormField.isRowSubmit()) {
+            if (UtilValidate.isNotEmpty(titleText)) writer.append(titleText).append("<br/>");
+            writer.append("<input type=\"checkbox\" name=\"selectAll\" value=\"Y\" onclick=\"javascript:toggleAll(this, '");
+            writer.append(modelFormField.getModelForm().getName());
+            writer.append("');\"/>");
+        } else {
+             writer.append(titleText);
+        }
+    }
+
+    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
+        writer.append("<div ");
+        String id = containerField.getModelFormField().getIdName();
+        if (UtilValidate.isNotEmpty(id)) {
+            writer.append("id=\"");
+            writer.append(id);
+            writer.append("\" ");
+        }
+        String className = containerField.getModelFormField().getWidgetStyle();
+        if (UtilValidate.isNotEmpty(className)) {
+            writer.append("class=\"");
+            writer.append(className);
+            writer.append("\" ");
+        }
+        writer.append("/>");
+    }
+
+    /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea objects. See
+     * <code>selectall.js</code>.
+     * @param updateAreas
+     * @param extraParams Renderer-supplied additional target parameters
+     * @param context
+     * @return Parameter string or empty string if no UpdateArea objects were found
+     */
+    public String createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas, String extraParams, Map<String, ? extends Object> context) {
+        if (updateAreas == null) {
+            return "";
+        }
+        StringBuilder ajaxUrl = new StringBuilder();
+        boolean firstLoop = true;
+        for (ModelForm.UpdateArea updateArea : updateAreas) {
+            if (firstLoop) {
+                firstLoop = false;
+            } else {
+                ajaxUrl.append(",");
+            }
+            String targetUrl = updateArea.getAreaTarget(context);
+            String ajaxParams = getAjaxParamsFromTarget(targetUrl);
+            if (UtilValidate.isNotEmpty(extraParams)) {
+                if (ajaxParams.length() > 0 && !extraParams.startsWith("&")) {
+                    ajaxParams += "&";
+                }
+                ajaxParams += extraParams;
+            }
+            ajaxUrl.append(updateArea.getAreaId()).append(",");
+            try {
+                appendOfbizUrl(ajaxUrl, UtilHttp.removeQueryStringFromTarget(targetUrl));
+            } catch (IOException e) {
+                throw UtilMisc.initCause(new InternalError(e.getMessage()), e);
+            }
+            ajaxUrl.append(",").append(ajaxParams);
+        }
+        return ajaxUrl.toString();
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlFormWrapper.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormWrapper.java
similarity index 96%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlFormWrapper.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormWrapper.java
index 6b36db2..3718ea0 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlFormWrapper.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormWrapper.java
@@ -1,200 +1,200 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.HashMap;
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.collections.MapStack;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.widget.form.FormFactory;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.FormRenderer;
-
-import org.xml.sax.SAXException;
-
-
-/**
- * Widget Library - HTML Form Wrapper class - makes it easy to do the setup and render of a form
- */
-public class HtmlFormWrapper {
-
-    public static final String module = HtmlFormWrapper.class.getName();
-
-    protected String resourceName;
-    protected String formName;
-    protected HttpServletRequest request;
-    protected HttpServletResponse response;
-    protected ModelForm modelForm;
-    protected FormStringRenderer renderer;
-    protected Map<String, Object> context;
-
-    protected HtmlFormWrapper() {}
-
-    public HtmlFormWrapper(String resourceName, String formName, HttpServletRequest request, HttpServletResponse response)
-            throws IOException, SAXException, ParserConfigurationException {
-        this.resourceName = resourceName;
-        this.formName = formName;
-        this.request = request;
-        this.response = response;
-        Delegator delegator = null;
-        try {
-            delegator = (Delegator) request.getAttribute("delegator");
-            LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
-            this.modelForm = FormFactory.getFormFromLocation(resourceName, formName, delegator.getModelReader(), dispatcher.getDispatchContext());
-        } catch (IllegalArgumentException iae) {
-            Debug.logWarning("Could not find form with name [" + formName + "] in class resource [" + resourceName + "], will try to load it using relative path syntax.", module);
-            this.modelForm = FormFactory.getFormFromWebappContext(resourceName, formName, request);
-        }
-
-        this.renderer = new HtmlFormRenderer(request, response);
-
-        this.context = new HashMap<String, Object>();
-        Map<String, Object> parameterMap = UtilHttp.getParameterMap(request);
-        context.put("parameters", parameterMap);
-
-        //make sure the locale is in the context
-        context.put("locale", UtilHttp.getLocale(request));
-        //make sure the timeZone is in the context
-        context.put("timeZone", UtilHttp.getTimeZone(request));
-
-        // if there was an error message, this is an error
-        if (UtilValidate.isNotEmpty(request.getAttribute("_ERROR_MESSAGE_"))) {
-            context.put("isError", Boolean.TRUE);
-        } else {
-            context.put("isError", Boolean.FALSE);
-        }
-
-        // if a parameter was passed saying this is an error, it is an error
-        if ("true".equals(parameterMap.get("isError"))) {
-            context.put("isError", Boolean.TRUE);
-        }
-
-        Map<String, String> uiLabelMap = UtilGenerics.cast(request.getAttribute("uiLabelMap"));
-        if (UtilValidate.isNotEmpty(uiLabelMap) && context.get("uiLabelMap") == null) {
-            Debug.logInfo("Got uiLabelMap: " + uiLabelMap, module);
-            context.put("uiLabelMap", uiLabelMap);
-        }
-        if (UtilValidate.isNotEmpty(delegator) && context.get("delegator") == null) {
-            context.put("delegator", delegator);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public StringWriter renderFormString(Object contextStack) throws Exception {
-        if (contextStack instanceof MapStack) {
-            return renderFormString((MapStack) contextStack);
-        } else {
-            Debug.logWarning("Call renderFormString with a non-MapStack: " + (contextStack == null ? "null" : contextStack.getClass().getName()), module);
-            return renderFormString();
-        }
-    }
-    public StringWriter renderFormString(MapStack<String> contextStack) throws Exception {
-        // create a new context with the current context on the bottom
-        contextStack.push(this.context);
-        StringWriter buffer = new StringWriter();
-        FormRenderer formRenderer = new FormRenderer(modelForm, renderer);
-        formRenderer.render(buffer, contextStack);
-        contextStack.pop();
-        return buffer;
-    }
-    public StringWriter renderFormString() throws Exception {
-        StringWriter buffer = new StringWriter();
-        FormRenderer formRenderer = new FormRenderer(modelForm, renderer);
-        formRenderer.render(buffer, context);
-        return buffer;
-    }
-
-    /**
-     * Tells the form library whether this is a response to an error or not.
-     * Defaults on initialization according to the presense of an errorMessage
-     * in the request or if an isError parameter was passed to the page with
-     * the value "true". If true then the prefilled values will come from the
-     * parameters Map instead of the value Map.
-     */
-    public void setIsError(boolean isError) {
-        this.context.put("isError", Boolean.valueOf(isError));
-    }
-
-    public boolean getIsError() {
-        Boolean isErrorBoolean = (Boolean) this.context.get("isError");
-        if (isErrorBoolean == null) {
-            return false;
-        } else {
-            return isErrorBoolean.booleanValue();
-        }
-    }
-
-    /**
-     * The "useRequestParameters" value in the form context tells the form library
-     * to use the request parameters to fill in values instead of the value map.
-     * This is generally used when it is an empty form to pre-set inital values.
-     * This is automatically set to false for list and multi forms. For related
-     * functionality see the setIsError method.
-     *
-     * @param useRequestParameters
-     */
-    public void setUseRequestParameters(boolean useRequestParameters) {
-        this.context.put("useRequestParameters", Boolean.valueOf(useRequestParameters));
-    }
-
-    public boolean getUseRequestParameters() {
-        Boolean useRequestParametersBoolean = (Boolean) this.context.get("useRequestParameters");
-        if (useRequestParametersBoolean == null) {
-            return false;
-        } else {
-            return useRequestParametersBoolean.booleanValue();
-        }
-    }
-
-    public void setFormOverrideName(String formName) {
-        this.context.put("formName", formName);
-    }
-
-    public void putInContext(String name, Object value) {
-        this.context.put(name, value);
-    }
-
-    public Object getFromContext(String name) {
-        return this.context.get(name);
-    }
-
-    public ModelForm getModelForm() {
-        return modelForm;
-    }
-
-    public FormStringRenderer getRenderer() {
-        return renderer;
-    }
-
-    public void setRenderer(FormStringRenderer renderer) {
-        this.renderer = renderer;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.widget.model.FormFactory;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.renderer.FormRenderer;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Widget Library - HTML Form Wrapper class - makes it easy to do the setup and render of a form
+ */
+public class HtmlFormWrapper {
+
+    public static final String module = HtmlFormWrapper.class.getName();
+
+    protected String resourceName;
+    protected String formName;
+    protected HttpServletRequest request;
+    protected HttpServletResponse response;
+    protected ModelForm modelForm;
+    protected FormStringRenderer renderer;
+    protected Map<String, Object> context;
+
+    protected HtmlFormWrapper() {}
+
+    public HtmlFormWrapper(String resourceName, String formName, HttpServletRequest request, HttpServletResponse response)
+            throws IOException, SAXException, ParserConfigurationException {
+        this.resourceName = resourceName;
+        this.formName = formName;
+        this.request = request;
+        this.response = response;
+        Delegator delegator = null;
+        try {
+            delegator = (Delegator) request.getAttribute("delegator");
+            LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
+            this.modelForm = FormFactory.getFormFromLocation(resourceName, formName, delegator.getModelReader(), dispatcher.getDispatchContext());
+        } catch (IllegalArgumentException iae) {
+            Debug.logWarning("Could not find form with name [" + formName + "] in class resource [" + resourceName + "], will try to load it using relative path syntax.", module);
+            this.modelForm = FormFactory.getFormFromWebappContext(resourceName, formName, request);
+        }
+
+        this.renderer = new HtmlFormRenderer(request, response);
+
+        this.context = new HashMap<String, Object>();
+        Map<String, Object> parameterMap = UtilHttp.getParameterMap(request);
+        context.put("parameters", parameterMap);
+
+        //make sure the locale is in the context
+        context.put("locale", UtilHttp.getLocale(request));
+        //make sure the timeZone is in the context
+        context.put("timeZone", UtilHttp.getTimeZone(request));
+
+        // if there was an error message, this is an error
+        if (UtilValidate.isNotEmpty(request.getAttribute("_ERROR_MESSAGE_"))) {
+            context.put("isError", Boolean.TRUE);
+        } else {
+            context.put("isError", Boolean.FALSE);
+        }
+
+        // if a parameter was passed saying this is an error, it is an error
+        if ("true".equals(parameterMap.get("isError"))) {
+            context.put("isError", Boolean.TRUE);
+        }
+
+        Map<String, String> uiLabelMap = UtilGenerics.cast(request.getAttribute("uiLabelMap"));
+        if (UtilValidate.isNotEmpty(uiLabelMap) && context.get("uiLabelMap") == null) {
+            Debug.logInfo("Got uiLabelMap: " + uiLabelMap, module);
+            context.put("uiLabelMap", uiLabelMap);
+        }
+        if (UtilValidate.isNotEmpty(delegator) && context.get("delegator") == null) {
+            context.put("delegator", delegator);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public StringWriter renderFormString(Object contextStack) throws Exception {
+        if (contextStack instanceof MapStack) {
+            return renderFormString((MapStack) contextStack);
+        } else {
+            Debug.logWarning("Call renderFormString with a non-MapStack: " + (contextStack == null ? "null" : contextStack.getClass().getName()), module);
+            return renderFormString();
+        }
+    }
+    public StringWriter renderFormString(MapStack<String> contextStack) throws Exception {
+        // create a new context with the current context on the bottom
+        contextStack.push(this.context);
+        StringWriter buffer = new StringWriter();
+        FormRenderer formRenderer = new FormRenderer(modelForm, renderer);
+        formRenderer.render(buffer, contextStack);
+        contextStack.pop();
+        return buffer;
+    }
+    public StringWriter renderFormString() throws Exception {
+        StringWriter buffer = new StringWriter();
+        FormRenderer formRenderer = new FormRenderer(modelForm, renderer);
+        formRenderer.render(buffer, context);
+        return buffer;
+    }
+
+    /**
+     * Tells the form library whether this is a response to an error or not.
+     * Defaults on initialization according to the presense of an errorMessage
+     * in the request or if an isError parameter was passed to the page with
+     * the value "true". If true then the prefilled values will come from the
+     * parameters Map instead of the value Map.
+     */
+    public void setIsError(boolean isError) {
+        this.context.put("isError", Boolean.valueOf(isError));
+    }
+
+    public boolean getIsError() {
+        Boolean isErrorBoolean = (Boolean) this.context.get("isError");
+        if (isErrorBoolean == null) {
+            return false;
+        } else {
+            return isErrorBoolean.booleanValue();
+        }
+    }
+
+    /**
+     * The "useRequestParameters" value in the form context tells the form library
+     * to use the request parameters to fill in values instead of the value map.
+     * This is generally used when it is an empty form to pre-set inital values.
+     * This is automatically set to false for list and multi forms. For related
+     * functionality see the setIsError method.
+     *
+     * @param useRequestParameters
+     */
+    public void setUseRequestParameters(boolean useRequestParameters) {
+        this.context.put("useRequestParameters", Boolean.valueOf(useRequestParameters));
+    }
+
+    public boolean getUseRequestParameters() {
+        Boolean useRequestParametersBoolean = (Boolean) this.context.get("useRequestParameters");
+        if (useRequestParametersBoolean == null) {
+            return false;
+        } else {
+            return useRequestParametersBoolean.booleanValue();
+        }
+    }
+
+    public void setFormOverrideName(String formName) {
+        this.context.put("formName", formName);
+    }
+
+    public void putInContext(String name, Object value) {
+        this.context.put(name, value);
+    }
+
+    public Object getFromContext(String name) {
+        return this.context.get(name);
+    }
+
+    public ModelForm getModelForm() {
+        return modelForm;
+    }
+
+    public FormStringRenderer getRenderer() {
+        return renderer;
+    }
+
+    public void setRenderer(FormStringRenderer renderer) {
+        this.renderer = renderer;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuRenderer.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlMenuRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuRenderer.java
index 77b36c1..15531a3 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuRenderer.java
@@ -1,592 +1,592 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.menu.MenuStringRenderer;
-import org.ofbiz.widget.menu.ModelMenu;
-import org.ofbiz.widget.menu.ModelMenuItem;
-import org.ofbiz.widget.CommonWidgetModels.*;
-import org.ofbiz.widget.menu.ModelMenuItem.MenuLink;
-
-/**
- * Widget Library - HTML Menu Renderer implementation
- */
-public class HtmlMenuRenderer extends HtmlWidgetRenderer implements MenuStringRenderer {
-
-    HttpServletRequest request;
-    HttpServletResponse response;
-    protected String userLoginIdAtPermGrant;
-    protected String permissionErrorMessage = "";
-
-    public static final String module = HtmlMenuRenderer.class.getName();
-
-    protected HtmlMenuRenderer() {}
-
-    public HtmlMenuRenderer(HttpServletRequest request, HttpServletResponse response) {
-        this.request = request;
-        this.response = response;
-    }
-
-    public void appendOfbizUrl(Appendable writer, String location) throws IOException {
-        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-        if (ctx == null) {
-            //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl, ctx is null(0): buffer=" + buffer.toString() + " location:" + location, "");
-            HttpSession session = request.getSession();
-            if (session != null) {
-                ctx = session.getServletContext();
-            } else {
-                //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl, session is null(1)", "");
-            }
-            if (ctx == null) {
-                throw new RuntimeException("ctx is null. location:" + location);
-            }
-                //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl, ctx is NOT null(2)", "");
-        }
-        Delegator delegator = (Delegator)request.getAttribute("delegator");
-        if (delegator == null) {
-                //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl, delegator is null(5)", "");
-        }
-        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-        // make and append the link
-        String s = rh.makeLink(this.request, this.response, location);
-        if (s.indexOf("null") >= 0) {
-            //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl(3), url: " + s, "");
-        }
-        writer.append(s);
-    }
-
-    public void appendContentUrl(Appendable writer, String location) throws IOException {
-        ServletContext ctx = (ServletContext) this.request.getAttribute("servletContext");
-        if (ctx == null) {
-            //if (Debug.infoOn()) Debug.logInfo("in appendContentUrl, ctx is null(0): buffer=" + buffer.toString() + " location:" + location, "");
-            HttpSession session = request.getSession();
-            if (session != null) {
-                ctx = session.getServletContext();
-            } else {
-                //if (Debug.infoOn()) Debug.logInfo("in appendContentUrl, session is null(1)", "");
-            }
-            if (ctx == null) {
-                throw new RuntimeException("ctx is null. location:" + location);
-            }
-            //if (Debug.infoOn()) Debug.logInfo("in appendContentUrl, ctx is NOT null(2)", "");
-            this.request.setAttribute("servletContext", ctx);
-        }
-        Delegator delegator = (Delegator) request.getAttribute("delegator");
-        if (delegator == null) {
-                //if (Debug.infoOn()) Debug.logInfo("in appendContentUrl, delegator is null(6)", "");
-        }
-        StringBuilder buffer = new StringBuilder();
-        ContentUrlTag.appendContentPrefix(this.request, buffer);
-        writer.append(buffer.toString());
-        writer.append(location);
-    }
-
-    public void appendTooltip(Appendable writer, Map<String, Object> context, ModelMenuItem modelMenuItem) throws IOException {
-        // render the tooltip
-        String tooltip = modelMenuItem.getTooltip(context);
-        if (UtilValidate.isNotEmpty(tooltip)) {
-            writer.append("<span class=\"");
-            String tooltipStyle = modelMenuItem.getTooltipStyle();
-            if (UtilValidate.isNotEmpty(tooltipStyle)) {
-                writer.append(tooltipStyle);
-            } else {
-                writer.append("tooltip");
-            }
-            writer.append("\"");
-            writer.append(tooltip);
-            writer.append("</span>");
-        }
-    }
-
-    public void renderFormatSimpleWrapperRows(Appendable writer, Map<String, Object> context, Object menuObj) throws IOException {
-        List<ModelMenuItem> menuItemList = ((ModelMenu) menuObj).getMenuItemList();
-        for (ModelMenuItem currentMenuItem: menuItemList) {
-            renderMenuItem(writer, context, currentMenuItem);
-        }
-    }
-
-    public void renderMenuItem(Appendable writer, Map<String, Object> context, ModelMenuItem menuItem) throws IOException {
-
-        //Debug.logInfo("in renderMenuItem, menuItem:" + menuItem.getName() + " context:" + context ,"");
-        boolean hideThisItem = isHideIfSelected(menuItem, context);
-        //if (Debug.infoOn()) Debug.logInfo("in HtmlMenuRendererImage, hideThisItem:" + hideThisItem,"");
-        if (hideThisItem)
-            return;
-
-        String style = menuItem.getWidgetStyle();
-
-        if (menuItem.isSelected(context)) {
-            style = menuItem.getSelectedStyle();
-            if (UtilValidate.isEmpty(style)) {
-                style = "selected";
-            }
-        }
-
-        if (this.isDisableIfEmpty(menuItem, context)) {
-            style = menuItem.getDisabledTitleStyle();
-        }
-
-        writer.append("  <li");
-        String alignStyle = menuItem.getAlignStyle();
-        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(alignStyle)) {
-            writer.append(" class=\"");
-            if (UtilValidate.isNotEmpty(style)) {
-                writer.append(style).append(" ");
-            }
-            if (UtilValidate.isNotEmpty(alignStyle)) {
-                writer.append(alignStyle);
-            }
-            writer.append("\"");
-        }
-        String toolTip = menuItem.getTooltip(context);
-        if (UtilValidate.isNotEmpty(toolTip)) {
-            writer.append(" title=\"").append(toolTip).append("\"");
-        }
-        writer.append(">");
-
-        MenuLink link = menuItem.getLink();
-        //if (Debug.infoOn()) Debug.logInfo("in HtmlMenuRendererImage, link(0):" + link,"");
-        if (link != null) {
-            renderLink(writer, context, link);
-        } else {
-            String txt = menuItem.getTitle(context);
-            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-            if (simpleEncoder != null) {
-                txt = simpleEncoder.encode(txt);
-            }
-            writer.append(txt);
-
-        }
-        if (!menuItem.getMenuItemList().isEmpty()) {
-            appendWhitespace(writer);
-            writer.append("    <ul>");
-            appendWhitespace(writer);
-            for (ModelMenuItem childMenuItem : menuItem.getMenuItemList()) {
-                childMenuItem.renderMenuItemString(writer, context, this);
-            }
-            writer.append("    </ul>");
-            appendWhitespace(writer);
-        }
-
-        writer.append("</li>");
-
-        appendWhitespace(writer);
-    }
-
-    public boolean isDisableIfEmpty(ModelMenuItem menuItem, Map<String, Object> context) {
-        boolean disabled = false;
-        String disableIfEmpty = menuItem.getDisableIfEmpty();
-        if (UtilValidate.isNotEmpty(disableIfEmpty)) {
-            List<String> keys = StringUtil.split(disableIfEmpty, "|");
-            for (String key: keys) {
-                Object obj = context.get(key);
-                if (obj == null) {
-                    disabled = true;
-                    break;
-                }
-            }
-        }
-        return disabled;
-    }
-
-/*
-    public String buildDivStr(ModelMenuItem menuItem, Map<String, Object> context) {
-        String divStr = "";
-        divStr =  menuItem.getTitle(context);
-        return divStr;
-    }
-*/
-    public void renderMenuOpen(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
-
-            //Debug.logInfo("in HtmlMenuRenderer, userLoginIdHasChanged:" + userLoginIdHasChanged,"");
-        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        renderBeginningBoundaryComment(writer, "Menu Widget", modelMenu);
-        writer.append("<div");
-        String menuId = modelMenu.getId();
-        if (UtilValidate.isNotEmpty(menuId)) {
-            writer.append(" id=\"").append(menuId).append("\"");
-        } else {
-            // TODO: Remove else after UI refactor - allow both id and style
-            String menuContainerStyle = modelMenu.getMenuContainerStyle(context);
-            if (UtilValidate.isNotEmpty(menuContainerStyle)) {
-                writer.append(" class=\"").append(menuContainerStyle).append("\"");
-            }
-        }
-        String menuWidth = modelMenu.getMenuWidth();
-        // TODO: Eliminate embedded styling after refactor
-        if (UtilValidate.isNotEmpty(menuWidth)) {
-            writer.append(" style=\"width:").append(menuWidth).append(";\"");
-        }
-        writer.append(">");
-        appendWhitespace(writer);
-        String menuTitle = modelMenu.getTitle(context);
-        if (UtilValidate.isNotEmpty(menuTitle)) {
-            writer.append("<h2>").append(menuTitle).append("</h2>");
-            appendWhitespace(writer);
-        }
-        if (modelMenu.renderedMenuItemCount(context) > 0) {
-            writer.append("<ul>");
-            appendWhitespace(writer);
-            writer.append("<li>");
-            appendWhitespace(writer);
-            writer.append(" <ul>");
-            appendWhitespace(writer);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see org.ofbiz.widget.menu.MenuStringRenderer#renderMenuClose(java.io.Writer, java.util.Map, org.ofbiz.widget.menu.ModelMenu)
-     */
-    public void renderMenuClose(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
-        // TODO: div can't be directly inside an UL
-        String fillStyle = modelMenu.getFillStyle();
-        if (UtilValidate.isNotEmpty(fillStyle)) {
-            writer.append("<div class=\"").append(fillStyle).append("\">&nbsp;</div>");
-        }
-        //String menuContainerStyle = modelMenu.getMenuContainerStyle(context);
-        if (modelMenu.renderedMenuItemCount(context) > 0) {      
-            writer.append(" </ul>");
-            appendWhitespace(writer);
-            writer.append("</li>");
-            appendWhitespace(writer);
-            writer.append("</ul>");
-            appendWhitespace(writer);
-        }
-        writer.append(" <br class=\"clear\"/>");
-        appendWhitespace(writer);
-        writer.append("</div>");
-        appendWhitespace(writer);
-        renderEndingBoundaryComment(writer, "Menu Widget", modelMenu);
-
-        GenericValue userLogin = (GenericValue)request.getSession().getAttribute("userLogin");
-        if (userLogin != null) {
-            String userLoginId = userLogin.getString("userLoginId");
-            //request.getSession().setAttribute("userLoginIdAtPermGrant", userLoginId);
-            setUserLoginIdAtPermGrant(userLoginId);
-            //Debug.logInfo("in HtmlMenuRenderer, userLoginId(Close):" + userLoginId + " userLoginIdAtPermGrant:" + request.getSession().getAttribute("userLoginIdAtPermGrant"),"");
-        } else {
-            request.getSession().setAttribute("userLoginIdAtPermGrant", null);
-        }
-    }
-
-    public void renderFormatSimpleWrapperOpen(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
-        //appendWhitespace(writer);
-    }
-
-    public void renderFormatSimpleWrapperClose(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
-        //appendWhitespace(writer);
-    }
-
-    public void setRequest(HttpServletRequest request) {
-        this.request = request;
-    }
-
-    public void setResponse(HttpServletResponse response) {
-        this.response = response;
-    }
-
-
-    /**
-     * @param string
-     */
-    public void setUserLoginIdAtPermGrant(String string) {
-            //Debug.logInfo("in HtmlMenuRenderer,  userLoginIdAtPermGrant(setUserLoginIdAtPermGrant):" + string,"");
-        this.userLoginIdAtPermGrant = string;
-    }
-
-    public String getUserLoginIdAtPermGrant() {
-        return this.userLoginIdAtPermGrant;
-    }
-
-    public boolean isHideIfSelected(ModelMenuItem menuItem, Map<String, Object> context) {
-        ModelMenu menu = menuItem.getModelMenu();
-        String currentMenuItemName = menu.getSelectedMenuItemContextFieldName(context);
-        String currentItemName = menuItem.getName();
-        Boolean hideIfSelected = menuItem.getHideIfSelected();
-            //Debug.logInfo("in HtmlMenuRenderer, currentMenuItemName:" + currentMenuItemName + " currentItemName:" + currentItemName + " hideIfSelected:" + hideIfSelected,"");
-        return (hideIfSelected != null && hideIfSelected.booleanValue() && currentMenuItemName != null && currentMenuItemName.equals(currentItemName));
-    }
-
-
-    public boolean userLoginIdHasChanged() {
-        boolean hasChanged = false;
-        GenericValue userLogin = (GenericValue)request.getSession().getAttribute("userLogin");
-        userLoginIdAtPermGrant = getUserLoginIdAtPermGrant();
-        //userLoginIdAtPermGrant = (String)request.getSession().getAttribute("userLoginIdAtPermGrant");
-        String userLoginId = null;
-        if (userLogin != null)
-            userLoginId = userLogin.getString("userLoginId");
-            //Debug.logInfo("in HtmlMenuRenderer, userLoginId:" + userLoginId + " userLoginIdAtPermGrant:" + userLoginIdAtPermGrant ,"");
-        if ((userLoginId == null && userLoginIdAtPermGrant != null)
-           || (userLoginId != null && userLoginIdAtPermGrant == null)
-           || ((userLoginId != null && userLoginIdAtPermGrant != null)
-              && !userLoginId.equals(userLoginIdAtPermGrant))) {
-            hasChanged = true;
-        } else {
-            if (userLoginIdAtPermGrant != null)
-               hasChanged = true;
-            else
-               hasChanged = false;
-
-            userLoginIdAtPermGrant = null;
-        }
-        return hasChanged;
-    }
-
-    public String getTitle(ModelMenuItem menuItem, Map<String, Object> context) {
-        String title = null;
-        title = menuItem.getTitle(context);
-        return title;
-    }
-
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelMenuItem.MenuLink link) throws IOException {
-        String target = link.getTarget(context);
-        ModelMenuItem menuItem = link.getLinkMenuItem();
-        if (isDisableIfEmpty(menuItem, context)) {
-            target = null;
-        }
-
-        if (UtilValidate.isNotEmpty(target)) {
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-
-            String targetWindow = link.getTargetWindow(context);
-            String uniqueItemName = menuItem.getModelMenu().getName() + "_" + menuItem.getName() + "_LF_" + UtilMisc.<String>addToBigDecimalInMap(context, "menuUniqueItemIndex", BigDecimal.ONE);
-
-            String linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request);
-            if ("hidden-form".equals(linkType)) {
-                writer.append("<form method=\"post\"");
-                writer.append(" action=\"");
-                // note that this passes null for the parameterList on purpose so they won't be put into the URL
-                WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), null, link.getPrefix(context),
-                        link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
-                writer.append("\"");
-
-                if (UtilValidate.isNotEmpty(targetWindow)) {
-                    writer.append(" target=\"");
-                    writer.append(targetWindow);
-                    writer.append("\"");
-                }
-
-                writer.append(" name=\"");
-                writer.append(uniqueItemName);
-                writer.append("\">");
-
-                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-                for (Map.Entry<String, String> parameter: link.getParameterMap(context).entrySet()) {
-                    writer.append("<input name=\"");
-                    writer.append(parameter.getKey());
-                    writer.append("\" value=\"");
-                    if (simpleEncoder != null) {
-                        writer.append(simpleEncoder.encode(parameter.getValue()));
-                    } else {
-                        writer.append(parameter.getValue());
-                    }
-                    writer.append("\" type=\"hidden\"/>");
-                }
-
-                writer.append("</form>");
-            }
-
-            writer.append("<a");
-            String id = link.getId(context);
-            if (UtilValidate.isNotEmpty(id)) {
-                writer.append(" id=\"");
-                writer.append(id);
-                writer.append("\"");
-            }
-
-            String style = link.getStyle(context);
-            if (UtilValidate.isNotEmpty(style)) {
-                writer.append(" class=\"");
-                writer.append(style);
-                writer.append("\"");
-            }
-            String name = link.getName(context);
-            if (UtilValidate.isNotEmpty(name)) {
-                writer.append(" name=\"");
-                writer.append(name);
-                writer.append("\"");
-            }
-            if (!"hidden-form".equals(linkType)) {
-                if (UtilValidate.isNotEmpty(targetWindow)) {
-                    writer.append(" target=\"");
-                    writer.append(targetWindow);
-                    writer.append("\"");
-                }
-            }
-
-            writer.append(" href=\"");
-            String confirmationMsg = null;
-            if ("hidden-form".equals(linkType)) {
-                if (UtilValidate.isNotEmpty(confirmationMsg)) {
-                    writer.append("javascript:confirmActionFormLink('");
-                    writer.append(confirmationMsg);
-                    writer.append("', '");
-                    writer.append(uniqueItemName);
-                    writer.append("')");
-                } else {
-                    writer.append("javascript:document.");
-                    writer.append(uniqueItemName);
-                    writer.append(".submit()");
-                }
-            } else {
-                if (UtilValidate.isNotEmpty(confirmationMsg)) {
-                    writer.append("javascript:confirmActionLink('");
-                    writer.append(confirmationMsg);
-                    writer.append("', '");
-                    WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
-                            link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
-                    writer.append("')");
-                } else {
-                WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
-                        link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
-                }
-            }
-            writer.append("\">");
-        }
-
-        // the text
-        Image img = link.getImage();
-        if (img != null) {
-            renderImage(writer, context, img);
-            writer.append("&nbsp;" + link.getText(context));
-        } else {
-            writer.append(link.getText(context));
-        }
-
-        if (UtilValidate.isNotEmpty(target)) {
-            // close tag
-            writer.append("</a>");
-        }
-
-        /* NOTE DEJ20090316: This was here as a comment and not sure what it is for or if it is useful... can probably be safely removed in the future if still not used/needed
-        boolean isSelected = menuItem.isSelected(context);
-
-        String style = null;
-
-        if (isSelected) {
-        style = menuItem.getSelectedStyle();
-        } else {
-        style = link.getStyle(context);
-        if (UtilValidate.isEmpty(style))
-        style = menuItem.getTitleStyle();
-        if (UtilValidate.isEmpty(style))
-        style = menuItem.getWidgetStyle();
-        }
-
-        if (menuItem.getDisabled()) {
-        style = menuItem.getDisabledTitleStyle();
-        }
-
-        if (UtilValidate.isNotEmpty(style)) {
-        writer.append(" class=\"");
-        writer.append(style);
-        writer.append("\"");
-        }
-        */
-    }
-
-    public void renderImage(Appendable writer, Map<String, Object> context, Image image) throws IOException {
-        // open tag
-        writer.append("<img ");
-        String id = image.getId(context);
-        if (UtilValidate.isNotEmpty(id)) {
-            writer.append(" id=\"");
-            writer.append(id);
-            writer.append("\"");
-        }
-        String style = image.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append(" class=\"");
-            writer.append(style);
-            writer.append("\"");
-        }
-        String wid = image.getWidth(context);
-        if (UtilValidate.isNotEmpty(wid)) {
-            writer.append(" width=\"");
-            writer.append(wid);
-            writer.append("\"");
-        }
-        String hgt = image.getHeight(context);
-        if (UtilValidate.isNotEmpty(hgt)) {
-            writer.append(" height=\"");
-            writer.append(hgt);
-            writer.append("\"");
-        }
-        String border = image.getBorder(context);
-        if (UtilValidate.isNotEmpty(border)) {
-            writer.append(" border=\"");
-            writer.append(border);
-            writer.append("\"");
-        }
-        String src = image.getSrc(context);
-        if (UtilValidate.isNotEmpty(src)) {
-            writer.append(" src=\"");
-            String urlMode = image.getUrlMode();
-            boolean fullPath = false;
-            boolean secure = false;
-            boolean encode = false;
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-            if (urlMode != null && urlMode.equalsIgnoreCase("ofbiz")) {
-                if (request != null && response != null) {
-                    ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                    RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                    String urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
-                    writer.append(urlString);
-                } else {
-                    writer.append(src);
-                }
-            } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
-                if (request != null && response != null) {
-                    StringBuilder newURL = new StringBuilder();
-                    ContentUrlTag.appendContentPrefix(request, newURL);
-                    newURL.append(src);
-                    writer.append(newURL.toString());
-                }
-            } else {
-                writer.append(src);
-            }
-
-            writer.append("\"");
-        }
-        writer.append("/>");
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.webapp.control.RequestHandler;
+import org.ofbiz.webapp.taglib.ContentUrlTag;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.CommonWidgetModels.Image;
+import org.ofbiz.widget.model.ModelMenu;
+import org.ofbiz.widget.model.ModelMenuItem;
+import org.ofbiz.widget.model.ModelMenuItem.MenuLink;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+
+/**
+ * Widget Library - HTML Menu Renderer implementation
+ */
+public class HtmlMenuRenderer extends HtmlWidgetRenderer implements MenuStringRenderer {
+
+    HttpServletRequest request;
+    HttpServletResponse response;
+    protected String userLoginIdAtPermGrant;
+    protected String permissionErrorMessage = "";
+
+    public static final String module = HtmlMenuRenderer.class.getName();
+
+    protected HtmlMenuRenderer() {}
+
+    public HtmlMenuRenderer(HttpServletRequest request, HttpServletResponse response) {
+        this.request = request;
+        this.response = response;
+    }
+
+    public void appendOfbizUrl(Appendable writer, String location) throws IOException {
+        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+        if (ctx == null) {
+            //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl, ctx is null(0): buffer=" + buffer.toString() + " location:" + location, "");
+            HttpSession session = request.getSession();
+            if (session != null) {
+                ctx = session.getServletContext();
+            } else {
+                //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl, session is null(1)", "");
+            }
+            if (ctx == null) {
+                throw new RuntimeException("ctx is null. location:" + location);
+            }
+                //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl, ctx is NOT null(2)", "");
+        }
+        Delegator delegator = (Delegator)request.getAttribute("delegator");
+        if (delegator == null) {
+                //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl, delegator is null(5)", "");
+        }
+        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+        // make and append the link
+        String s = rh.makeLink(this.request, this.response, location);
+        if (s.indexOf("null") >= 0) {
+            //if (Debug.infoOn()) Debug.logInfo("in appendOfbizUrl(3), url: " + s, "");
+        }
+        writer.append(s);
+    }
+
+    public void appendContentUrl(Appendable writer, String location) throws IOException {
+        ServletContext ctx = (ServletContext) this.request.getAttribute("servletContext");
+        if (ctx == null) {
+            //if (Debug.infoOn()) Debug.logInfo("in appendContentUrl, ctx is null(0): buffer=" + buffer.toString() + " location:" + location, "");
+            HttpSession session = request.getSession();
+            if (session != null) {
+                ctx = session.getServletContext();
+            } else {
+                //if (Debug.infoOn()) Debug.logInfo("in appendContentUrl, session is null(1)", "");
+            }
+            if (ctx == null) {
+                throw new RuntimeException("ctx is null. location:" + location);
+            }
+            //if (Debug.infoOn()) Debug.logInfo("in appendContentUrl, ctx is NOT null(2)", "");
+            this.request.setAttribute("servletContext", ctx);
+        }
+        Delegator delegator = (Delegator) request.getAttribute("delegator");
+        if (delegator == null) {
+                //if (Debug.infoOn()) Debug.logInfo("in appendContentUrl, delegator is null(6)", "");
+        }
+        StringBuilder buffer = new StringBuilder();
+        ContentUrlTag.appendContentPrefix(this.request, buffer);
+        writer.append(buffer.toString());
+        writer.append(location);
+    }
+
+    public void appendTooltip(Appendable writer, Map<String, Object> context, ModelMenuItem modelMenuItem) throws IOException {
+        // render the tooltip
+        String tooltip = modelMenuItem.getTooltip(context);
+        if (UtilValidate.isNotEmpty(tooltip)) {
+            writer.append("<span class=\"");
+            String tooltipStyle = modelMenuItem.getTooltipStyle();
+            if (UtilValidate.isNotEmpty(tooltipStyle)) {
+                writer.append(tooltipStyle);
+            } else {
+                writer.append("tooltip");
+            }
+            writer.append("\"");
+            writer.append(tooltip);
+            writer.append("</span>");
+        }
+    }
+
+    public void renderFormatSimpleWrapperRows(Appendable writer, Map<String, Object> context, Object menuObj) throws IOException {
+        List<ModelMenuItem> menuItemList = ((ModelMenu) menuObj).getMenuItemList();
+        for (ModelMenuItem currentMenuItem: menuItemList) {
+            renderMenuItem(writer, context, currentMenuItem);
+        }
+    }
+
+    public void renderMenuItem(Appendable writer, Map<String, Object> context, ModelMenuItem menuItem) throws IOException {
+
+        //Debug.logInfo("in renderMenuItem, menuItem:" + menuItem.getName() + " context:" + context ,"");
+        boolean hideThisItem = isHideIfSelected(menuItem, context);
+        //if (Debug.infoOn()) Debug.logInfo("in HtmlMenuRendererImage, hideThisItem:" + hideThisItem,"");
+        if (hideThisItem)
+            return;
+
+        String style = menuItem.getWidgetStyle();
+
+        if (menuItem.isSelected(context)) {
+            style = menuItem.getSelectedStyle();
+            if (UtilValidate.isEmpty(style)) {
+                style = "selected";
+            }
+        }
+
+        if (this.isDisableIfEmpty(menuItem, context)) {
+            style = menuItem.getDisabledTitleStyle();
+        }
+
+        writer.append("  <li");
+        String alignStyle = menuItem.getAlignStyle();
+        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(alignStyle)) {
+            writer.append(" class=\"");
+            if (UtilValidate.isNotEmpty(style)) {
+                writer.append(style).append(" ");
+            }
+            if (UtilValidate.isNotEmpty(alignStyle)) {
+                writer.append(alignStyle);
+            }
+            writer.append("\"");
+        }
+        String toolTip = menuItem.getTooltip(context);
+        if (UtilValidate.isNotEmpty(toolTip)) {
+            writer.append(" title=\"").append(toolTip).append("\"");
+        }
+        writer.append(">");
+
+        MenuLink link = menuItem.getLink();
+        //if (Debug.infoOn()) Debug.logInfo("in HtmlMenuRendererImage, link(0):" + link,"");
+        if (link != null) {
+            renderLink(writer, context, link);
+        } else {
+            String txt = menuItem.getTitle(context);
+            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+            if (simpleEncoder != null) {
+                txt = simpleEncoder.encode(txt);
+            }
+            writer.append(txt);
+
+        }
+        if (!menuItem.getMenuItemList().isEmpty()) {
+            appendWhitespace(writer);
+            writer.append("    <ul>");
+            appendWhitespace(writer);
+            for (ModelMenuItem childMenuItem : menuItem.getMenuItemList()) {
+                childMenuItem.renderMenuItemString(writer, context, this);
+            }
+            writer.append("    </ul>");
+            appendWhitespace(writer);
+        }
+
+        writer.append("</li>");
+
+        appendWhitespace(writer);
+    }
+
+    public boolean isDisableIfEmpty(ModelMenuItem menuItem, Map<String, Object> context) {
+        boolean disabled = false;
+        String disableIfEmpty = menuItem.getDisableIfEmpty();
+        if (UtilValidate.isNotEmpty(disableIfEmpty)) {
+            List<String> keys = StringUtil.split(disableIfEmpty, "|");
+            for (String key: keys) {
+                Object obj = context.get(key);
+                if (obj == null) {
+                    disabled = true;
+                    break;
+                }
+            }
+        }
+        return disabled;
+    }
+
+/*
+    public String buildDivStr(ModelMenuItem menuItem, Map<String, Object> context) {
+        String divStr = "";
+        divStr =  menuItem.getTitle(context);
+        return divStr;
+    }
+*/
+    public void renderMenuOpen(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
+
+            //Debug.logInfo("in HtmlMenuRenderer, userLoginIdHasChanged:" + userLoginIdHasChanged,"");
+        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+        renderBeginningBoundaryComment(writer, "Menu Widget", modelMenu);
+        writer.append("<div");
+        String menuId = modelMenu.getId();
+        if (UtilValidate.isNotEmpty(menuId)) {
+            writer.append(" id=\"").append(menuId).append("\"");
+        } else {
+            // TODO: Remove else after UI refactor - allow both id and style
+            String menuContainerStyle = modelMenu.getMenuContainerStyle(context);
+            if (UtilValidate.isNotEmpty(menuContainerStyle)) {
+                writer.append(" class=\"").append(menuContainerStyle).append("\"");
+            }
+        }
+        String menuWidth = modelMenu.getMenuWidth();
+        // TODO: Eliminate embedded styling after refactor
+        if (UtilValidate.isNotEmpty(menuWidth)) {
+            writer.append(" style=\"width:").append(menuWidth).append(";\"");
+        }
+        writer.append(">");
+        appendWhitespace(writer);
+        String menuTitle = modelMenu.getTitle(context);
+        if (UtilValidate.isNotEmpty(menuTitle)) {
+            writer.append("<h2>").append(menuTitle).append("</h2>");
+            appendWhitespace(writer);
+        }
+        if (modelMenu.renderedMenuItemCount(context) > 0) {
+            writer.append("<ul>");
+            appendWhitespace(writer);
+            writer.append("<li>");
+            appendWhitespace(writer);
+            writer.append(" <ul>");
+            appendWhitespace(writer);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.ofbiz.widget.menu.MenuStringRenderer#renderMenuClose(java.io.Writer, java.util.Map, org.ofbiz.widget.menu.ModelMenu)
+     */
+    public void renderMenuClose(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
+        // TODO: div can't be directly inside an UL
+        String fillStyle = modelMenu.getFillStyle();
+        if (UtilValidate.isNotEmpty(fillStyle)) {
+            writer.append("<div class=\"").append(fillStyle).append("\">&nbsp;</div>");
+        }
+        //String menuContainerStyle = modelMenu.getMenuContainerStyle(context);
+        if (modelMenu.renderedMenuItemCount(context) > 0) {      
+            writer.append(" </ul>");
+            appendWhitespace(writer);
+            writer.append("</li>");
+            appendWhitespace(writer);
+            writer.append("</ul>");
+            appendWhitespace(writer);
+        }
+        writer.append(" <br class=\"clear\"/>");
+        appendWhitespace(writer);
+        writer.append("</div>");
+        appendWhitespace(writer);
+        renderEndingBoundaryComment(writer, "Menu Widget", modelMenu);
+
+        GenericValue userLogin = (GenericValue)request.getSession().getAttribute("userLogin");
+        if (userLogin != null) {
+            String userLoginId = userLogin.getString("userLoginId");
+            //request.getSession().setAttribute("userLoginIdAtPermGrant", userLoginId);
+            setUserLoginIdAtPermGrant(userLoginId);
+            //Debug.logInfo("in HtmlMenuRenderer, userLoginId(Close):" + userLoginId + " userLoginIdAtPermGrant:" + request.getSession().getAttribute("userLoginIdAtPermGrant"),"");
+        } else {
+            request.getSession().setAttribute("userLoginIdAtPermGrant", null);
+        }
+    }
+
+    public void renderFormatSimpleWrapperOpen(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
+        //appendWhitespace(writer);
+    }
+
+    public void renderFormatSimpleWrapperClose(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) throws IOException {
+        //appendWhitespace(writer);
+    }
+
+    public void setRequest(HttpServletRequest request) {
+        this.request = request;
+    }
+
+    public void setResponse(HttpServletResponse response) {
+        this.response = response;
+    }
+
+
+    /**
+     * @param string
+     */
+    public void setUserLoginIdAtPermGrant(String string) {
+            //Debug.logInfo("in HtmlMenuRenderer,  userLoginIdAtPermGrant(setUserLoginIdAtPermGrant):" + string,"");
+        this.userLoginIdAtPermGrant = string;
+    }
+
+    public String getUserLoginIdAtPermGrant() {
+        return this.userLoginIdAtPermGrant;
+    }
+
+    public boolean isHideIfSelected(ModelMenuItem menuItem, Map<String, Object> context) {
+        ModelMenu menu = menuItem.getModelMenu();
+        String currentMenuItemName = menu.getSelectedMenuItemContextFieldName(context);
+        String currentItemName = menuItem.getName();
+        Boolean hideIfSelected = menuItem.getHideIfSelected();
+            //Debug.logInfo("in HtmlMenuRenderer, currentMenuItemName:" + currentMenuItemName + " currentItemName:" + currentItemName + " hideIfSelected:" + hideIfSelected,"");
+        return (hideIfSelected != null && hideIfSelected.booleanValue() && currentMenuItemName != null && currentMenuItemName.equals(currentItemName));
+    }
+
+
+    public boolean userLoginIdHasChanged() {
+        boolean hasChanged = false;
+        GenericValue userLogin = (GenericValue)request.getSession().getAttribute("userLogin");
+        userLoginIdAtPermGrant = getUserLoginIdAtPermGrant();
+        //userLoginIdAtPermGrant = (String)request.getSession().getAttribute("userLoginIdAtPermGrant");
+        String userLoginId = null;
+        if (userLogin != null)
+            userLoginId = userLogin.getString("userLoginId");
+            //Debug.logInfo("in HtmlMenuRenderer, userLoginId:" + userLoginId + " userLoginIdAtPermGrant:" + userLoginIdAtPermGrant ,"");
+        if ((userLoginId == null && userLoginIdAtPermGrant != null)
+           || (userLoginId != null && userLoginIdAtPermGrant == null)
+           || ((userLoginId != null && userLoginIdAtPermGrant != null)
+              && !userLoginId.equals(userLoginIdAtPermGrant))) {
+            hasChanged = true;
+        } else {
+            if (userLoginIdAtPermGrant != null)
+               hasChanged = true;
+            else
+               hasChanged = false;
+
+            userLoginIdAtPermGrant = null;
+        }
+        return hasChanged;
+    }
+
+    public String getTitle(ModelMenuItem menuItem, Map<String, Object> context) {
+        String title = null;
+        title = menuItem.getTitle(context);
+        return title;
+    }
+
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelMenuItem.MenuLink link) throws IOException {
+        String target = link.getTarget(context);
+        ModelMenuItem menuItem = link.getLinkMenuItem();
+        if (isDisableIfEmpty(menuItem, context)) {
+            target = null;
+        }
+
+        if (UtilValidate.isNotEmpty(target)) {
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+
+            String targetWindow = link.getTargetWindow(context);
+            String uniqueItemName = menuItem.getModelMenu().getName() + "_" + menuItem.getName() + "_LF_" + UtilMisc.<String>addToBigDecimalInMap(context, "menuUniqueItemIndex", BigDecimal.ONE);
+
+            String linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request);
+            if ("hidden-form".equals(linkType)) {
+                writer.append("<form method=\"post\"");
+                writer.append(" action=\"");
+                // note that this passes null for the parameterList on purpose so they won't be put into the URL
+                WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), null, link.getPrefix(context),
+                        link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
+                writer.append("\"");
+
+                if (UtilValidate.isNotEmpty(targetWindow)) {
+                    writer.append(" target=\"");
+                    writer.append(targetWindow);
+                    writer.append("\"");
+                }
+
+                writer.append(" name=\"");
+                writer.append(uniqueItemName);
+                writer.append("\">");
+
+                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+                for (Map.Entry<String, String> parameter: link.getParameterMap(context).entrySet()) {
+                    writer.append("<input name=\"");
+                    writer.append(parameter.getKey());
+                    writer.append("\" value=\"");
+                    if (simpleEncoder != null) {
+                        writer.append(simpleEncoder.encode(parameter.getValue()));
+                    } else {
+                        writer.append(parameter.getValue());
+                    }
+                    writer.append("\" type=\"hidden\"/>");
+                }
+
+                writer.append("</form>");
+            }
+
+            writer.append("<a");
+            String id = link.getId(context);
+            if (UtilValidate.isNotEmpty(id)) {
+                writer.append(" id=\"");
+                writer.append(id);
+                writer.append("\"");
+            }
+
+            String style = link.getStyle(context);
+            if (UtilValidate.isNotEmpty(style)) {
+                writer.append(" class=\"");
+                writer.append(style);
+                writer.append("\"");
+            }
+            String name = link.getName(context);
+            if (UtilValidate.isNotEmpty(name)) {
+                writer.append(" name=\"");
+                writer.append(name);
+                writer.append("\"");
+            }
+            if (!"hidden-form".equals(linkType)) {
+                if (UtilValidate.isNotEmpty(targetWindow)) {
+                    writer.append(" target=\"");
+                    writer.append(targetWindow);
+                    writer.append("\"");
+                }
+            }
+
+            writer.append(" href=\"");
+            String confirmationMsg = null;
+            if ("hidden-form".equals(linkType)) {
+                if (UtilValidate.isNotEmpty(confirmationMsg)) {
+                    writer.append("javascript:confirmActionFormLink('");
+                    writer.append(confirmationMsg);
+                    writer.append("', '");
+                    writer.append(uniqueItemName);
+                    writer.append("')");
+                } else {
+                    writer.append("javascript:document.");
+                    writer.append(uniqueItemName);
+                    writer.append(".submit()");
+                }
+            } else {
+                if (UtilValidate.isNotEmpty(confirmationMsg)) {
+                    writer.append("javascript:confirmActionLink('");
+                    writer.append(confirmationMsg);
+                    writer.append("', '");
+                    WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
+                            link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
+                    writer.append("')");
+                } else {
+                WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
+                        link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
+                }
+            }
+            writer.append("\">");
+        }
+
+        // the text
+        Image img = link.getImage();
+        if (img != null) {
+            renderImage(writer, context, img);
+            writer.append("&nbsp;" + link.getText(context));
+        } else {
+            writer.append(link.getText(context));
+        }
+
+        if (UtilValidate.isNotEmpty(target)) {
+            // close tag
+            writer.append("</a>");
+        }
+
+        /* NOTE DEJ20090316: This was here as a comment and not sure what it is for or if it is useful... can probably be safely removed in the future if still not used/needed
+        boolean isSelected = menuItem.isSelected(context);
+
+        String style = null;
+
+        if (isSelected) {
+        style = menuItem.getSelectedStyle();
+        } else {
+        style = link.getStyle(context);
+        if (UtilValidate.isEmpty(style))
+        style = menuItem.getTitleStyle();
+        if (UtilValidate.isEmpty(style))
+        style = menuItem.getWidgetStyle();
+        }
+
+        if (menuItem.getDisabled()) {
+        style = menuItem.getDisabledTitleStyle();
+        }
+
+        if (UtilValidate.isNotEmpty(style)) {
+        writer.append(" class=\"");
+        writer.append(style);
+        writer.append("\"");
+        }
+        */
+    }
+
+    public void renderImage(Appendable writer, Map<String, Object> context, Image image) throws IOException {
+        // open tag
+        writer.append("<img ");
+        String id = image.getId(context);
+        if (UtilValidate.isNotEmpty(id)) {
+            writer.append(" id=\"");
+            writer.append(id);
+            writer.append("\"");
+        }
+        String style = image.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append(" class=\"");
+            writer.append(style);
+            writer.append("\"");
+        }
+        String wid = image.getWidth(context);
+        if (UtilValidate.isNotEmpty(wid)) {
+            writer.append(" width=\"");
+            writer.append(wid);
+            writer.append("\"");
+        }
+        String hgt = image.getHeight(context);
+        if (UtilValidate.isNotEmpty(hgt)) {
+            writer.append(" height=\"");
+            writer.append(hgt);
+            writer.append("\"");
+        }
+        String border = image.getBorder(context);
+        if (UtilValidate.isNotEmpty(border)) {
+            writer.append(" border=\"");
+            writer.append(border);
+            writer.append("\"");
+        }
+        String src = image.getSrc(context);
+        if (UtilValidate.isNotEmpty(src)) {
+            writer.append(" src=\"");
+            String urlMode = image.getUrlMode();
+            boolean fullPath = false;
+            boolean secure = false;
+            boolean encode = false;
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+            if (urlMode != null && urlMode.equalsIgnoreCase("ofbiz")) {
+                if (request != null && response != null) {
+                    ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                    RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                    String urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
+                    writer.append(urlString);
+                } else {
+                    writer.append(src);
+                }
+            } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
+                if (request != null && response != null) {
+                    StringBuilder newURL = new StringBuilder();
+                    ContentUrlTag.appendContentPrefix(request, newURL);
+                    newURL.append(src);
+                    writer.append(newURL.toString());
+                }
+            } else {
+                writer.append(src);
+            }
+
+            writer.append("\"");
+        }
+        writer.append("/>");
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuRendererImage.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuRendererImage.java
similarity index 95%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlMenuRendererImage.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuRendererImage.java
index e521b90..d0a51c6 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuRendererImage.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuRendererImage.java
@@ -1,80 +1,80 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.widget.WidgetContentWorker;
-import org.ofbiz.widget.menu.ModelMenuItem;
-
-/**
- * Widget Library - HTML Menu Renderer implementation
- */
-
-public class HtmlMenuRendererImage extends HtmlMenuRenderer {
-
-    protected HtmlMenuRendererImage() {}
-
-    public HtmlMenuRendererImage(HttpServletRequest request, HttpServletResponse response) {
-        super(request, response);
-    }
-
-
-    public String buildDivStr(ModelMenuItem menuItem, Map<String, Object> context) throws IOException {
-
-        StringBuilder imgStr = new StringBuilder("<img src=\"");
-        String contentId = menuItem.getAssociatedContentId(context);
-        Delegator delegator = (Delegator)request.getAttribute("delegator");
-        GenericValue webSitePublishPoint = null;
-                //Debug.logInfo("in HtmlMenuRendererImage, contentId:" + contentId,"");
-        try {
-            if (WidgetContentWorker.contentWorker != null) {
-                webSitePublishPoint = WidgetContentWorker.contentWorker.getWebSitePublishPointExt(delegator, contentId, false);
-            } else {
-                Debug.logError("Not rendering image because can't get WebSitePublishPoint, not ContentWorker found.", module);
-            }
-        } catch (GenericEntityException e) {
-                //Debug.logInfo("in HtmlMenuRendererImage, GEException:" + e.getMessage(),"");
-            throw new RuntimeException(e.getMessage());
-        }
-        String medallionLogoStr = webSitePublishPoint.getString("medallionLogo");
-        StringWriter buf = new StringWriter();
-        appendContentUrl(buf, medallionLogoStr);
-        imgStr.append(buf.toString());
-                //Debug.logInfo("in HtmlMenuRendererImage, imgStr:" + imgStr,"");
-        String cellWidth = menuItem.getCellWidth();
-        imgStr.append("\"");
-        if (UtilValidate.isNotEmpty(cellWidth))
-            imgStr.append(" width=\"").append(cellWidth).append("\" ");
-
-        imgStr.append(" border=\"0\" />");
-        return imgStr.toString();
-    }
-
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.widget.content.WidgetContentWorker;
+import org.ofbiz.widget.model.ModelMenuItem;
+
+/**
+ * Widget Library - HTML Menu Renderer implementation
+ */
+
+public class HtmlMenuRendererImage extends HtmlMenuRenderer {
+
+    protected HtmlMenuRendererImage() {}
+
+    public HtmlMenuRendererImage(HttpServletRequest request, HttpServletResponse response) {
+        super(request, response);
+    }
+
+
+    public String buildDivStr(ModelMenuItem menuItem, Map<String, Object> context) throws IOException {
+
+        StringBuilder imgStr = new StringBuilder("<img src=\"");
+        String contentId = menuItem.getAssociatedContentId(context);
+        Delegator delegator = (Delegator)request.getAttribute("delegator");
+        GenericValue webSitePublishPoint = null;
+                //Debug.logInfo("in HtmlMenuRendererImage, contentId:" + contentId,"");
+        try {
+            if (WidgetContentWorker.contentWorker != null) {
+                webSitePublishPoint = WidgetContentWorker.contentWorker.getWebSitePublishPointExt(delegator, contentId, false);
+            } else {
+                Debug.logError("Not rendering image because can't get WebSitePublishPoint, not ContentWorker found.", module);
+            }
+        } catch (GenericEntityException e) {
+                //Debug.logInfo("in HtmlMenuRendererImage, GEException:" + e.getMessage(),"");
+            throw new RuntimeException(e.getMessage());
+        }
+        String medallionLogoStr = webSitePublishPoint.getString("medallionLogo");
+        StringWriter buf = new StringWriter();
+        appendContentUrl(buf, medallionLogoStr);
+        imgStr.append(buf.toString());
+                //Debug.logInfo("in HtmlMenuRendererImage, imgStr:" + imgStr,"");
+        String cellWidth = menuItem.getCellWidth();
+        imgStr.append("\"");
+        if (UtilValidate.isNotEmpty(cellWidth))
+            imgStr.append(" width=\"").append(cellWidth).append("\" ");
+
+        imgStr.append(" border=\"0\" />");
+        return imgStr.toString();
+    }
+
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuWrapper.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuWrapper.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlMenuWrapper.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuWrapper.java
index dcb5898..54cb8d5 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuWrapper.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuWrapper.java
@@ -1,252 +1,252 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.widget.menu.MenuFactory;
-import org.ofbiz.widget.menu.MenuStringRenderer;
-import org.ofbiz.widget.menu.ModelMenu;
-import org.xml.sax.SAXException;
-
-
-/**
- * Widget Library - HTML Menu Wrapper class - makes it easy to do the setup and render of a menu
- */
-public class HtmlMenuWrapper {
-
-    public static final String module = HtmlMenuWrapper.class.getName();
-
-    protected String resourceName;
-    protected String menuName;
-    protected HttpServletRequest request;
-    protected HttpServletResponse response;
-    protected ModelMenu modelMenu;
-    protected MenuStringRenderer renderer;
-    protected Map<String, Object> context;
-
-    protected HtmlMenuWrapper() {}
-
-    public HtmlMenuWrapper(String resourceName, String menuName, HttpServletRequest request, HttpServletResponse response)
-            throws IOException, SAXException, ParserConfigurationException {
-        init(resourceName, menuName, request, response);
-    }
-
-    public void init(String resourceName, String menuName, HttpServletRequest request, HttpServletResponse response)
-            throws IOException, SAXException, ParserConfigurationException {
-        this.resourceName = resourceName;
-        this.menuName = menuName;
-        this.request = request;
-        this.response = response;
-
-        this.modelMenu = MenuFactory.getMenuFromWebappContext(resourceName, menuName, request);
-
-        this.renderer = getMenuRenderer();
-
-        this.context = new HashMap<String, Object>();
-        Map<String, Object> parameterMap = UtilHttp.getParameterMap(request);
-        context.put("parameters", parameterMap);
-
-        HttpSession session = request.getSession();
-        GenericValue userLogin = (GenericValue)session.getAttribute("userLogin");
-        context.put("userLogin", userLogin);
-
-        //make sure the locale is in the context
-        context.put("locale", UtilHttp.getLocale(request));
-
-        // if there was an error message, this is an error
-        if (UtilValidate.isNotEmpty(request.getAttribute("_ERROR_MESSAGE_"))) {
-            context.put("isError", Boolean.TRUE);
-        } else {
-            context.put("isError", Boolean.FALSE);
-        }
-
-        // if a parameter was passed saying this is an error, it is an error
-        if ("true".equals(parameterMap.get("isError"))) {
-            context.put("isError", Boolean.TRUE);
-        }
-    }
-
-    public MenuStringRenderer getMenuRenderer() {
-        return new HtmlMenuRenderer(request, response);
-    }
-
-    public String renderMenuString() throws IOException {
-        HttpServletRequest req = ((HtmlMenuRenderer)renderer).request;
-        ServletContext ctx = (ServletContext) req.getAttribute("servletContext");
-        if (ctx == null) {
-            if (Debug.infoOn()) Debug.logInfo("in renderMenuString, ctx is null(0)" , "");
-        }
-
-        Writer writer = new StringWriter();
-        modelMenu.renderMenuString(writer, context, renderer);
-
-        HttpServletRequest req2 = ((HtmlMenuRenderer)renderer).request;
-        ServletContext ctx2 = (ServletContext) req2.getAttribute("servletContext");
-        if (ctx2 == null) {
-            if (Debug.infoOn()) Debug.logInfo("in renderMenuString, ctx is null(2)" , "");
-        }
-
-        return writer.toString();
-    }
-
-    /**
-     * Tells the menu library whether this is a response to an error or not.
-     * Defaults on initialization according to the presense of an errorMessage
-     * in the request or if an isError parameter was passed to the page with
-     * the value "true". If true then the prefilled values will come from the
-     * parameters Map instead of the value Map.
-     */
-    public void setIsError(boolean isError) {
-        this.context.put("isError", Boolean.valueOf(isError));
-    }
-
-    public boolean getIsError() {
-        Boolean isErrorBoolean = (Boolean) this.context.get("isError");
-        if (isErrorBoolean == null) {
-            return false;
-        } else {
-            return isErrorBoolean.booleanValue();
-        }
-    }
-
-    public void setMenuOverrideName(String menuName) {
-        this.context.put("menuName", menuName);
-    }
-
-    public void putInContext(String name, Object value) {
-        this.context.put(name, value);
-    }
-
-    public void putInContext(String menuItemName, String valueName,  Object value) {
-        Map<String, Object> valueMap = UtilGenerics.toMap(context.get(menuItemName));
-        if (valueMap == null) {
-            valueMap = new HashMap<String, Object>();
-            context.put(menuItemName, valueMap);
-        }
-        valueMap.put(valueName, value);
-    }
-
-    public Object getFromContext(String name) {
-        return this.context.get(name);
-    }
-
-    public Object getFromContext(String menuItemName, String valueName) {
-        Map<String, Object> valueMap = UtilGenerics.toMap(context.get(menuItemName));
-        if (valueMap == null) {
-            valueMap = new HashMap<String, Object>();
-            context.put(menuItemName, valueMap);
-        }
-        return valueMap.get(valueName);
-    }
-
-    public ModelMenu getModelMenu() {
-        return modelMenu;
-    }
-
-    public MenuStringRenderer getRenderer() {
-        return renderer;
-    }
-
-    public void setRenderer(MenuStringRenderer renderer) {
-        this.renderer = renderer;
-    }
-
-    public void setRequest(HttpServletRequest request) {
-        this.request = request;
-        ((HtmlMenuRenderer)renderer).setRequest(request);
-    }
-
-    public void setResponse(HttpServletResponse response) {
-        this.response = response;
-        ((HtmlMenuRenderer)renderer).setResponse(response);
-    }
-
-    public HttpServletRequest getRequest() {
-        return ((HtmlMenuRenderer)renderer).request;
-    }
-
-    public HttpServletResponse getResponse() {
-        return ((HtmlMenuRenderer)renderer).response;
-    }
-
-    public static HtmlMenuWrapper getMenuWrapper(HttpServletRequest request, HttpServletResponse response, HttpSession session, String menuDefFile, String menuName, String menuWrapperClassName) {
-
-        HtmlMenuWrapper menuWrapper = null;
-
-        String menuSig = menuDefFile + "__" + menuName;
-        if (session != null) {
-             menuWrapper = (HtmlMenuWrapper)session.getAttribute(menuSig);
-        }
-
-        if (menuWrapper == null) {
-            try {
-                Class<?> cls = Class.forName("org.ofbiz.widget.html." + menuWrapperClassName);
-                menuWrapper = (HtmlMenuWrapper)cls.newInstance();
-                menuWrapper.init(menuDefFile, menuName, request, response);
-            } catch (InstantiationException e) {
-                throw new RuntimeException(e.getMessage());
-            } catch (IllegalAccessException e2) {
-                throw new RuntimeException(e2.getMessage());
-            } catch (ClassNotFoundException e3) {
-                throw new RuntimeException("Class not found:" + e3.getMessage());
-            } catch (IOException e4) {
-                throw new RuntimeException(e4.getMessage());
-            } catch (SAXException e5) {
-                throw new RuntimeException(e5.getMessage());
-            } catch (ParserConfigurationException e6) {
-                throw new RuntimeException(e6.getMessage());
-            }
-        } else {
-            menuWrapper.setRequest(request);
-            menuWrapper.setResponse(response);
-            Map<String, Object> parameterMap = UtilHttp.getParameterMap(request);
-            menuWrapper.setParameters(parameterMap);
-
-            GenericValue userLogin = (GenericValue)session.getAttribute("userLogin");
-            menuWrapper.putInContext("userLogin", userLogin);
-
-        }
-
-        if (session != null) {
-            session.setAttribute(menuSig, menuWrapper);
-        }
-        return menuWrapper;
-    }
-
-    public void setParameters(Map<String, Object> paramMap) {
-        context.put("parameters", paramMap);
-    }
-
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.widget.model.MenuFactory;
+import org.ofbiz.widget.model.ModelMenu;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Widget Library - HTML Menu Wrapper class - makes it easy to do the setup and render of a menu
+ */
+public class HtmlMenuWrapper {
+
+    public static final String module = HtmlMenuWrapper.class.getName();
+
+    protected String resourceName;
+    protected String menuName;
+    protected HttpServletRequest request;
+    protected HttpServletResponse response;
+    protected ModelMenu modelMenu;
+    protected MenuStringRenderer renderer;
+    protected Map<String, Object> context;
+
+    protected HtmlMenuWrapper() {}
+
+    public HtmlMenuWrapper(String resourceName, String menuName, HttpServletRequest request, HttpServletResponse response)
+            throws IOException, SAXException, ParserConfigurationException {
+        init(resourceName, menuName, request, response);
+    }
+
+    public void init(String resourceName, String menuName, HttpServletRequest request, HttpServletResponse response)
+            throws IOException, SAXException, ParserConfigurationException {
+        this.resourceName = resourceName;
+        this.menuName = menuName;
+        this.request = request;
+        this.response = response;
+
+        this.modelMenu = MenuFactory.getMenuFromWebappContext(resourceName, menuName, request);
+
+        this.renderer = getMenuRenderer();
+
+        this.context = new HashMap<String, Object>();
+        Map<String, Object> parameterMap = UtilHttp.getParameterMap(request);
+        context.put("parameters", parameterMap);
+
+        HttpSession session = request.getSession();
+        GenericValue userLogin = (GenericValue)session.getAttribute("userLogin");
+        context.put("userLogin", userLogin);
+
+        //make sure the locale is in the context
+        context.put("locale", UtilHttp.getLocale(request));
+
+        // if there was an error message, this is an error
+        if (UtilValidate.isNotEmpty(request.getAttribute("_ERROR_MESSAGE_"))) {
+            context.put("isError", Boolean.TRUE);
+        } else {
+            context.put("isError", Boolean.FALSE);
+        }
+
+        // if a parameter was passed saying this is an error, it is an error
+        if ("true".equals(parameterMap.get("isError"))) {
+            context.put("isError", Boolean.TRUE);
+        }
+    }
+
+    public MenuStringRenderer getMenuRenderer() {
+        return new HtmlMenuRenderer(request, response);
+    }
+
+    public String renderMenuString() throws IOException {
+        HttpServletRequest req = ((HtmlMenuRenderer)renderer).request;
+        ServletContext ctx = (ServletContext) req.getAttribute("servletContext");
+        if (ctx == null) {
+            if (Debug.infoOn()) Debug.logInfo("in renderMenuString, ctx is null(0)" , "");
+        }
+
+        Writer writer = new StringWriter();
+        modelMenu.renderMenuString(writer, context, renderer);
+
+        HttpServletRequest req2 = ((HtmlMenuRenderer)renderer).request;
+        ServletContext ctx2 = (ServletContext) req2.getAttribute("servletContext");
+        if (ctx2 == null) {
+            if (Debug.infoOn()) Debug.logInfo("in renderMenuString, ctx is null(2)" , "");
+        }
+
+        return writer.toString();
+    }
+
+    /**
+     * Tells the menu library whether this is a response to an error or not.
+     * Defaults on initialization according to the presense of an errorMessage
+     * in the request or if an isError parameter was passed to the page with
+     * the value "true". If true then the prefilled values will come from the
+     * parameters Map instead of the value Map.
+     */
+    public void setIsError(boolean isError) {
+        this.context.put("isError", Boolean.valueOf(isError));
+    }
+
+    public boolean getIsError() {
+        Boolean isErrorBoolean = (Boolean) this.context.get("isError");
+        if (isErrorBoolean == null) {
+            return false;
+        } else {
+            return isErrorBoolean.booleanValue();
+        }
+    }
+
+    public void setMenuOverrideName(String menuName) {
+        this.context.put("menuName", menuName);
+    }
+
+    public void putInContext(String name, Object value) {
+        this.context.put(name, value);
+    }
+
+    public void putInContext(String menuItemName, String valueName,  Object value) {
+        Map<String, Object> valueMap = UtilGenerics.toMap(context.get(menuItemName));
+        if (valueMap == null) {
+            valueMap = new HashMap<String, Object>();
+            context.put(menuItemName, valueMap);
+        }
+        valueMap.put(valueName, value);
+    }
+
+    public Object getFromContext(String name) {
+        return this.context.get(name);
+    }
+
+    public Object getFromContext(String menuItemName, String valueName) {
+        Map<String, Object> valueMap = UtilGenerics.toMap(context.get(menuItemName));
+        if (valueMap == null) {
+            valueMap = new HashMap<String, Object>();
+            context.put(menuItemName, valueMap);
+        }
+        return valueMap.get(valueName);
+    }
+
+    public ModelMenu getModelMenu() {
+        return modelMenu;
+    }
+
+    public MenuStringRenderer getRenderer() {
+        return renderer;
+    }
+
+    public void setRenderer(MenuStringRenderer renderer) {
+        this.renderer = renderer;
+    }
+
+    public void setRequest(HttpServletRequest request) {
+        this.request = request;
+        ((HtmlMenuRenderer)renderer).setRequest(request);
+    }
+
+    public void setResponse(HttpServletResponse response) {
+        this.response = response;
+        ((HtmlMenuRenderer)renderer).setResponse(response);
+    }
+
+    public HttpServletRequest getRequest() {
+        return ((HtmlMenuRenderer)renderer).request;
+    }
+
+    public HttpServletResponse getResponse() {
+        return ((HtmlMenuRenderer)renderer).response;
+    }
+
+    public static HtmlMenuWrapper getMenuWrapper(HttpServletRequest request, HttpServletResponse response, HttpSession session, String menuDefFile, String menuName, String menuWrapperClassName) {
+
+        HtmlMenuWrapper menuWrapper = null;
+
+        String menuSig = menuDefFile + "__" + menuName;
+        if (session != null) {
+             menuWrapper = (HtmlMenuWrapper)session.getAttribute(menuSig);
+        }
+
+        if (menuWrapper == null) {
+            try {
+                Class<?> cls = Class.forName("org.ofbiz.widget.html." + menuWrapperClassName);
+                menuWrapper = (HtmlMenuWrapper)cls.newInstance();
+                menuWrapper.init(menuDefFile, menuName, request, response);
+            } catch (InstantiationException e) {
+                throw new RuntimeException(e.getMessage());
+            } catch (IllegalAccessException e2) {
+                throw new RuntimeException(e2.getMessage());
+            } catch (ClassNotFoundException e3) {
+                throw new RuntimeException("Class not found:" + e3.getMessage());
+            } catch (IOException e4) {
+                throw new RuntimeException(e4.getMessage());
+            } catch (SAXException e5) {
+                throw new RuntimeException(e5.getMessage());
+            } catch (ParserConfigurationException e6) {
+                throw new RuntimeException(e6.getMessage());
+            }
+        } else {
+            menuWrapper.setRequest(request);
+            menuWrapper.setResponse(response);
+            Map<String, Object> parameterMap = UtilHttp.getParameterMap(request);
+            menuWrapper.setParameters(parameterMap);
+
+            GenericValue userLogin = (GenericValue)session.getAttribute("userLogin");
+            menuWrapper.putInContext("userLogin", userLogin);
+
+        }
+
+        if (session != null) {
+            session.setAttribute(menuSig, menuWrapper);
+        }
+        return menuWrapper;
+    }
+
+    public void setParameters(Map<String, Object> paramMap) {
+        context.put("parameters", paramMap);
+    }
+
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuWrapperImage.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuWrapperImage.java
similarity index 95%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlMenuWrapperImage.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuWrapperImage.java
index 6346ef4..c41f2ac 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlMenuWrapperImage.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuWrapperImage.java
@@ -1,81 +1,80 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.util.EntityQuery;
-import org.ofbiz.widget.menu.MenuStringRenderer;
-import org.ofbiz.widget.menu.ModelMenuItem;
-import org.xml.sax.SAXException;
-
-/**
- * Widget Library - HTML Menu Wrapper class - makes it easy to do the setup and render of a menu
- */
-public class HtmlMenuWrapperImage extends HtmlMenuWrapper {
-
-    public static final String module = HtmlMenuWrapperImage.class.getName();
-
-    protected HtmlMenuWrapperImage() {}
-
-    public HtmlMenuWrapperImage(String resourceName, String menuName, HttpServletRequest request, HttpServletResponse response)
-            throws IOException, SAXException, ParserConfigurationException {
-        super(resourceName, menuName, request, response);
-    }
-
-    @Override
-    public MenuStringRenderer getMenuRenderer() {
-        return new HtmlMenuRendererImage(request, response);
-    }
-
-    @Override
-    public void init(String resourceName, String menuName, HttpServletRequest request, HttpServletResponse response)
-            throws IOException, SAXException, ParserConfigurationException {
-
-        super.init(resourceName, menuName, request, response);
-        //String pubPt = (String)request.getAttribute("pubPt");
-        //if (Debug.infoOn()) Debug.logInfo("in init, pubPt:" + pubPt, module);
-        Map<String, Object> dummyMap = new HashMap<String, Object>();
-        Delegator delegator = (Delegator)request.getAttribute("delegator");
-        //if (Debug.infoOn()) Debug.logInfo("in init, delegator:" + delegator, module);
-        try {
-            for (ModelMenuItem menuItem : modelMenu.getMenuItemList()) {
-               String contentId = menuItem.getAssociatedContentId(dummyMap);
-               //if (Debug.infoOn()) Debug.logInfo("in init, contentId:" + contentId, module);
-               GenericValue webSitePublishPoint = EntityQuery.use(delegator).from("WebSitePublishPoint").where("contentId", contentId).cache().queryOne();
-               String menuItemName = menuItem.getName();
-               //if (Debug.infoOn()) Debug.logInfo("in init, menuItemName:" + menuItemName, module);
-               //if (Debug.infoOn()) Debug.logInfo("in init, webSitePublishPoint:" + webSitePublishPoint, module);
-               putInContext(menuItemName, "WebSitePublishPoint", webSitePublishPoint);
-            }
-        } catch (GenericEntityException e) {
-            return;
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
+import org.ofbiz.widget.model.ModelMenuItem;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+import org.xml.sax.SAXException;
+
+/**
+ * Widget Library - HTML Menu Wrapper class - makes it easy to do the setup and render of a menu
+ */
+public class HtmlMenuWrapperImage extends HtmlMenuWrapper {
+
+    public static final String module = HtmlMenuWrapperImage.class.getName();
+
+    protected HtmlMenuWrapperImage() {}
+
+    public HtmlMenuWrapperImage(String resourceName, String menuName, HttpServletRequest request, HttpServletResponse response)
+            throws IOException, SAXException, ParserConfigurationException {
+        super(resourceName, menuName, request, response);
+    }
+
+    @Override
+    public MenuStringRenderer getMenuRenderer() {
+        return new HtmlMenuRendererImage(request, response);
+    }
+
+    @Override
+    public void init(String resourceName, String menuName, HttpServletRequest request, HttpServletResponse response)
+            throws IOException, SAXException, ParserConfigurationException {
+
+        super.init(resourceName, menuName, request, response);
+        //String pubPt = (String)request.getAttribute("pubPt");
+        //if (Debug.infoOn()) Debug.logInfo("in init, pubPt:" + pubPt, module);
+        Map<String, Object> dummyMap = new HashMap<String, Object>();
+        Delegator delegator = (Delegator)request.getAttribute("delegator");
+        //if (Debug.infoOn()) Debug.logInfo("in init, delegator:" + delegator, module);
+        try {
+            for (ModelMenuItem menuItem : modelMenu.getMenuItemList()) {
+               String contentId = menuItem.getAssociatedContentId(dummyMap);
+               //if (Debug.infoOn()) Debug.logInfo("in init, contentId:" + contentId, module);
+               GenericValue webSitePublishPoint = EntityQuery.use(delegator).from("WebSitePublishPoint").where("contentId", contentId).cache().queryOne();
+               String menuItemName = menuItem.getName();
+               //if (Debug.infoOn()) Debug.logInfo("in init, menuItemName:" + menuItemName, module);
+               //if (Debug.infoOn()) Debug.logInfo("in init, webSitePublishPoint:" + webSitePublishPoint, module);
+               putInContext(menuItemName, "WebSitePublishPoint", webSitePublishPoint);
+            }
+        } catch (GenericEntityException e) {
+            return;
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlScreenRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlScreenRenderer.java
similarity index 96%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlScreenRenderer.java
index 90c05b1..04a81cb 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlScreenRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlScreenRenderer.java
@@ -1,932 +1,944 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilFormatOut;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.WidgetContentWorker;
-import org.ofbiz.widget.WidgetDataResourceWorker;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.Paginator;
-import org.ofbiz.widget.menu.MenuStringRenderer;
-import org.ofbiz.widget.menu.ModelMenu;
-import org.ofbiz.widget.screen.ModelScreenWidget;
-import org.ofbiz.widget.screen.ModelScreenWidget.*;
-import org.ofbiz.widget.screen.ScreenStringRenderer;
-
-/**
- * Widget Library - HTML Form Renderer implementation
- * @deprecated Use MacroScreenRenderer.
- */
-public class HtmlScreenRenderer extends HtmlWidgetRenderer implements ScreenStringRenderer {
-
-    public static final String module = HtmlScreenRenderer.class.getName();
-    protected int elementId = 999;
-
-    public HtmlScreenRenderer() {}
-
-    protected String getNextElementId() {
-        elementId++;
-        return "hsr" + elementId;
-    }
-
-    public String getRendererName() {
-        return "html";
-    }
-
-    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException {
-        writer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
-        appendWhitespace(writer);
-    }
-
-    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException {
-    }
-
-    public void renderSectionBegin(Appendable writer, Map<String, Object> context, Section section) throws IOException {
-        if (section.isMainSection()) {
-            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        }
-        renderBeginningBoundaryComment(writer, section.isMainSection()?"Screen":"Section Widget", section);
-    }
-
-    public void renderSectionEnd(Appendable writer, Map<String, Object> context, Section section) throws IOException {
-        renderEndingBoundaryComment(writer, section.isMainSection()?"Screen":"Section Widget", section);
-    }
-
-    public void renderContainerBegin(Appendable writer, Map<String, Object> context, Container container) throws IOException {
-        String containerId = container.getId(context);
-        String autoUpdateTarget = container.getAutoUpdateTargetExdr(context);
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        if (UtilValidate.isNotEmpty(autoUpdateTarget) && UtilHttp.isJavaScriptEnabled(request)) {
-            if (UtilValidate.isEmpty(containerId)) {
-                containerId = getNextElementId();
-            }
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-            RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-
-            writer.append("<script type=\"text/javascript\">ajaxUpdateAreaPeriodic('");
-            writer.append(containerId);
-            writer.append("', '");
-            writer.append(rh.makeLink(request, response, autoUpdateTarget));
-            writer.append("', '");
-            writer.append("', '").append(container.getAutoUpdateInterval(context)).append("');</script>");
-            appendWhitespace(writer);
-        }
-        writer.append("<div");
-
-        if (UtilValidate.isNotEmpty(containerId)) {
-            writer.append(" id=\"");
-            writer.append(containerId);
-            writer.append("\"");
-        }
-
-        String style = container.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append(" class=\"");
-            writer.append(style);
-            writer.append("\"");
-        }
-
-        writer.append(">");
-        appendWhitespace(writer);
-    }
-    public void renderContainerEnd(Appendable writer, Map<String, Object> context, Container container) throws IOException {
-        writer.append("</div>");
-        appendWhitespace(writer);
-    }
-
-    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, HorizontalSeparator separator) throws IOException {
-        writer.append("<hr");
-        String className = separator.getStyle(context);
-        if (UtilValidate.isNotEmpty(className)) {
-            writer.append(" class=\"").append(className).append("\"");
-        }
-        String idName = separator.getId(context);
-        if (UtilValidate.isNotEmpty(idName)) {
-            writer.append(" id=\"").append(idName).append("\"");
-        }
-        writer.append("/>");
-        appendWhitespace(writer);
-    }
-
-    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, Screenlet screenlet) throws IOException {
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        boolean javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
-        Menu tabMenu = screenlet.getTabMenu();
-        if (tabMenu != null) {
-            tabMenu.renderWidgetString(writer, context, this);
-        }
-        writer.append("<div class=\"screenlet\"");
-        String id = screenlet.getId(context);
-        if (UtilValidate.isNotEmpty(id)) {
-            writer.append(" id=\"");
-            writer.append(id);
-            writer.append("\"");
-        }
-        writer.append(">");
-        appendWhitespace(writer);
-
-        String title = screenlet.getTitle(context);
-        Menu navMenu = screenlet.getNavigationMenu();
-        Form navForm = screenlet.getNavigationForm();
-        String collapsibleAreaId = null;
-        if (UtilValidate.isNotEmpty(title) || navMenu != null || navForm != null || screenlet.collapsible()) {
-            writer.append("<div class=\"screenlet-title-bar\">");
-            appendWhitespace(writer);
-            writer.append("<ul>");
-            appendWhitespace(writer);
-            if (UtilValidate.isNotEmpty(title)) {
-                writer.append("<li class=\"h3\">");
-                writer.append(title);
-                writer.append("</li>");
-                appendWhitespace(writer);
-            }
-            if (screenlet.collapsible()) {
-                collapsibleAreaId = this.getNextElementId();
-                String expandToolTip = null;
-                String collapseToolTip = null;
-                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-                Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
-                Map<String, Object> requestParameters = new HashMap<String, Object>(paramMap);
-                if (uiLabelMap != null) {
-                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
-                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
-                }
-                writer.append("<li class=\"");
-                if (collapsed) {
-                    writer.append("collapsed\"><a ");
-                    if (javaScriptEnabled) {
-                        writer.append("onclick=\"javascript:toggleScreenlet(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
-                    } else {
-                        requestParameters.put(screenlet.getPreferenceKey(context) + "_collapsed", "false");
-                        String queryString = UtilHttp.urlEncodeArgs(requestParameters);
-                        writer.append("href=\"").append(request.getRequestURI()).append("?").append(queryString).append("\"");
-                    }
-                    if (UtilValidate.isNotEmpty(expandToolTip)) {
-                        writer.append(" title=\"").append(expandToolTip).append("\"");
-                    }
-                } else {
-                    writer.append("expanded\"><a ");
-                    if (javaScriptEnabled) {
-                        writer.append("onclick=\"javascript:toggleScreenlet(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
-                    } else {
-                        requestParameters.put(screenlet.getPreferenceKey(context) + "_collapsed", "true");
-                        String queryString = UtilHttp.urlEncodeArgs(requestParameters);
-                        writer.append("href=\"").append(request.getRequestURI()).append("?").append(queryString).append("\"");
-                    }
-                    if (UtilValidate.isNotEmpty(collapseToolTip)) {
-                        writer.append(" title=\"").append(collapseToolTip).append("\"");
-                    }
-                }
-                writer.append(">&nbsp</a></li>");
-                appendWhitespace(writer);
-            }
-            if (!collapsed) {
-                if (navMenu != null) {
-                    MenuStringRenderer savedRenderer = (MenuStringRenderer) context.get("menuStringRenderer");
-                    MenuStringRenderer renderer = new ScreenletMenuRenderer(request, response);
-                    context.put("menuStringRenderer", renderer);
-                    navMenu.renderWidgetString(writer, context, this);
-                    context.put("menuStringRenderer", savedRenderer);
-                } else if (navForm != null) {
-                    renderScreenletPaginateMenu(writer, context, navForm);
-                }
-            }
-            writer.append("</ul>");
-            appendWhitespace(writer);
-            writer.append("<br class=\"clear\" />");
-            appendWhitespace(writer);
-            writer.append("</div>");
-            appendWhitespace(writer);
-            writer.append("<div");
-            if (UtilValidate.isNotEmpty(collapsibleAreaId)) {
-                writer.append(" id=\"").append(collapsibleAreaId).append("\"");
-                if (collapsed) {
-                    writer.append(" style=\"display: none;\"");
-                }
-            }
-            if (screenlet.padded()) {
-                writer.append(" class=\"screenlet-body\"");
-            }
-            writer.append(">");
-            appendWhitespace(writer);
-        }
-    }
-
-    private int getActualPageSize(Map<String, Object> context) {
-        Integer value = (Integer) context.get("actualPageSize");
-        return value != null ? value.intValue() : (getHighIndex(context) - getLowIndex(context));
-    }
-
-    private int getHighIndex(Map<String, Object> context) {
-        Integer value = (Integer) context.get("highIndex");
-        return value != null ? value.intValue() : 0;
-    }
-
-    private int getListSize(Map<String, Object> context) {
-        Integer value = (Integer) context.get("listSize");
-        return value != null ? value.intValue() : 0;
-    }
-
-    private int getLowIndex(Map<String, Object> context) {
-        Integer value = (Integer) context.get("lowIndex");
-        return value != null ? value.intValue() : 0;
-    }
-
-    protected void renderScreenletPaginateMenu(Appendable writer, Map<String, Object> context, Form form) throws IOException {
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        ModelForm modelForm = form.getModelForm(context);
-        modelForm.runFormActions(context);
-        Paginator.preparePager(modelForm, context);
-        String targetService = modelForm.getPaginateTarget(context);
-        if (targetService == null) {
-            targetService = "${targetService}";
-        }
-
-        // get the parametrized pagination index and size fields
-        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
-        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
-        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
-
-        int viewIndex = Paginator.getViewIndex(modelForm, context);
-        int viewSize = Paginator.getViewSize(modelForm, context);
-        int listSize = getListSize(context);
-
-        int lowIndex = getLowIndex(context);
-        int highIndex = getHighIndex(context);
-        int actualPageSize = getActualPageSize(context);
-
-        // if this is all there seems to be (if listSize < 0, then size is unknown)
-        if (actualPageSize >= listSize && listSize >= 0) return;
-
-        // needed for the "Page" and "rows" labels
-        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
-        String ofLabel = "";
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        } else {
-            ofLabel = uiLabelMap.get("CommonOf");
-            ofLabel = ofLabel.toLowerCase();
-        }
-
-        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
-        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber)) viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
-        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber)) viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;
-
-        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-
-        Map<String, Object> inputFields = UtilGenerics.toMap(context.get("requestParameters"));
-        // strip out any multi form fields if the form is of type multi
-        if (modelForm.getType().equals("multi")) {
-            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
-        }
-        String queryString = UtilHttp.urlEncodeArgs(inputFields);
-        // strip legacy viewIndex/viewSize params from the query string
-        queryString = UtilHttp.stripViewParamsFromQueryString(queryString, "" + paginatorNumber);
-        // strip parametrized index/size params from the query string
-        HashSet<String> paramNames = new HashSet<String>();
-        paramNames.add(viewIndexParam);
-        paramNames.add(viewSizeParam);
-        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);
-
-        String anchor = "";
-        String paginateAnchor = modelForm.getPaginateTargetAnchor();
-        if (paginateAnchor != null) anchor = "#" + paginateAnchor;
-
-        // preparing the link text, so that later in the code we can reuse this and just add the viewIndex
-        StringBuilder prepLinkTextBuffer = new StringBuilder(targetService);
-        if (prepLinkTextBuffer.indexOf("?") < 0) {
-            prepLinkTextBuffer.append("?");
-        } else if (prepLinkTextBuffer.indexOf("?", prepLinkTextBuffer.length() - 1) > 0) {
-            prepLinkTextBuffer.append("&amp;");
-        }
-        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
-            prepLinkTextBuffer.append(queryString).append("&amp;");
-        }
-        prepLinkTextBuffer.append(viewSizeParam).append("=").append(viewSize).append("&amp;").append(viewIndexParam).append("=");
-        String prepLinkText = prepLinkTextBuffer.toString();
-
-        String linkText;
-
-        appendWhitespace(writer);
-        // The current screenlet title bar navigation syling requires rendering
-        // these links in reverse order
-        // Last button
-        writer.append("<li class=\"").append(modelForm.getPaginateLastStyle());
-        if (highIndex < listSize) {
-            writer.append("\"><a href=\"");
-            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
-            linkText = prepLinkText + lastIndex + anchor;
-            // - make the link
-            writer.append(rh.makeLink(request, response, linkText));
-            writer.append("\">").append(modelForm.getPaginateLastLabel(context)).append("</a>");
-        } else {
-            // disabled button
-            writer.append(" disabled\">").append(modelForm.getPaginateLastLabel(context));
-        }
-        writer.append("</li>");
-        appendWhitespace(writer);
-        // Next button
-        writer.append("<li class=\"").append(modelForm.getPaginateNextStyle());
-        if (highIndex < listSize) {
-            writer.append("\"><a href=\"");
-            linkText = prepLinkText + (viewIndex + 1) + anchor;
-            // - make the link
-            writer.append(rh.makeLink(request, response, linkText));
-            writer.append("\">").append(modelForm.getPaginateNextLabel(context)).append("</a>");
-        } else {
-            // disabled button
-            writer.append(" disabled\">").append(modelForm.getPaginateNextLabel(context));
-        }
-        writer.append("</li>");
-        appendWhitespace(writer);
-        if (listSize > 0) {
-            writer.append("<li>");
-            writer.append(Integer.toString(lowIndex + 1)).append(" - ").append(Integer.toString(lowIndex + actualPageSize)).append(" ").append(ofLabel).append(" ").append(Integer.toString(listSize));
-            writer.append("</li>");
-            appendWhitespace(writer);
-        }
-        // Previous button
-        writer.append("<li class=\"nav-previous");
-        if (viewIndex > 0) {
-            writer.append("\"><a href=\"");
-            linkText = prepLinkText + (viewIndex - 1) + anchor;
-            // - make the link
-            writer.append(rh.makeLink(request, response, linkText));
-            writer.append("\">").append(modelForm.getPaginatePreviousLabel(context)).append("</a>");
-        } else {
-            // disabled button
-            writer.append(" disabled\">").append(modelForm.getPaginatePreviousLabel(context));
-        }
-        writer.append("</li>");
-        appendWhitespace(writer);
-        // First button
-        writer.append("<li class=\"nav-first");
-        if (viewIndex > 0) {
-            writer.append("\"><a href=\"");
-            linkText = prepLinkText + 0 + anchor;
-            writer.append(rh.makeLink(request, response, linkText));
-            writer.append("\">").append(modelForm.getPaginateFirstLabel(context)).append("</a>");
-        } else {
-            writer.append(" disabled\">").append(modelForm.getPaginateFirstLabel(context));
-        }
-        writer.append("</li>");
-        appendWhitespace(writer);
-    }
-
-    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, Screenlet screenlet) throws GeneralException, IOException {
-        if (subWidget.equals(screenlet.getNavigationForm())) {
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            if (request != null && response != null) {
-                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
-                globalCtx.put("NO_PAGINATOR", true);
-                FormStringRenderer savedRenderer = (FormStringRenderer) context.get("formStringRenderer");
-                HtmlFormRenderer renderer = new HtmlFormRenderer(request, response);
-                renderer.setRenderPagination(false);
-                context.put("formStringRenderer", renderer);
-                subWidget.renderWidgetString(writer, context, this);
-                context.put("formStringRenderer", savedRenderer);
-            }
-        } else {
-            subWidget.renderWidgetString(writer, context, this);
-        }
-    }
-
-    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, Screenlet screenlet) throws IOException {
-        writer.append("</div>");
-        appendWhitespace(writer);
-        writer.append("</div>");
-        appendWhitespace(writer);
-    }
-
-    public static class ScreenletMenuRenderer extends HtmlMenuRenderer {
-        public ScreenletMenuRenderer(HttpServletRequest request, HttpServletResponse response) {
-            super(request, response);
-        }
-        @Override
-        public void renderMenuOpen(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) {}
-        @Override
-        public void renderMenuClose(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) {}
-    }
-
-    public void renderLabel(Appendable writer, Map<String, Object> context, Label label) throws IOException {
-        String labelText = label.getText(context);
-        if (UtilValidate.isEmpty(labelText)) {
-            // nothing to render
-            return;
-        }
-        // open tag
-        String style = label.getStyle(context);
-        String id = label.getId(context);
-        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id)) {
-               writer.append("<span");
-
-            if (UtilValidate.isNotEmpty(id)) {
-                writer.append(" id=\"");
-                writer.append(id);
-                writer.append("\"");
-            }
-            if (UtilValidate.isNotEmpty(style)) {
-                writer.append(" class=\"");
-                writer.append(style);
-                writer.append("\"");
-            }
-            writer.append(">");
-
-            // the text
-            writer.append(labelText);
-
-            // close tag
-               writer.append("</span>");
-
-        } else {
-            writer.append(labelText);
-        }
-
-        appendWhitespace(writer);
-    }
-
-    public void renderLink(Appendable writer, Map<String, Object> context, ScreenLink link) throws IOException {
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-
-        String targetWindow = link.getTargetWindow(context);
-        String target = link.getTarget(context);
-
-        String uniqueItemName = link.getModelScreen().getName() + "_LF_" + UtilMisc.<String>addToBigDecimalInMap(context, "screenUniqueItemIndex", BigDecimal.ONE);
-
-        String linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request);
-        if ("hidden-form".equals(linkType)) {
-            writer.append("<form method=\"post\"");
-            writer.append(" action=\"");
-            // note that this passes null for the parameterList on purpose so they won't be put into the URL
-            WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), null, link.getPrefix(context),
-                    link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
-            writer.append("\"");
-
-            if (UtilValidate.isNotEmpty(targetWindow)) {
-                writer.append(" target=\"");
-                writer.append(targetWindow);
-                writer.append("\"");
-            }
-
-            writer.append(" onsubmit=\"javascript:submitFormDisableSubmits(this)\"");
-
-            writer.append(" name=\"");
-            writer.append(uniqueItemName);
-            writer.append("\">");
-
-            for (Map.Entry<String, String> parameter: link.getParameterMap(context).entrySet()) {
-                writer.append("<input name=\"");
-                writer.append(parameter.getKey());
-                writer.append("\" value=\"");
-                writer.append(parameter.getValue());
-                writer.append("\" type=\"hidden\"/>");
-            }
-
-            writer.append("</form>");
-        }
-
-        writer.append("<a");
-        String id = link.getId(context);
-        if (UtilValidate.isNotEmpty(id)) {
-            writer.append(" id=\"");
-            writer.append(id);
-            writer.append("\"");
-        }
-        String style = link.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append(" class=\"");
-            writer.append(style);
-            writer.append("\"");
-        }
-        String name = link.getName(context);
-        if (UtilValidate.isNotEmpty(name)) {
-            writer.append(" name=\"");
-            writer.append(name);
-            writer.append("\"");
-        }
-        if (UtilValidate.isNotEmpty(targetWindow)) {
-            writer.append(" target=\"");
-            writer.append(targetWindow);
-            writer.append("\"");
-        }
-        if (UtilValidate.isNotEmpty(target)) {
-            writer.append(" href=\"");
-            if ("hidden-form".equals(linkType)) {
-                writer.append("javascript:document.");
-                writer.append(uniqueItemName);
-                writer.append(".submit()");
-            } else {
-                WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
-                        link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
-            }
-            writer.append("\"");
-        }
-        writer.append(">");
-
-        // the text
-        ScreenImage img = link.getImage();
-        if (img == null) {
-            writer.append(link.getText(context));
-        } else {
-            renderImage(writer, context, img);
-        }
-
-        // close tag
-        writer.append("</a>");
-
-        appendWhitespace(writer);
-    }
-
-    public void renderImage(Appendable writer, Map<String, Object> context, ScreenImage image) throws IOException {
-        // open tag
-        String src = image.getSrc(context);
-        if (UtilValidate.isEmpty(src)) {
-            return;
-        }
-        writer.append("<img ");
-        String id = image.getId(context);
-        if (UtilValidate.isNotEmpty(id)) {
-            writer.append(" id=\"");
-            writer.append(id);
-            writer.append("\"");
-        }
-        String style = image.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append(" class=\"");
-            writer.append(style);
-            writer.append("\"");
-        }
-        String wid = image.getWidth(context);
-        if (UtilValidate.isNotEmpty(wid)) {
-            writer.append(" width=\"");
-            writer.append(wid);
-            writer.append("\"");
-        }
-        String hgt = image.getHeight(context);
-        if (UtilValidate.isNotEmpty(hgt)) {
-            writer.append(" height=\"");
-            writer.append(hgt);
-            writer.append("\"");
-        }
-        String border = image.getBorder(context);
-        if (UtilValidate.isNotEmpty(border)) {
-            writer.append(" border=\"");
-            writer.append(border);
-            writer.append("\"");
-        }
-        String alt = image.getAlt(context);
-        if (UtilValidate.isNotEmpty(alt)) {
-            writer.append(" alt=\"");
-            writer.append(alt);
-            writer.append("\"");
-        }
-
-        writer.append(" src=\"");
-        String urlMode = image.getUrlMode();
-        boolean fullPath = false;
-        boolean secure = false;
-        boolean encode = false;
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
-            if (request != null && response != null) {
-                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                String urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
-                writer.append(urlString);
-            } else {
-                writer.append(src);
-            }
-        } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
-            if (request != null && response != null) {
-                StringBuilder newURL = new StringBuilder();
-                ContentUrlTag.appendContentPrefix(request, newURL);
-                newURL.append(src);
-                writer.append(newURL.toString());
-            }
-        } else {
-            writer.append(src);
-        }
-
-        writer.append("\"/>");
-
-        appendWhitespace(writer);
-    }
-
-    public void renderContentBegin(Appendable writer, Map<String, Object> context, Content content) throws IOException {
-        String editRequest = content.getEditRequest(context);
-        String editContainerStyle = content.getEditContainerStyle(context);
-        String enableEditName = content.getEnableEditName(context);
-        String enableEditValue = (String)context.get(enableEditName);
-
-        if (Debug.verboseOn()) Debug.logVerbose("directEditRequest:" + editRequest, module);
-
-        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
-            writer.append("<div");
-            writer.append(" class=\"").append(editContainerStyle).append("\"> ");
-            appendWhitespace(writer);
-        }
-    }
-
-    public void renderContentBody(Appendable writer, Map<String, Object> context, Content content) throws IOException {
-        Locale locale = UtilMisc.ensureLocale(context.get("locale"));
-        //Boolean nullThruDatesOnly = Boolean.valueOf(false);
-        String mimeTypeId = "text/html";
-        String expandedContentId = content.getContentId(context);
-        String expandedDataResourceId = content.getDataResourceId(context);
-        String renderedContent = null;
-        LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
-        Delegator delegator = (Delegator) context.get("delegator");
-
-        // make a new map for content rendering; so our current map does not get clobbered
-        Map<String, Object> contentContext = new HashMap<String, Object>();
-        contentContext.putAll(context);
-        String dataResourceId = (String)contentContext.get("dataResourceId");
-        if (Debug.verboseOn()) Debug.logVerbose("expandedContentId:" + expandedContentId, module);
-
-        try {
-            if (UtilValidate.isNotEmpty(dataResourceId)) {
-                if (WidgetDataResourceWorker.dataresourceWorker != null) {
-                    renderedContent = WidgetDataResourceWorker.dataresourceWorker.renderDataResourceAsTextExt(delegator, dataResourceId, contentContext, locale, mimeTypeId, false);
-                } else {
-                    Debug.logError("Not rendering content, WidgetDataResourceWorker.dataresourceWorker not found.", module);
-                }
-            } else if (UtilValidate.isNotEmpty(expandedContentId)) {
-                if (WidgetContentWorker.contentWorker != null) {
-                    renderedContent = WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, expandedContentId, contentContext, locale, mimeTypeId, true);
-                } else {
-                    Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
-                }
-            } else if (UtilValidate.isNotEmpty(expandedDataResourceId)) {
-                if (WidgetDataResourceWorker.dataresourceWorker != null) {
-                    renderedContent = WidgetDataResourceWorker.dataresourceWorker.renderDataResourceAsTextExt(delegator, expandedDataResourceId, contentContext, locale, mimeTypeId, false);
-                } else {
-                    Debug.logError("Not rendering content, WidgetDataResourceWorker.dataresourceWorker not found.", module);
-                }
-            }
-            if (UtilValidate.isEmpty(renderedContent)) {
-                String editRequest = content.getEditRequest(context);
-                if (UtilValidate.isNotEmpty(editRequest)) {
-                    if (WidgetContentWorker.contentWorker != null) {
-                        WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, "NOCONTENTFOUND", writer, contentContext, locale, mimeTypeId, true);
-                    } else {
-                        Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
-                    }
-                }
-            } else {
-                if (content.xmlEscape()) {
-                    renderedContent = UtilFormatOut.encodeXmlValue(renderedContent);
-                }
-
-                writer.append(renderedContent);
-            }
-
-        } catch (GeneralException e) {
-            String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e.toString();
-            Debug.logError(e, errMsg, module);
-            //throw new RuntimeException(errMsg);
-        } catch (IOException e2) {
-            String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e2.toString();
-            Debug.logError(e2, errMsg, module);
-            //throw new RuntimeException(errMsg);
-        }
-    }
-
-    public void renderContentEnd(Appendable writer, Map<String, Object> context, Content content) throws IOException {
-
-                //Debug.logInfo("renderContentEnd, context:" + context, module);
-        String expandedContentId = content.getContentId(context);
-        String editMode = "Edit";
-        String editRequest = content.getEditRequest(context);
-        String editContainerStyle = content.getEditContainerStyle(context);
-        String enableEditName = content.getEnableEditName(context);
-        String enableEditValue = (String)context.get(enableEditName);
-        if (editRequest != null && editRequest.toUpperCase().indexOf("IMAGE") > 0) {
-            editMode += " Image";
-        }
-        //String editRequestWithParams = editRequest + "?contentId=${currentValue.contentId}&drDataResourceId=${currentValue.drDataResourceId}&directEditRequest=${directEditRequest}&indirectEditRequest=${indirectEditRequest}&caContentIdTo=${currentValue.caContentIdTo}&caFromDate=${currentValue.caFromDate}&caContentAssocTypeId=${currentValue.caContentAssocTypeId}";
-
-        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-            if (request != null && response != null) {
-                if (editRequest.indexOf("?") < 0)  editRequest += "?";
-                else editRequest += "&amp;";
-                editRequest += "contentId=" + expandedContentId;
-                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                writer.append("<a href=\"").append(rh.makeLink(request, response, editRequest, false, false, false)).append("\">").append(editMode).append("</a>");
-            }
-            if (UtilValidate.isNotEmpty(editContainerStyle)) {
-                writer.append("</div>");
-            }
-            appendWhitespace(writer);
-        }
-    }
-
-    public void renderContentFrame(Appendable writer, Map<String, Object> context, Content content) throws IOException {
-
-
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        if (request != null && response != null) {
-            ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-            RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-            String dataResourceId = content.getDataResourceId(context);
-//          String urlString = "/content/control/ViewSimpleContent?dataResourceId=" + dataResourceId;
-            String urlString = "/ViewSimpleContent?dataResourceId=" + dataResourceId;
-
-            writer.append("<iframe src=\"").append(rh.makeLink(request, response, urlString, true, false, false)).append("\" ");
-            writer.append(" width=\"").append(content.getWidth()).append("\"");
-            writer.append(" height=\"").append(content.getHeight()).append("\"");
-            String border = content.getBorder();
-            if (UtilValidate.isNotEmpty(border)) {
-                writer.append(" border=\"").append(border).append("\"");
-            }
-            writer.append(" />");
-        }
-
-    }
-
-    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, SubContent content) throws IOException {
-
-        String editRequest = content.getEditRequest(context);
-        String editContainerStyle = content.getEditContainerStyle(context);
-        String enableEditName = content.getEnableEditName(context);
-        String enableEditValue = (String)context.get(enableEditName);
-        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
-            writer.append("<div");
-            writer.append(" class=\"").append(editContainerStyle).append("\"> ");
-
-            appendWhitespace(writer);
-        }
-    }
-
-    public void renderSubContentBody(Appendable writer, Map<String, Object> context, SubContent content) throws IOException {
-            Locale locale = Locale.getDefault();
-            String mimeTypeId = "text/html";
-            String expandedContentId = content.getContentId(context);
-            String expandedMapKey = content.getMapKey(context);
-            String renderedContent = null;
-            LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
-            Delegator delegator = (Delegator) context.get("delegator");
-
-            // create a new map for the content rendering; so our current context does not get overwritten!
-            Map<String, Object> contentContext = new HashMap<String, Object>();
-            contentContext.putAll(context);
-
-            try {
-                if (WidgetContentWorker.contentWorker != null) {
-                    renderedContent = WidgetContentWorker.contentWorker.renderSubContentAsTextExt(dispatcher, delegator, expandedContentId, expandedMapKey, contentContext, locale, mimeTypeId, true);
-                    //Debug.logInfo("renderedContent=" + renderedContent, module);
-                } else {
-                    Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
-                }
-                if (UtilValidate.isEmpty(renderedContent)) {
-                    String editRequest = content.getEditRequest(context);
-                    if (UtilValidate.isNotEmpty(editRequest)) {
-                        if (WidgetContentWorker.contentWorker != null) {
-                            WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, "NOCONTENTFOUND", writer, contentContext, locale, mimeTypeId, true);
-                        } else {
-                            Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
-                        }
-                    }
-                } else {
-                    if (content.xmlEscape()) {
-                        renderedContent = UtilFormatOut.encodeXmlValue(renderedContent);
-                    }
-
-                    writer.append(renderedContent);
-                }
-
-            } catch (GeneralException e) {
-                String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e.toString();
-                Debug.logError(e, errMsg, module);
-                //throw new RuntimeException(errMsg);
-            } catch (IOException e2) {
-                String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e2.toString();
-                Debug.logError(e2, errMsg, module);
-                //throw new RuntimeException(errMsg);
-            }
-    }
-
-    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, SubContent content) throws IOException {
-
-        String editMode = "Edit";
-        String editRequest = content.getEditRequest(context);
-        String editContainerStyle = content.getEditContainerStyle(context);
-        String enableEditName = content.getEnableEditName(context);
-        String enableEditValue = (String)context.get(enableEditName);
-        String expandedContentId = content.getContentId(context);
-        String expandedMapKey = content.getMapKey(context);
-        if (editRequest != null && editRequest.toUpperCase().indexOf("IMAGE") > 0) {
-            editMode += " Image";
-        }
-        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-            if (request != null && response != null) {
-                if (editRequest.indexOf("?") < 0)  editRequest += "?";
-                else editRequest += "&amp;";
-                editRequest += "contentId=" + expandedContentId;
-                if (UtilValidate.isNotEmpty(expandedMapKey)) {
-                    editRequest += "&amp;mapKey=" + expandedMapKey;
-                }
-                //HttpSession session = request.getSession();
-                //GenericValue userLogin = (GenericValue)session.getAttribute("userLogin");
-                /* don't know why this is here. might come to me later. -amb
-                Delegator delegator = (Delegator)request.getAttribute("delegator");
-                String contentIdTo = content.getContentId(context);
-                String mapKey = content.getAssocName(context);
-                GenericValue view = null;
-                try {
-                    view = ContentWorker.getSubContentCache(delegator, contentIdTo, mapKey, userLogin, null, UtilDateTime.nowTimestamp(), Boolean.valueOf(false), null);
-                } catch (GenericEntityException e) {
-                    throw new IOException("Originally a GenericEntityException. " + e.getMessage());
-                }
-                */
-                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                writer.append("<a href=\"").append(rh.makeLink(request, response, editRequest, false, false, false)).append("\">").append(editMode).append("</a>");
-            }
-            if (UtilValidate.isNotEmpty(editContainerStyle)) {
-                writer.append("</div>");
-            }
-            appendWhitespace(writer);
-        }
-    }
-
-    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, PortalPage portalPage) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, PortalPage portalPage) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-
-    @Override
-    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ColumnContainer columnContainer) throws IOException {
-        // TODO: not implemented
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.webapp.control.RequestHandler;
+import org.ofbiz.webapp.taglib.ContentUrlTag;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.content.WidgetContentWorker;
+import org.ofbiz.widget.content.WidgetDataResourceWorker;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelMenu;
+import org.ofbiz.widget.model.ModelScreenWidget;
+import org.ofbiz.widget.model.ModelScreenWidget.ColumnContainer;
+import org.ofbiz.widget.model.ModelScreenWidget.Container;
+import org.ofbiz.widget.model.ModelScreenWidget.Content;
+import org.ofbiz.widget.model.ModelScreenWidget.Form;
+import org.ofbiz.widget.model.ModelScreenWidget.HorizontalSeparator;
+import org.ofbiz.widget.model.ModelScreenWidget.Label;
+import org.ofbiz.widget.model.ModelScreenWidget.Menu;
+import org.ofbiz.widget.model.ModelScreenWidget.PortalPage;
+import org.ofbiz.widget.model.ModelScreenWidget.ScreenImage;
+import org.ofbiz.widget.model.ModelScreenWidget.ScreenLink;
+import org.ofbiz.widget.model.ModelScreenWidget.Screenlet;
+import org.ofbiz.widget.model.ModelScreenWidget.Section;
+import org.ofbiz.widget.model.ModelScreenWidget.SubContent;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+import org.ofbiz.widget.renderer.Paginator;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+
+/**
+ * Widget Library - HTML Form Renderer implementation
+ * @deprecated Use MacroScreenRenderer.
+ */
+public class HtmlScreenRenderer extends HtmlWidgetRenderer implements ScreenStringRenderer {
+
+    public static final String module = HtmlScreenRenderer.class.getName();
+    protected int elementId = 999;
+
+    public HtmlScreenRenderer() {}
+
+    protected String getNextElementId() {
+        elementId++;
+        return "hsr" + elementId;
+    }
+
+    public String getRendererName() {
+        return "html";
+    }
+
+    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException {
+        writer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
+        appendWhitespace(writer);
+    }
+
+    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException {
+    }
+
+    public void renderSectionBegin(Appendable writer, Map<String, Object> context, Section section) throws IOException {
+        if (section.isMainSection()) {
+            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+        }
+        renderBeginningBoundaryComment(writer, section.isMainSection()?"Screen":"Section Widget", section);
+    }
+
+    public void renderSectionEnd(Appendable writer, Map<String, Object> context, Section section) throws IOException {
+        renderEndingBoundaryComment(writer, section.isMainSection()?"Screen":"Section Widget", section);
+    }
+
+    public void renderContainerBegin(Appendable writer, Map<String, Object> context, Container container) throws IOException {
+        String containerId = container.getId(context);
+        String autoUpdateTarget = container.getAutoUpdateTargetExdr(context);
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        if (UtilValidate.isNotEmpty(autoUpdateTarget) && UtilHttp.isJavaScriptEnabled(request)) {
+            if (UtilValidate.isEmpty(containerId)) {
+                containerId = getNextElementId();
+            }
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+            RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+
+            writer.append("<script type=\"text/javascript\">ajaxUpdateAreaPeriodic('");
+            writer.append(containerId);
+            writer.append("', '");
+            writer.append(rh.makeLink(request, response, autoUpdateTarget));
+            writer.append("', '");
+            writer.append("', '").append(container.getAutoUpdateInterval(context)).append("');</script>");
+            appendWhitespace(writer);
+        }
+        writer.append("<div");
+
+        if (UtilValidate.isNotEmpty(containerId)) {
+            writer.append(" id=\"");
+            writer.append(containerId);
+            writer.append("\"");
+        }
+
+        String style = container.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append(" class=\"");
+            writer.append(style);
+            writer.append("\"");
+        }
+
+        writer.append(">");
+        appendWhitespace(writer);
+    }
+    public void renderContainerEnd(Appendable writer, Map<String, Object> context, Container container) throws IOException {
+        writer.append("</div>");
+        appendWhitespace(writer);
+    }
+
+    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, HorizontalSeparator separator) throws IOException {
+        writer.append("<hr");
+        String className = separator.getStyle(context);
+        if (UtilValidate.isNotEmpty(className)) {
+            writer.append(" class=\"").append(className).append("\"");
+        }
+        String idName = separator.getId(context);
+        if (UtilValidate.isNotEmpty(idName)) {
+            writer.append(" id=\"").append(idName).append("\"");
+        }
+        writer.append("/>");
+        appendWhitespace(writer);
+    }
+
+    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, Screenlet screenlet) throws IOException {
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        boolean javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
+        Menu tabMenu = screenlet.getTabMenu();
+        if (tabMenu != null) {
+            tabMenu.renderWidgetString(writer, context, this);
+        }
+        writer.append("<div class=\"screenlet\"");
+        String id = screenlet.getId(context);
+        if (UtilValidate.isNotEmpty(id)) {
+            writer.append(" id=\"");
+            writer.append(id);
+            writer.append("\"");
+        }
+        writer.append(">");
+        appendWhitespace(writer);
+
+        String title = screenlet.getTitle(context);
+        Menu navMenu = screenlet.getNavigationMenu();
+        Form navForm = screenlet.getNavigationForm();
+        String collapsibleAreaId = null;
+        if (UtilValidate.isNotEmpty(title) || navMenu != null || navForm != null || screenlet.collapsible()) {
+            writer.append("<div class=\"screenlet-title-bar\">");
+            appendWhitespace(writer);
+            writer.append("<ul>");
+            appendWhitespace(writer);
+            if (UtilValidate.isNotEmpty(title)) {
+                writer.append("<li class=\"h3\">");
+                writer.append(title);
+                writer.append("</li>");
+                appendWhitespace(writer);
+            }
+            if (screenlet.collapsible()) {
+                collapsibleAreaId = this.getNextElementId();
+                String expandToolTip = null;
+                String collapseToolTip = null;
+                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+                Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
+                Map<String, Object> requestParameters = new HashMap<String, Object>(paramMap);
+                if (uiLabelMap != null) {
+                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
+                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
+                }
+                writer.append("<li class=\"");
+                if (collapsed) {
+                    writer.append("collapsed\"><a ");
+                    if (javaScriptEnabled) {
+                        writer.append("onclick=\"javascript:toggleScreenlet(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
+                    } else {
+                        requestParameters.put(screenlet.getPreferenceKey(context) + "_collapsed", "false");
+                        String queryString = UtilHttp.urlEncodeArgs(requestParameters);
+                        writer.append("href=\"").append(request.getRequestURI()).append("?").append(queryString).append("\"");
+                    }
+                    if (UtilValidate.isNotEmpty(expandToolTip)) {
+                        writer.append(" title=\"").append(expandToolTip).append("\"");
+                    }
+                } else {
+                    writer.append("expanded\"><a ");
+                    if (javaScriptEnabled) {
+                        writer.append("onclick=\"javascript:toggleScreenlet(this, '").append(collapsibleAreaId).append("', '").append(expandToolTip).append("', '").append(collapseToolTip).append("');\"");
+                    } else {
+                        requestParameters.put(screenlet.getPreferenceKey(context) + "_collapsed", "true");
+                        String queryString = UtilHttp.urlEncodeArgs(requestParameters);
+                        writer.append("href=\"").append(request.getRequestURI()).append("?").append(queryString).append("\"");
+                    }
+                    if (UtilValidate.isNotEmpty(collapseToolTip)) {
+                        writer.append(" title=\"").append(collapseToolTip).append("\"");
+                    }
+                }
+                writer.append(">&nbsp</a></li>");
+                appendWhitespace(writer);
+            }
+            if (!collapsed) {
+                if (navMenu != null) {
+                    MenuStringRenderer savedRenderer = (MenuStringRenderer) context.get("menuStringRenderer");
+                    MenuStringRenderer renderer = new ScreenletMenuRenderer(request, response);
+                    context.put("menuStringRenderer", renderer);
+                    navMenu.renderWidgetString(writer, context, this);
+                    context.put("menuStringRenderer", savedRenderer);
+                } else if (navForm != null) {
+                    renderScreenletPaginateMenu(writer, context, navForm);
+                }
+            }
+            writer.append("</ul>");
+            appendWhitespace(writer);
+            writer.append("<br class=\"clear\" />");
+            appendWhitespace(writer);
+            writer.append("</div>");
+            appendWhitespace(writer);
+            writer.append("<div");
+            if (UtilValidate.isNotEmpty(collapsibleAreaId)) {
+                writer.append(" id=\"").append(collapsibleAreaId).append("\"");
+                if (collapsed) {
+                    writer.append(" style=\"display: none;\"");
+                }
+            }
+            if (screenlet.padded()) {
+                writer.append(" class=\"screenlet-body\"");
+            }
+            writer.append(">");
+            appendWhitespace(writer);
+        }
+    }
+
+    private int getActualPageSize(Map<String, Object> context) {
+        Integer value = (Integer) context.get("actualPageSize");
+        return value != null ? value.intValue() : (getHighIndex(context) - getLowIndex(context));
+    }
+
+    private int getHighIndex(Map<String, Object> context) {
+        Integer value = (Integer) context.get("highIndex");
+        return value != null ? value.intValue() : 0;
+    }
+
+    private int getListSize(Map<String, Object> context) {
+        Integer value = (Integer) context.get("listSize");
+        return value != null ? value.intValue() : 0;
+    }
+
+    private int getLowIndex(Map<String, Object> context) {
+        Integer value = (Integer) context.get("lowIndex");
+        return value != null ? value.intValue() : 0;
+    }
+
+    protected void renderScreenletPaginateMenu(Appendable writer, Map<String, Object> context, Form form) throws IOException {
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        ModelForm modelForm = form.getModelForm(context);
+        modelForm.runFormActions(context);
+        Paginator.preparePager(modelForm, context);
+        String targetService = modelForm.getPaginateTarget(context);
+        if (targetService == null) {
+            targetService = "${targetService}";
+        }
+
+        // get the parametrized pagination index and size fields
+        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
+        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
+        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
+
+        int viewIndex = Paginator.getViewIndex(modelForm, context);
+        int viewSize = Paginator.getViewSize(modelForm, context);
+        int listSize = getListSize(context);
+
+        int lowIndex = getLowIndex(context);
+        int highIndex = getHighIndex(context);
+        int actualPageSize = getActualPageSize(context);
+
+        // if this is all there seems to be (if listSize < 0, then size is unknown)
+        if (actualPageSize >= listSize && listSize >= 0) return;
+
+        // needed for the "Page" and "rows" labels
+        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
+        String ofLabel = "";
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        } else {
+            ofLabel = uiLabelMap.get("CommonOf");
+            ofLabel = ofLabel.toLowerCase();
+        }
+
+        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
+        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber)) viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
+        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber)) viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;
+
+        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+
+        Map<String, Object> inputFields = UtilGenerics.toMap(context.get("requestParameters"));
+        // strip out any multi form fields if the form is of type multi
+        if (modelForm.getType().equals("multi")) {
+            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
+        }
+        String queryString = UtilHttp.urlEncodeArgs(inputFields);
+        // strip legacy viewIndex/viewSize params from the query string
+        queryString = UtilHttp.stripViewParamsFromQueryString(queryString, "" + paginatorNumber);
+        // strip parametrized index/size params from the query string
+        HashSet<String> paramNames = new HashSet<String>();
+        paramNames.add(viewIndexParam);
+        paramNames.add(viewSizeParam);
+        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);
+
+        String anchor = "";
+        String paginateAnchor = modelForm.getPaginateTargetAnchor();
+        if (paginateAnchor != null) anchor = "#" + paginateAnchor;
+
+        // preparing the link text, so that later in the code we can reuse this and just add the viewIndex
+        StringBuilder prepLinkTextBuffer = new StringBuilder(targetService);
+        if (prepLinkTextBuffer.indexOf("?") < 0) {
+            prepLinkTextBuffer.append("?");
+        } else if (prepLinkTextBuffer.indexOf("?", prepLinkTextBuffer.length() - 1) > 0) {
+            prepLinkTextBuffer.append("&amp;");
+        }
+        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
+            prepLinkTextBuffer.append(queryString).append("&amp;");
+        }
+        prepLinkTextBuffer.append(viewSizeParam).append("=").append(viewSize).append("&amp;").append(viewIndexParam).append("=");
+        String prepLinkText = prepLinkTextBuffer.toString();
+
+        String linkText;
+
+        appendWhitespace(writer);
+        // The current screenlet title bar navigation syling requires rendering
+        // these links in reverse order
+        // Last button
+        writer.append("<li class=\"").append(modelForm.getPaginateLastStyle());
+        if (highIndex < listSize) {
+            writer.append("\"><a href=\"");
+            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
+            linkText = prepLinkText + lastIndex + anchor;
+            // - make the link
+            writer.append(rh.makeLink(request, response, linkText));
+            writer.append("\">").append(modelForm.getPaginateLastLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            writer.append(" disabled\">").append(modelForm.getPaginateLastLabel(context));
+        }
+        writer.append("</li>");
+        appendWhitespace(writer);
+        // Next button
+        writer.append("<li class=\"").append(modelForm.getPaginateNextStyle());
+        if (highIndex < listSize) {
+            writer.append("\"><a href=\"");
+            linkText = prepLinkText + (viewIndex + 1) + anchor;
+            // - make the link
+            writer.append(rh.makeLink(request, response, linkText));
+            writer.append("\">").append(modelForm.getPaginateNextLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            writer.append(" disabled\">").append(modelForm.getPaginateNextLabel(context));
+        }
+        writer.append("</li>");
+        appendWhitespace(writer);
+        if (listSize > 0) {
+            writer.append("<li>");
+            writer.append(Integer.toString(lowIndex + 1)).append(" - ").append(Integer.toString(lowIndex + actualPageSize)).append(" ").append(ofLabel).append(" ").append(Integer.toString(listSize));
+            writer.append("</li>");
+            appendWhitespace(writer);
+        }
+        // Previous button
+        writer.append("<li class=\"nav-previous");
+        if (viewIndex > 0) {
+            writer.append("\"><a href=\"");
+            linkText = prepLinkText + (viewIndex - 1) + anchor;
+            // - make the link
+            writer.append(rh.makeLink(request, response, linkText));
+            writer.append("\">").append(modelForm.getPaginatePreviousLabel(context)).append("</a>");
+        } else {
+            // disabled button
+            writer.append(" disabled\">").append(modelForm.getPaginatePreviousLabel(context));
+        }
+        writer.append("</li>");
+        appendWhitespace(writer);
+        // First button
+        writer.append("<li class=\"nav-first");
+        if (viewIndex > 0) {
+            writer.append("\"><a href=\"");
+            linkText = prepLinkText + 0 + anchor;
+            writer.append(rh.makeLink(request, response, linkText));
+            writer.append("\">").append(modelForm.getPaginateFirstLabel(context)).append("</a>");
+        } else {
+            writer.append(" disabled\">").append(modelForm.getPaginateFirstLabel(context));
+        }
+        writer.append("</li>");
+        appendWhitespace(writer);
+    }
+
+    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, Screenlet screenlet) throws GeneralException, IOException {
+        if (subWidget.equals(screenlet.getNavigationForm())) {
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            if (request != null && response != null) {
+                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
+                globalCtx.put("NO_PAGINATOR", true);
+                FormStringRenderer savedRenderer = (FormStringRenderer) context.get("formStringRenderer");
+                HtmlFormRenderer renderer = new HtmlFormRenderer(request, response);
+                renderer.setRenderPagination(false);
+                context.put("formStringRenderer", renderer);
+                subWidget.renderWidgetString(writer, context, this);
+                context.put("formStringRenderer", savedRenderer);
+            }
+        } else {
+            subWidget.renderWidgetString(writer, context, this);
+        }
+    }
+
+    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, Screenlet screenlet) throws IOException {
+        writer.append("</div>");
+        appendWhitespace(writer);
+        writer.append("</div>");
+        appendWhitespace(writer);
+    }
+
+    public static class ScreenletMenuRenderer extends HtmlMenuRenderer {
+        public ScreenletMenuRenderer(HttpServletRequest request, HttpServletResponse response) {
+            super(request, response);
+        }
+        @Override
+        public void renderMenuOpen(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) {}
+        @Override
+        public void renderMenuClose(Appendable writer, Map<String, Object> context, ModelMenu modelMenu) {}
+    }
+
+    public void renderLabel(Appendable writer, Map<String, Object> context, Label label) throws IOException {
+        String labelText = label.getText(context);
+        if (UtilValidate.isEmpty(labelText)) {
+            // nothing to render
+            return;
+        }
+        // open tag
+        String style = label.getStyle(context);
+        String id = label.getId(context);
+        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id)) {
+               writer.append("<span");
+
+            if (UtilValidate.isNotEmpty(id)) {
+                writer.append(" id=\"");
+                writer.append(id);
+                writer.append("\"");
+            }
+            if (UtilValidate.isNotEmpty(style)) {
+                writer.append(" class=\"");
+                writer.append(style);
+                writer.append("\"");
+            }
+            writer.append(">");
+
+            // the text
+            writer.append(labelText);
+
+            // close tag
+               writer.append("</span>");
+
+        } else {
+            writer.append(labelText);
+        }
+
+        appendWhitespace(writer);
+    }
+
+    public void renderLink(Appendable writer, Map<String, Object> context, ScreenLink link) throws IOException {
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+
+        String targetWindow = link.getTargetWindow(context);
+        String target = link.getTarget(context);
+
+        String uniqueItemName = link.getModelScreen().getName() + "_LF_" + UtilMisc.<String>addToBigDecimalInMap(context, "screenUniqueItemIndex", BigDecimal.ONE);
+
+        String linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request);
+        if ("hidden-form".equals(linkType)) {
+            writer.append("<form method=\"post\"");
+            writer.append(" action=\"");
+            // note that this passes null for the parameterList on purpose so they won't be put into the URL
+            WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), null, link.getPrefix(context),
+                    link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
+            writer.append("\"");
+
+            if (UtilValidate.isNotEmpty(targetWindow)) {
+                writer.append(" target=\"");
+                writer.append(targetWindow);
+                writer.append("\"");
+            }
+
+            writer.append(" onsubmit=\"javascript:submitFormDisableSubmits(this)\"");
+
+            writer.append(" name=\"");
+            writer.append(uniqueItemName);
+            writer.append("\">");
+
+            for (Map.Entry<String, String> parameter: link.getParameterMap(context).entrySet()) {
+                writer.append("<input name=\"");
+                writer.append(parameter.getKey());
+                writer.append("\" value=\"");
+                writer.append(parameter.getValue());
+                writer.append("\" type=\"hidden\"/>");
+            }
+
+            writer.append("</form>");
+        }
+
+        writer.append("<a");
+        String id = link.getId(context);
+        if (UtilValidate.isNotEmpty(id)) {
+            writer.append(" id=\"");
+            writer.append(id);
+            writer.append("\"");
+        }
+        String style = link.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append(" class=\"");
+            writer.append(style);
+            writer.append("\"");
+        }
+        String name = link.getName(context);
+        if (UtilValidate.isNotEmpty(name)) {
+            writer.append(" name=\"");
+            writer.append(name);
+            writer.append("\"");
+        }
+        if (UtilValidate.isNotEmpty(targetWindow)) {
+            writer.append(" target=\"");
+            writer.append(targetWindow);
+            writer.append("\"");
+        }
+        if (UtilValidate.isNotEmpty(target)) {
+            writer.append(" href=\"");
+            if ("hidden-form".equals(linkType)) {
+                writer.append("javascript:document.");
+                writer.append(uniqueItemName);
+                writer.append(".submit()");
+            } else {
+                WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
+                        link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
+            }
+            writer.append("\"");
+        }
+        writer.append(">");
+
+        // the text
+        ScreenImage img = link.getImage();
+        if (img == null) {
+            writer.append(link.getText(context));
+        } else {
+            renderImage(writer, context, img);
+        }
+
+        // close tag
+        writer.append("</a>");
+
+        appendWhitespace(writer);
+    }
+
+    public void renderImage(Appendable writer, Map<String, Object> context, ScreenImage image) throws IOException {
+        // open tag
+        String src = image.getSrc(context);
+        if (UtilValidate.isEmpty(src)) {
+            return;
+        }
+        writer.append("<img ");
+        String id = image.getId(context);
+        if (UtilValidate.isNotEmpty(id)) {
+            writer.append(" id=\"");
+            writer.append(id);
+            writer.append("\"");
+        }
+        String style = image.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append(" class=\"");
+            writer.append(style);
+            writer.append("\"");
+        }
+        String wid = image.getWidth(context);
+        if (UtilValidate.isNotEmpty(wid)) {
+            writer.append(" width=\"");
+            writer.append(wid);
+            writer.append("\"");
+        }
+        String hgt = image.getHeight(context);
+        if (UtilValidate.isNotEmpty(hgt)) {
+            writer.append(" height=\"");
+            writer.append(hgt);
+            writer.append("\"");
+        }
+        String border = image.getBorder(context);
+        if (UtilValidate.isNotEmpty(border)) {
+            writer.append(" border=\"");
+            writer.append(border);
+            writer.append("\"");
+        }
+        String alt = image.getAlt(context);
+        if (UtilValidate.isNotEmpty(alt)) {
+            writer.append(" alt=\"");
+            writer.append(alt);
+            writer.append("\"");
+        }
+
+        writer.append(" src=\"");
+        String urlMode = image.getUrlMode();
+        boolean fullPath = false;
+        boolean secure = false;
+        boolean encode = false;
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
+            if (request != null && response != null) {
+                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                String urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
+                writer.append(urlString);
+            } else {
+                writer.append(src);
+            }
+        } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
+            if (request != null && response != null) {
+                StringBuilder newURL = new StringBuilder();
+                ContentUrlTag.appendContentPrefix(request, newURL);
+                newURL.append(src);
+                writer.append(newURL.toString());
+            }
+        } else {
+            writer.append(src);
+        }
+
+        writer.append("\"/>");
+
+        appendWhitespace(writer);
+    }
+
+    public void renderContentBegin(Appendable writer, Map<String, Object> context, Content content) throws IOException {
+        String editRequest = content.getEditRequest(context);
+        String editContainerStyle = content.getEditContainerStyle(context);
+        String enableEditName = content.getEnableEditName(context);
+        String enableEditValue = (String)context.get(enableEditName);
+
+        if (Debug.verboseOn()) Debug.logVerbose("directEditRequest:" + editRequest, module);
+
+        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
+            writer.append("<div");
+            writer.append(" class=\"").append(editContainerStyle).append("\"> ");
+            appendWhitespace(writer);
+        }
+    }
+
+    public void renderContentBody(Appendable writer, Map<String, Object> context, Content content) throws IOException {
+        Locale locale = UtilMisc.ensureLocale(context.get("locale"));
+        //Boolean nullThruDatesOnly = Boolean.valueOf(false);
+        String mimeTypeId = "text/html";
+        String expandedContentId = content.getContentId(context);
+        String expandedDataResourceId = content.getDataResourceId(context);
+        String renderedContent = null;
+        LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+        Delegator delegator = (Delegator) context.get("delegator");
+
+        // make a new map for content rendering; so our current map does not get clobbered
+        Map<String, Object> contentContext = new HashMap<String, Object>();
+        contentContext.putAll(context);
+        String dataResourceId = (String)contentContext.get("dataResourceId");
+        if (Debug.verboseOn()) Debug.logVerbose("expandedContentId:" + expandedContentId, module);
+
+        try {
+            if (UtilValidate.isNotEmpty(dataResourceId)) {
+                if (WidgetDataResourceWorker.dataresourceWorker != null) {
+                    renderedContent = WidgetDataResourceWorker.dataresourceWorker.renderDataResourceAsTextExt(delegator, dataResourceId, contentContext, locale, mimeTypeId, false);
+                } else {
+                    Debug.logError("Not rendering content, WidgetDataResourceWorker.dataresourceWorker not found.", module);
+                }
+            } else if (UtilValidate.isNotEmpty(expandedContentId)) {
+                if (WidgetContentWorker.contentWorker != null) {
+                    renderedContent = WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, expandedContentId, contentContext, locale, mimeTypeId, true);
+                } else {
+                    Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
+                }
+            } else if (UtilValidate.isNotEmpty(expandedDataResourceId)) {
+                if (WidgetDataResourceWorker.dataresourceWorker != null) {
+                    renderedContent = WidgetDataResourceWorker.dataresourceWorker.renderDataResourceAsTextExt(delegator, expandedDataResourceId, contentContext, locale, mimeTypeId, false);
+                } else {
+                    Debug.logError("Not rendering content, WidgetDataResourceWorker.dataresourceWorker not found.", module);
+                }
+            }
+            if (UtilValidate.isEmpty(renderedContent)) {
+                String editRequest = content.getEditRequest(context);
+                if (UtilValidate.isNotEmpty(editRequest)) {
+                    if (WidgetContentWorker.contentWorker != null) {
+                        WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, "NOCONTENTFOUND", writer, contentContext, locale, mimeTypeId, true);
+                    } else {
+                        Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
+                    }
+                }
+            } else {
+                if (content.xmlEscape()) {
+                    renderedContent = UtilFormatOut.encodeXmlValue(renderedContent);
+                }
+
+                writer.append(renderedContent);
+            }
+
+        } catch (GeneralException e) {
+            String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e.toString();
+            Debug.logError(e, errMsg, module);
+            //throw new RuntimeException(errMsg);
+        } catch (IOException e2) {
+            String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e2.toString();
+            Debug.logError(e2, errMsg, module);
+            //throw new RuntimeException(errMsg);
+        }
+    }
+
+    public void renderContentEnd(Appendable writer, Map<String, Object> context, Content content) throws IOException {
+
+                //Debug.logInfo("renderContentEnd, context:" + context, module);
+        String expandedContentId = content.getContentId(context);
+        String editMode = "Edit";
+        String editRequest = content.getEditRequest(context);
+        String editContainerStyle = content.getEditContainerStyle(context);
+        String enableEditName = content.getEnableEditName(context);
+        String enableEditValue = (String)context.get(enableEditName);
+        if (editRequest != null && editRequest.toUpperCase().indexOf("IMAGE") > 0) {
+            editMode += " Image";
+        }
+        //String editRequestWithParams = editRequest + "?contentId=${currentValue.contentId}&drDataResourceId=${currentValue.drDataResourceId}&directEditRequest=${directEditRequest}&indirectEditRequest=${indirectEditRequest}&caContentIdTo=${currentValue.caContentIdTo}&caFromDate=${currentValue.caFromDate}&caContentAssocTypeId=${currentValue.caContentAssocTypeId}";
+
+        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+            if (request != null && response != null) {
+                if (editRequest.indexOf("?") < 0)  editRequest += "?";
+                else editRequest += "&amp;";
+                editRequest += "contentId=" + expandedContentId;
+                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                writer.append("<a href=\"").append(rh.makeLink(request, response, editRequest, false, false, false)).append("\">").append(editMode).append("</a>");
+            }
+            if (UtilValidate.isNotEmpty(editContainerStyle)) {
+                writer.append("</div>");
+            }
+            appendWhitespace(writer);
+        }
+    }
+
+    public void renderContentFrame(Appendable writer, Map<String, Object> context, Content content) throws IOException {
+
+
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        if (request != null && response != null) {
+            ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+            RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+            String dataResourceId = content.getDataResourceId(context);
+//          String urlString = "/content/control/ViewSimpleContent?dataResourceId=" + dataResourceId;
+            String urlString = "/ViewSimpleContent?dataResourceId=" + dataResourceId;
+
+            writer.append("<iframe src=\"").append(rh.makeLink(request, response, urlString, true, false, false)).append("\" ");
+            writer.append(" width=\"").append(content.getWidth()).append("\"");
+            writer.append(" height=\"").append(content.getHeight()).append("\"");
+            String border = content.getBorder();
+            if (UtilValidate.isNotEmpty(border)) {
+                writer.append(" border=\"").append(border).append("\"");
+            }
+            writer.append(" />");
+        }
+
+    }
+
+    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, SubContent content) throws IOException {
+
+        String editRequest = content.getEditRequest(context);
+        String editContainerStyle = content.getEditContainerStyle(context);
+        String enableEditName = content.getEnableEditName(context);
+        String enableEditValue = (String)context.get(enableEditName);
+        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
+            writer.append("<div");
+            writer.append(" class=\"").append(editContainerStyle).append("\"> ");
+
+            appendWhitespace(writer);
+        }
+    }
+
+    public void renderSubContentBody(Appendable writer, Map<String, Object> context, SubContent content) throws IOException {
+            Locale locale = Locale.getDefault();
+            String mimeTypeId = "text/html";
+            String expandedContentId = content.getContentId(context);
+            String expandedMapKey = content.getMapKey(context);
+            String renderedContent = null;
+            LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+            Delegator delegator = (Delegator) context.get("delegator");
+
+            // create a new map for the content rendering; so our current context does not get overwritten!
+            Map<String, Object> contentContext = new HashMap<String, Object>();
+            contentContext.putAll(context);
+
+            try {
+                if (WidgetContentWorker.contentWorker != null) {
+                    renderedContent = WidgetContentWorker.contentWorker.renderSubContentAsTextExt(dispatcher, delegator, expandedContentId, expandedMapKey, contentContext, locale, mimeTypeId, true);
+                    //Debug.logInfo("renderedContent=" + renderedContent, module);
+                } else {
+                    Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
+                }
+                if (UtilValidate.isEmpty(renderedContent)) {
+                    String editRequest = content.getEditRequest(context);
+                    if (UtilValidate.isNotEmpty(editRequest)) {
+                        if (WidgetContentWorker.contentWorker != null) {
+                            WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, "NOCONTENTFOUND", writer, contentContext, locale, mimeTypeId, true);
+                        } else {
+                            Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
+                        }
+                    }
+                } else {
+                    if (content.xmlEscape()) {
+                        renderedContent = UtilFormatOut.encodeXmlValue(renderedContent);
+                    }
+
+                    writer.append(renderedContent);
+                }
+
+            } catch (GeneralException e) {
+                String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e.toString();
+                Debug.logError(e, errMsg, module);
+                //throw new RuntimeException(errMsg);
+            } catch (IOException e2) {
+                String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e2.toString();
+                Debug.logError(e2, errMsg, module);
+                //throw new RuntimeException(errMsg);
+            }
+    }
+
+    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, SubContent content) throws IOException {
+
+        String editMode = "Edit";
+        String editRequest = content.getEditRequest(context);
+        String editContainerStyle = content.getEditContainerStyle(context);
+        String enableEditName = content.getEnableEditName(context);
+        String enableEditValue = (String)context.get(enableEditName);
+        String expandedContentId = content.getContentId(context);
+        String expandedMapKey = content.getMapKey(context);
+        if (editRequest != null && editRequest.toUpperCase().indexOf("IMAGE") > 0) {
+            editMode += " Image";
+        }
+        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+            if (request != null && response != null) {
+                if (editRequest.indexOf("?") < 0)  editRequest += "?";
+                else editRequest += "&amp;";
+                editRequest += "contentId=" + expandedContentId;
+                if (UtilValidate.isNotEmpty(expandedMapKey)) {
+                    editRequest += "&amp;mapKey=" + expandedMapKey;
+                }
+                //HttpSession session = request.getSession();
+                //GenericValue userLogin = (GenericValue)session.getAttribute("userLogin");
+                /* don't know why this is here. might come to me later. -amb
+                Delegator delegator = (Delegator)request.getAttribute("delegator");
+                String contentIdTo = content.getContentId(context);
+                String mapKey = content.getAssocName(context);
+                GenericValue view = null;
+                try {
+                    view = ContentWorker.getSubContentCache(delegator, contentIdTo, mapKey, userLogin, null, UtilDateTime.nowTimestamp(), Boolean.valueOf(false), null);
+                } catch (GenericEntityException e) {
+                    throw new IOException("Originally a GenericEntityException. " + e.getMessage());
+                }
+                */
+                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                writer.append("<a href=\"").append(rh.makeLink(request, response, editRequest, false, false, false)).append("\">").append(editMode).append("</a>");
+            }
+            if (UtilValidate.isNotEmpty(editContainerStyle)) {
+                writer.append("</div>");
+            }
+            appendWhitespace(writer);
+        }
+    }
+
+    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, PortalPage portalPage) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, PortalPage portalPage) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+
+    @Override
+    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ColumnContainer columnContainer) throws IOException {
+        // TODO: not implemented
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlTreeRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlTreeRenderer.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlTreeRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlTreeRenderer.java
index d3a3d4a..ba509a5 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlTreeRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlTreeRenderer.java
@@ -1,342 +1,342 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.screen.ScreenRenderer;
-import org.ofbiz.widget.screen.ScreenStringRenderer;
-import org.ofbiz.widget.tree.ModelTree;
-import org.ofbiz.widget.tree.TreeStringRenderer;
-
-
-/**
- * Widget Library - HTML Tree Renderer implementation
- */
-public class HtmlTreeRenderer extends HtmlWidgetRenderer implements TreeStringRenderer {
-
-    ScreenStringRenderer screenStringRenderer = null;
-    public static final String module = HtmlTreeRenderer.class.getName();
-
-    public HtmlTreeRenderer() {}
-
-    public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException {
-        String currentNodeTrailPiped = null;
-        List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
-        if (node.isRootNode()) {
-            appendWhitespace(writer);
-            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-            renderBeginningBoundaryComment(writer, "Tree Widget", node.getModelTree());
-            writer.append("<ul class=\"basic-tree\">");
-        }
-        appendWhitespace(writer);
-        writer.append("<li>");
-
-        String pkName = node.getPkName(context);
-        String entityId = null;
-        String entryName = node.getEntryName();
-        if (UtilValidate.isNotEmpty(entryName)) {
-            entityId = UtilGenerics.<Map<String, String>>cast(context.get(entryName)).get(pkName);
-        } else {
-            entityId = (String) context.get(pkName);
-        }
-        boolean hasChildren = node.hasChildren(context);
-
-        // check to see if this node needs to be expanded.
-        if (hasChildren && node.isExpandCollapse()) {
-            String targetEntityId = null;
-            List<String> targetNodeTrail = UtilGenerics.toList(context.get("targetNodeTrail"));
-            if (depth < targetNodeTrail.size()) {
-                targetEntityId = targetNodeTrail.get(depth);
-            }
-            // FIXME: Using a widget model in this way is an ugly hack.
-            ModelTree.ModelNode.Link expandCollapseLink = null;
-            int openDepth = node.getModelTree().getOpenDepth();
-            if (depth >= openDepth && (targetEntityId == null || !targetEntityId.equals(entityId))) {
-                // Not on the trail
-                if (node.showPeers(depth, context)) {
-                    context.put("processChildren", Boolean.FALSE);
-                    //expandCollapseLink.setText("&nbsp;+&nbsp;");
-                    currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
-                    StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
-                    String trailName = node.getModelTree().getTrailName(context);
-                    if (target.indexOf("?") < 0) {
-                        target.append("?");
-                    } else {
-                        target.append("&");
-                    }
-                    target.append(trailName).append("=").append(currentNodeTrailPiped);
-                    expandCollapseLink = new ModelTree.ModelNode.Link("collapsed", target.toString(), " ");
-                }
-            } else {
-                context.put("processChildren", Boolean.TRUE);
-                //expandCollapseLink.setText("&nbsp;-&nbsp;");
-                String lastContentId = currentNodeTrail.remove(currentNodeTrail.size() - 1);
-                currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
-                if (currentNodeTrailPiped == null) {
-                    currentNodeTrailPiped = "";
-                }
-                StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
-                String trailName = node.getModelTree().getTrailName(context);
-                if (target.indexOf("?") < 0) {
-                    target.append("?");
-                } else {
-                    target.append("&");
-                }
-                target.append(trailName).append("=").append(currentNodeTrailPiped);
-                expandCollapseLink = new ModelTree.ModelNode.Link("expanded", target.toString(), " ");
-                // add it so it can be remove in renderNodeEnd
-                currentNodeTrail.add(lastContentId);
-            }
-            if (expandCollapseLink != null) {
-                renderLink(writer, context, expandCollapseLink);
-            }
-        } else if (!hasChildren) {
-            context.put("processChildren", Boolean.FALSE);
-            ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link("leafnode", "", " ");
-            renderLink(writer, context, expandCollapseLink);
-        }
-    }
-
-    public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
-        Boolean processChildren = (Boolean) context.get("processChildren");
-        if (processChildren.booleanValue()) {
-            appendWhitespace(writer);
-            writer.append("</ul>");
-        }
-        appendWhitespace(writer);
-        writer.append("</li>");
-        if (node.isRootNode()) {
-            appendWhitespace(writer);
-            writer.append("</ul>");
-            appendWhitespace(writer);
-            renderEndingBoundaryComment(writer, "Tree Widget", node.getModelTree());
-        }
-    }
-
-    public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
-        Boolean processChildren = (Boolean) context.get("processChildren");
-        if (processChildren.booleanValue()) {
-            appendWhitespace(writer);
-            writer.append("<ul class=\"basic-tree\">");
-        }
-    }
-
-    public void renderLabel(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Label label) throws IOException {
-        // open tag
-        writer.append("<span");
-        String id = label.getId(context);
-        if (UtilValidate.isNotEmpty(id)) {
-            writer.append(" id=\"");
-            writer.append(id);
-            writer.append("\"");
-        }
-        String style = label.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append(" class=\"");
-            writer.append(style);
-            writer.append("\"");
-        }
-        writer.append(">");
-
-        // the text
-        writer.append(label.getText(context));
-
-        // close tag
-        writer.append("</span>");
-
-        appendWhitespace(writer);
-    }
-
-
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Link link) throws IOException {
-        // open tag
-        writer.append("<a");
-        String id = link.getId(context);
-        if (UtilValidate.isNotEmpty(id)) {
-            writer.append(" id=\"");
-            writer.append(id);
-            writer.append("\"");
-        }
-        String style = link.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append(" class=\"");
-            writer.append(style);
-            writer.append("\"");
-        }
-        String name = link.getName(context);
-        if (UtilValidate.isNotEmpty(name)) {
-            writer.append(" name=\"");
-            writer.append(name);
-            writer.append("\"");
-        }
-        String title = link.getTitle(context);
-        if (UtilValidate.isNotEmpty(title)) {
-            writer.append(" title=\"");
-            writer.append(title);
-            writer.append("\"");
-        }
-        String targetWindow = link.getTargetWindow(context);
-        if (UtilValidate.isNotEmpty(targetWindow)) {
-            writer.append(" target=\"");
-            writer.append(targetWindow);
-            writer.append("\"");
-        }
-        String target = link.getTarget(context);
-        if (UtilValidate.isNotEmpty(target)) {
-            writer.append(" href=\"");
-            String urlMode = link.getUrlMode();
-            String prefix = link.getPrefix(context);
-            HttpServletResponse res = (HttpServletResponse) context.get("response");
-            HttpServletRequest req = (HttpServletRequest) context.get("request");
-            if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
-                if (req != null && res != null) {
-                    WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
-                        link.getFullPath(), link.getSecure(), link.getEncode(), req, res, context);
-                } else if (prefix != null) {
-                    writer.append(prefix).append(target);
-                } else {
-                    writer.append(target);
-                }
-            } else if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
-                StringBuilder newURL = new StringBuilder();
-                ContentUrlTag.appendContentPrefix(req, newURL);
-                newURL.append(target);
-                writer.append(newURL.toString());
-            } else if ("inter-app".equalsIgnoreCase(urlMode) && req != null) {
-                String externalLoginKey = (String) req.getAttribute("externalLoginKey");
-                if (UtilValidate.isNotEmpty(externalLoginKey)) {
-                    writer.append(target);
-                    if (target.contains("?")) {
-                        writer.append("&externalLoginKey=");
-                    } else {
-                        writer.append("?externalLoginKey=");
-                    }
-                    writer.append(externalLoginKey);
-                }
-            } else {
-                writer.append(target);
-            }
-            writer.append("\"");
-        }
-        writer.append(">");
-
-        // the text
-        ModelTree.ModelNode.Image img = link.getImage();
-        if (img == null) {
-            writer.append(link.getText(context));
-        } else {
-            renderImage(writer, context, img);
-        }
-        // close tag
-        writer.append("</a>");
-    }
-
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Image image) throws IOException {
-        // open tag
-        writer.append("<img ");
-        String id = image.getId(context);
-        if (UtilValidate.isNotEmpty(id)) {
-            writer.append(" id=\"");
-            writer.append(id);
-            writer.append("\"");
-        }
-        String style = image.getStyle(context);
-        if (UtilValidate.isNotEmpty(style)) {
-            writer.append(" class=\"");
-            writer.append(style);
-            writer.append("\"");
-        }
-        String wid = image.getWidth(context);
-        if (UtilValidate.isNotEmpty(wid)) {
-            writer.append(" width=\"");
-            writer.append(wid);
-            writer.append("\"");
-        }
-        String hgt = image.getHeight(context);
-        if (UtilValidate.isNotEmpty(hgt)) {
-            writer.append(" height=\"");
-            writer.append(hgt);
-            writer.append("\"");
-        }
-        String border = image.getBorder(context);
-        if (UtilValidate.isNotEmpty(border)) {
-            writer.append(" border=\"");
-            writer.append(border);
-            writer.append("\"");
-        }
-        String src = image.getSrc(context);
-        if (UtilValidate.isNotEmpty(src)) {
-            writer.append(" src=\"");
-            String urlMode = image.getUrlMode();
-            boolean fullPath = false;
-            boolean secure = false;
-            boolean encode = false;
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-            if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
-                if (request != null && response != null) {
-                    ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                    RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                    String urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
-                    writer.append(urlString);
-                } else {
-                    writer.append(src);
-                }
-            } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
-                if (request != null && response != null) {
-                    StringBuilder newURL = new StringBuilder();
-                    ContentUrlTag.appendContentPrefix(request, newURL);
-                    newURL.append(src);
-                    writer.append(newURL.toString());
-                }
-            } else {
-                writer.append(src);
-            }
-            writer.append("\"");
-        }
-        writer.append("/>");
-
-    }
-
-    public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context) {
-        ScreenRenderer screenRenderer = (ScreenRenderer)context.get("screens");
-        if (screenRenderer != null) {
-            screenStringRenderer = screenRenderer.getScreenStringRenderer();
-        } else {
-            if (screenStringRenderer == null) {
-                screenStringRenderer = new HtmlScreenRenderer();
-            }
-        }
-        return screenStringRenderer;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.webapp.control.RequestHandler;
+import org.ofbiz.webapp.taglib.ContentUrlTag;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.ModelTree;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.TreeStringRenderer;
+
+
+/**
+ * Widget Library - HTML Tree Renderer implementation
+ */
+public class HtmlTreeRenderer extends HtmlWidgetRenderer implements TreeStringRenderer {
+
+    ScreenStringRenderer screenStringRenderer = null;
+    public static final String module = HtmlTreeRenderer.class.getName();
+
+    public HtmlTreeRenderer() {}
+
+    public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException {
+        String currentNodeTrailPiped = null;
+        List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
+        if (node.isRootNode()) {
+            appendWhitespace(writer);
+            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+            renderBeginningBoundaryComment(writer, "Tree Widget", node.getModelTree());
+            writer.append("<ul class=\"basic-tree\">");
+        }
+        appendWhitespace(writer);
+        writer.append("<li>");
+
+        String pkName = node.getPkName(context);
+        String entityId = null;
+        String entryName = node.getEntryName();
+        if (UtilValidate.isNotEmpty(entryName)) {
+            entityId = UtilGenerics.<Map<String, String>>cast(context.get(entryName)).get(pkName);
+        } else {
+            entityId = (String) context.get(pkName);
+        }
+        boolean hasChildren = node.hasChildren(context);
+
+        // check to see if this node needs to be expanded.
+        if (hasChildren && node.isExpandCollapse()) {
+            String targetEntityId = null;
+            List<String> targetNodeTrail = UtilGenerics.toList(context.get("targetNodeTrail"));
+            if (depth < targetNodeTrail.size()) {
+                targetEntityId = targetNodeTrail.get(depth);
+            }
+            // FIXME: Using a widget model in this way is an ugly hack.
+            ModelTree.ModelNode.Link expandCollapseLink = null;
+            int openDepth = node.getModelTree().getOpenDepth();
+            if (depth >= openDepth && (targetEntityId == null || !targetEntityId.equals(entityId))) {
+                // Not on the trail
+                if (node.showPeers(depth, context)) {
+                    context.put("processChildren", Boolean.FALSE);
+                    //expandCollapseLink.setText("&nbsp;+&nbsp;");
+                    currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
+                    StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
+                    String trailName = node.getModelTree().getTrailName(context);
+                    if (target.indexOf("?") < 0) {
+                        target.append("?");
+                    } else {
+                        target.append("&");
+                    }
+                    target.append(trailName).append("=").append(currentNodeTrailPiped);
+                    expandCollapseLink = new ModelTree.ModelNode.Link("collapsed", target.toString(), " ");
+                }
+            } else {
+                context.put("processChildren", Boolean.TRUE);
+                //expandCollapseLink.setText("&nbsp;-&nbsp;");
+                String lastContentId = currentNodeTrail.remove(currentNodeTrail.size() - 1);
+                currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
+                if (currentNodeTrailPiped == null) {
+                    currentNodeTrailPiped = "";
+                }
+                StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
+                String trailName = node.getModelTree().getTrailName(context);
+                if (target.indexOf("?") < 0) {
+                    target.append("?");
+                } else {
+                    target.append("&");
+                }
+                target.append(trailName).append("=").append(currentNodeTrailPiped);
+                expandCollapseLink = new ModelTree.ModelNode.Link("expanded", target.toString(), " ");
+                // add it so it can be remove in renderNodeEnd
+                currentNodeTrail.add(lastContentId);
+            }
+            if (expandCollapseLink != null) {
+                renderLink(writer, context, expandCollapseLink);
+            }
+        } else if (!hasChildren) {
+            context.put("processChildren", Boolean.FALSE);
+            ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link("leafnode", "", " ");
+            renderLink(writer, context, expandCollapseLink);
+        }
+    }
+
+    public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
+        Boolean processChildren = (Boolean) context.get("processChildren");
+        if (processChildren.booleanValue()) {
+            appendWhitespace(writer);
+            writer.append("</ul>");
+        }
+        appendWhitespace(writer);
+        writer.append("</li>");
+        if (node.isRootNode()) {
+            appendWhitespace(writer);
+            writer.append("</ul>");
+            appendWhitespace(writer);
+            renderEndingBoundaryComment(writer, "Tree Widget", node.getModelTree());
+        }
+    }
+
+    public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
+        Boolean processChildren = (Boolean) context.get("processChildren");
+        if (processChildren.booleanValue()) {
+            appendWhitespace(writer);
+            writer.append("<ul class=\"basic-tree\">");
+        }
+    }
+
+    public void renderLabel(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Label label) throws IOException {
+        // open tag
+        writer.append("<span");
+        String id = label.getId(context);
+        if (UtilValidate.isNotEmpty(id)) {
+            writer.append(" id=\"");
+            writer.append(id);
+            writer.append("\"");
+        }
+        String style = label.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append(" class=\"");
+            writer.append(style);
+            writer.append("\"");
+        }
+        writer.append(">");
+
+        // the text
+        writer.append(label.getText(context));
+
+        // close tag
+        writer.append("</span>");
+
+        appendWhitespace(writer);
+    }
+
+
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Link link) throws IOException {
+        // open tag
+        writer.append("<a");
+        String id = link.getId(context);
+        if (UtilValidate.isNotEmpty(id)) {
+            writer.append(" id=\"");
+            writer.append(id);
+            writer.append("\"");
+        }
+        String style = link.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append(" class=\"");
+            writer.append(style);
+            writer.append("\"");
+        }
+        String name = link.getName(context);
+        if (UtilValidate.isNotEmpty(name)) {
+            writer.append(" name=\"");
+            writer.append(name);
+            writer.append("\"");
+        }
+        String title = link.getTitle(context);
+        if (UtilValidate.isNotEmpty(title)) {
+            writer.append(" title=\"");
+            writer.append(title);
+            writer.append("\"");
+        }
+        String targetWindow = link.getTargetWindow(context);
+        if (UtilValidate.isNotEmpty(targetWindow)) {
+            writer.append(" target=\"");
+            writer.append(targetWindow);
+            writer.append("\"");
+        }
+        String target = link.getTarget(context);
+        if (UtilValidate.isNotEmpty(target)) {
+            writer.append(" href=\"");
+            String urlMode = link.getUrlMode();
+            String prefix = link.getPrefix(context);
+            HttpServletResponse res = (HttpServletResponse) context.get("response");
+            HttpServletRequest req = (HttpServletRequest) context.get("request");
+            if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
+                if (req != null && res != null) {
+                    WidgetWorker.buildHyperlinkUrl(writer, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
+                        link.getFullPath(), link.getSecure(), link.getEncode(), req, res, context);
+                } else if (prefix != null) {
+                    writer.append(prefix).append(target);
+                } else {
+                    writer.append(target);
+                }
+            } else if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
+                StringBuilder newURL = new StringBuilder();
+                ContentUrlTag.appendContentPrefix(req, newURL);
+                newURL.append(target);
+                writer.append(newURL.toString());
+            } else if ("inter-app".equalsIgnoreCase(urlMode) && req != null) {
+                String externalLoginKey = (String) req.getAttribute("externalLoginKey");
+                if (UtilValidate.isNotEmpty(externalLoginKey)) {
+                    writer.append(target);
+                    if (target.contains("?")) {
+                        writer.append("&externalLoginKey=");
+                    } else {
+                        writer.append("?externalLoginKey=");
+                    }
+                    writer.append(externalLoginKey);
+                }
+            } else {
+                writer.append(target);
+            }
+            writer.append("\"");
+        }
+        writer.append(">");
+
+        // the text
+        ModelTree.ModelNode.Image img = link.getImage();
+        if (img == null) {
+            writer.append(link.getText(context));
+        } else {
+            renderImage(writer, context, img);
+        }
+        // close tag
+        writer.append("</a>");
+    }
+
+    public void renderImage(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Image image) throws IOException {
+        // open tag
+        writer.append("<img ");
+        String id = image.getId(context);
+        if (UtilValidate.isNotEmpty(id)) {
+            writer.append(" id=\"");
+            writer.append(id);
+            writer.append("\"");
+        }
+        String style = image.getStyle(context);
+        if (UtilValidate.isNotEmpty(style)) {
+            writer.append(" class=\"");
+            writer.append(style);
+            writer.append("\"");
+        }
+        String wid = image.getWidth(context);
+        if (UtilValidate.isNotEmpty(wid)) {
+            writer.append(" width=\"");
+            writer.append(wid);
+            writer.append("\"");
+        }
+        String hgt = image.getHeight(context);
+        if (UtilValidate.isNotEmpty(hgt)) {
+            writer.append(" height=\"");
+            writer.append(hgt);
+            writer.append("\"");
+        }
+        String border = image.getBorder(context);
+        if (UtilValidate.isNotEmpty(border)) {
+            writer.append(" border=\"");
+            writer.append(border);
+            writer.append("\"");
+        }
+        String src = image.getSrc(context);
+        if (UtilValidate.isNotEmpty(src)) {
+            writer.append(" src=\"");
+            String urlMode = image.getUrlMode();
+            boolean fullPath = false;
+            boolean secure = false;
+            boolean encode = false;
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+            if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
+                if (request != null && response != null) {
+                    ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                    RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                    String urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
+                    writer.append(urlString);
+                } else {
+                    writer.append(src);
+                }
+            } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
+                if (request != null && response != null) {
+                    StringBuilder newURL = new StringBuilder();
+                    ContentUrlTag.appendContentPrefix(request, newURL);
+                    newURL.append(src);
+                    writer.append(newURL.toString());
+                }
+            } else {
+                writer.append(src);
+            }
+            writer.append("\"");
+        }
+        writer.append("/>");
+
+    }
+
+    public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context) {
+        ScreenRenderer screenRenderer = (ScreenRenderer)context.get("screens");
+        if (screenRenderer != null) {
+            screenStringRenderer = screenRenderer.getScreenStringRenderer();
+        } else {
+            if (screenStringRenderer == null) {
+                screenStringRenderer = new HtmlScreenRenderer();
+            }
+        }
+        return screenStringRenderer;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/html/HtmlWidgetRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlWidgetRenderer.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlWidgetRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlWidgetRenderer.java
index 21d7be1..b4a8e32 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlWidgetRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlWidgetRenderer.java
@@ -1,99 +1,99 @@
-/*******************************************************************************
- * 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.ofbiz.widget.html;
-
-import java.io.IOException;
-
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.widget.ModelWidget;
-
-/**
- * Widget Library - HTML Widget Renderer implementation. HtmlWidgetRenderer
- * is a base class that is extended by other widget HTML rendering classes.
- */
-public class HtmlWidgetRenderer {
-    public static final String module = HtmlWidgetRenderer.class.getName();
-
-    /**
-     * Characters that are appended to the end of each rendered element. Currently set to
-     * CR/LF.
-     */
-    public static final String whiteSpace = "\r\n";
-
-    protected boolean widgetCommentsEnabled = false;
-
-    /**
-     * Helper method used to append whitespace characters to the end of each rendered element.
-     * @param writer The writer to write to
-     */
-    public void appendWhitespace(Appendable writer) throws IOException {
-        writer.append(whiteSpace);
-    }
-
-    /**
-     * Helper method used to build the boundary comment string.
-     * @param boundaryType The boundary type: "Begin" or "End"
-     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
-     * @param widgetName The widget name
-     */
-    public String buildBoundaryComment(String boundaryType, String widgetType, String widgetName) {
-        return formatBoundaryComment(boundaryType, widgetType, widgetName);
-    }
-
-    public static String formatBoundaryComment(String boundaryType, String widgetType, String widgetName) {
-        return "<!-- " + boundaryType + " " + widgetType + " " + widgetName + " -->" + whiteSpace;
-    }
-
-    /**
-     * Renders the beginning boundary comment string.
-     * @param writer The writer to write to
-     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
-     * @param modelWidget The widget
-     */
-    public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
-        if (this.widgetCommentsEnabled) {
-            writer.append(this.buildBoundaryComment("Begin", widgetType, modelWidget.getBoundaryCommentName()));
-        }
-    }
-
-    /**
-     * Renders the ending boundary comment string.
-     * @param writer The writer to write to
-     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
-     * @param modelWidget The widget
-     */
-    public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
-        if (this.widgetCommentsEnabled) {
-            writer.append(this.buildBoundaryComment("End", widgetType, modelWidget.getBoundaryCommentName()));
-        }
-    }
-
-    /** Extracts parameters from a target URL string, prepares them for an Ajax
-     * JavaScript call. This method is currently set to return a parameter string
-     * suitable for the Prototype.js library.
-     * @param target Target URL string
-     * @return Parameter string
-     */
-    public static String getAjaxParamsFromTarget(String target) {
-        String targetParams = UtilHttp.getQueryStringFromTarget(target);
-        targetParams = targetParams.replace("?", "");
-        targetParams = targetParams.replace("&amp;", "&");
-        return targetParams;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.html;
+
+import java.io.IOException;
+
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.widget.model.ModelWidget;
+
+/**
+ * Widget Library - HTML Widget Renderer implementation. HtmlWidgetRenderer
+ * is a base class that is extended by other widget HTML rendering classes.
+ */
+public class HtmlWidgetRenderer {
+    public static final String module = HtmlWidgetRenderer.class.getName();
+
+    /**
+     * Characters that are appended to the end of each rendered element. Currently set to
+     * CR/LF.
+     */
+    public static final String whiteSpace = "\r\n";
+
+    protected boolean widgetCommentsEnabled = false;
+
+    /**
+     * Helper method used to append whitespace characters to the end of each rendered element.
+     * @param writer The writer to write to
+     */
+    public void appendWhitespace(Appendable writer) throws IOException {
+        writer.append(whiteSpace);
+    }
+
+    /**
+     * Helper method used to build the boundary comment string.
+     * @param boundaryType The boundary type: "Begin" or "End"
+     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
+     * @param widgetName The widget name
+     */
+    public String buildBoundaryComment(String boundaryType, String widgetType, String widgetName) {
+        return formatBoundaryComment(boundaryType, widgetType, widgetName);
+    }
+
+    public static String formatBoundaryComment(String boundaryType, String widgetType, String widgetName) {
+        return "<!-- " + boundaryType + " " + widgetType + " " + widgetName + " -->" + whiteSpace;
+    }
+
+    /**
+     * Renders the beginning boundary comment string.
+     * @param writer The writer to write to
+     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
+     * @param modelWidget The widget
+     */
+    public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
+        if (this.widgetCommentsEnabled) {
+            writer.append(this.buildBoundaryComment("Begin", widgetType, modelWidget.getBoundaryCommentName()));
+        }
+    }
+
+    /**
+     * Renders the ending boundary comment string.
+     * @param writer The writer to write to
+     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
+     * @param modelWidget The widget
+     */
+    public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
+        if (this.widgetCommentsEnabled) {
+            writer.append(this.buildBoundaryComment("End", widgetType, modelWidget.getBoundaryCommentName()));
+        }
+    }
+
+    /** Extracts parameters from a target URL string, prepares them for an Ajax
+     * JavaScript call. This method is currently set to return a parameter string
+     * suitable for the Prototype.js library.
+     * @param target Target URL string
+     * @return Parameter string
+     */
+    public static String getAjaxParamsFromTarget(String target) {
+        String targetParams = UtilHttp.getQueryStringFromTarget(target);
+        targetParams = targetParams.replace("?", "");
+        targetParams = targetParams.replace("&amp;", "&");
+        return targetParams;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
index 742f471..a369bea 100644
--- a/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
@@ -1,3124 +1,3132 @@
-/*******************************************************************************
- * 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.ofbiz.widget.form;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.rmi.server.UID;
-import java.sql.Timestamp;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilFormatOut;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.base.util.template.FreeMarkerWorker;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.CommonWidgetModels;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.ModelFormField.CheckField;
-import org.ofbiz.widget.form.ModelFormField.ContainerField;
-import org.ofbiz.widget.form.ModelFormField.DateFindField;
-import org.ofbiz.widget.form.ModelFormField.DateTimeField;
-import org.ofbiz.widget.form.ModelFormField.DisplayEntityField;
-import org.ofbiz.widget.form.ModelFormField.DisplayField;
-import org.ofbiz.widget.form.ModelFormField.DropDownField;
-import org.ofbiz.widget.form.ModelFormField.FieldInfoWithOptions;
-import org.ofbiz.widget.form.ModelFormField.FileField;
-import org.ofbiz.widget.form.ModelFormField.HiddenField;
-import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
-import org.ofbiz.widget.form.ModelFormField.IgnoredField;
-import org.ofbiz.widget.form.ModelFormField.ImageField;
-import org.ofbiz.widget.form.ModelFormField.LookupField;
-import org.ofbiz.widget.form.ModelFormField.PasswordField;
-import org.ofbiz.widget.form.ModelFormField.RadioField;
-import org.ofbiz.widget.form.ModelFormField.RangeFindField;
-import org.ofbiz.widget.form.ModelFormField.ResetField;
-import org.ofbiz.widget.form.ModelFormField.SubmitField;
-import org.ofbiz.widget.form.ModelFormField.TextField;
-import org.ofbiz.widget.form.ModelFormField.TextFindField;
-import org.ofbiz.widget.form.ModelFormField.TextareaField;
-import org.ofbiz.widget.screen.ModelScreenWidget;
-
-import com.ibm.icu.util.Calendar;
-
-import freemarker.core.Environment;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-
-/**
- * Widget Library - Form Renderer implementation based on Freemarker macros
- *
- */
-public final class MacroFormRenderer implements FormStringRenderer {
-
-    public static final String module = MacroFormRenderer.class.getName();
-    private final Template macroLibrary;
-    private final WeakHashMap<Appendable, Environment> environments = new WeakHashMap<Appendable, Environment>();
-    private final UtilCodec.SimpleEncoder internalEncoder;
-    private final RequestHandler rh;
-    private final HttpServletRequest request;
-    private final HttpServletResponse response;
-    private final boolean javaScriptEnabled;
-    private boolean renderPagination = true;
-    private boolean widgetCommentsEnabled = false;
-
-    public MacroFormRenderer(String macroLibraryPath, HttpServletRequest request, HttpServletResponse response) throws TemplateException, IOException {
-        macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
-        this.request = request;
-        this.response = response;
-        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-        this.rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-        this.javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
-        internalEncoder = UtilCodec.getEncoder("string");
-    }
-
-    @Deprecated
-    public MacroFormRenderer(String macroLibraryPath, Appendable writer, HttpServletRequest request, HttpServletResponse response) throws TemplateException, IOException {
-        this(macroLibraryPath, request, response);
-    }
-
-    public boolean getRenderPagination() {
-        return this.renderPagination;
-    }
-
-    public void setRenderPagination(boolean renderPagination) {
-        this.renderPagination = renderPagination;
-    }
-
-    private void executeMacro(Appendable writer, String macro) throws IOException {
-        try {
-            Environment environment = getEnvironment(writer);
-            Reader templateReader = new StringReader(macro);
-            Template template = new Template(new UID().toString(), templateReader, FreeMarkerWorker.getDefaultOfbizConfig());
-            templateReader.close();
-            environment.include(template);
-        } catch (TemplateException e) {
-            Debug.logError(e, "Error rendering screen thru ftl macro: " + macro, module);
-        } catch (IOException e) {
-            Debug.logError(e, "Error rendering screen thru ftl, macro: " + macro, module);
-        }
-    }
-
-    private Environment getEnvironment(Appendable writer) throws TemplateException, IOException {
-        Environment environment = environments.get(writer);
-        if (environment == null) {
-            Map<String, Object> input = UtilMisc.toMap("key", null);
-            environment = FreeMarkerWorker.renderTemplate(macroLibrary, input, writer);
-            environments.put(writer, environment);
-        }
-        return environment;
-    }
-
-    private void appendWhitespace(Appendable writer) throws IOException {
-        // appending line ends for now, but this could be replaced with a simple space or something
-        writer.append("\r\n");
-        //writer.append(' ');
-    }
-
-    private String encode(String value, ModelFormField modelFormField, Map<String, Object> context) {
-        if (UtilValidate.isEmpty(value)) {
-            return value;
-        }
-        UtilCodec.SimpleEncoder encoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-        if (modelFormField.getEncodeOutput() && encoder != null) {
-            value = encoder.encode(value);
-        } else {
-            value = internalEncoder.encode(value);
-        }
-        return value;
-    }
-
-    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException {
-        String labelText = label.getText(context);
-        if (UtilValidate.isEmpty(labelText)) {
-            // nothing to render
-            return;
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderLabel ");
-        sr.append("text=\"");
-        sr.append(labelText);
-        sr.append("\"");
-        sr.append(" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
-        ModelFormField modelFormField = displayField.getModelFormField();
-        String idName = modelFormField.getCurrentContainerId(context);
-        String description = displayField.getDescription(context);
-        String type = displayField.getType();
-        String imageLocation = displayField.getImageLocation(context);
-        Integer size = Integer.valueOf("0");
-        String title = "";
-        if (UtilValidate.isNotEmpty(displayField.getSize())) {
-            try {
-                size = Integer.parseInt(displayField.getSize());
-            } catch (NumberFormatException nfe) {
-                Debug.logError(nfe, "Error reading size of a field fieldName=" + displayField.getModelFormField().getFieldName() + " FormName= " + displayField.getModelFormField().getModelForm().getName(), module);
-            }
-        }
-        ModelFormField.InPlaceEditor inPlaceEditor = displayField.getInPlaceEditor();
-        boolean ajaxEnabled = inPlaceEditor != null && this.javaScriptEnabled;
-        if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) {
-            title = description;
-            description = description.substring(0, size - 8) + "..." + description.substring(description.length() - 5);
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderDisplayField ");
-        sr.append("type=\"");
-        sr.append(type);
-        sr.append("\" imageLocation=\"");
-        sr.append(imageLocation);
-        sr.append("\" idName=\"");
-        sr.append(idName);
-        sr.append("\" description=\"");
-        sr.append(FreeMarkerWorker.encodeDoubleQuotes(description));
-        sr.append("\" title=\"");
-        sr.append(title);
-        sr.append("\" class=\"");
-        sr.append(modelFormField.getWidgetStyle());
-        sr.append("\" alert=\"");
-        sr.append(modelFormField.shouldBeRed(context) ? "true" : "false");
-        if (ajaxEnabled) {
-            String url = inPlaceEditor.getUrl(context);
-            String extraParameter = "{";
-            Map<String, Object> fieldMap = inPlaceEditor.getFieldMap(context);
-            if (fieldMap != null) {
-                Set<Entry<String, Object>> fieldSet = fieldMap.entrySet();
-                Iterator<Entry<String, Object>> fieldIterator = fieldSet.iterator();
-                int count = 0;
-                while (fieldIterator.hasNext()) {
-                    count++;
-                    Entry<String, Object> field = fieldIterator.next();
-                    extraParameter += field.getKey() + ":'" + (String) field.getValue() + "'";
-                    if (count < fieldSet.size()) {
-                        extraParameter += ',';
-                    }
-                }
-
-            }
-            extraParameter += "}";
-            sr.append("\" inPlaceEditorUrl=\"");
-            sr.append(url);
-            sr.append("\" inPlaceEditorParams=\"");
-            StringWriter inPlaceEditorParams = new StringWriter();
-            inPlaceEditorParams.append("{name: '");
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getParamName())) {
-                inPlaceEditorParams.append(inPlaceEditor.getParamName());
-            } else {
-                inPlaceEditorParams.append(modelFormField.getFieldName());
-            }
-            inPlaceEditorParams.append("'");
-            inPlaceEditorParams.append(", method: 'POST'");
-            inPlaceEditorParams.append(", submitdata: " + extraParameter);
-            inPlaceEditorParams.append(", type: 'textarea'");
-            inPlaceEditorParams.append(", select: 'true'");
-            inPlaceEditorParams.append(", onreset: function(){jQuery('#cc_" + idName + "').css('background-color', 'transparent');}");
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelText())) {
-                inPlaceEditorParams.append(", cancel: '" + inPlaceEditor.getCancelText() + "'");
-            } else {
-                inPlaceEditorParams.append(", cancel: 'Cancel'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getClickToEditText())) {
-                inPlaceEditorParams.append(", tooltip: '" + inPlaceEditor.getClickToEditText() + "'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getFormClassName())) {
-                inPlaceEditorParams.append(", cssclass: '" + inPlaceEditor.getFormClassName() + "'");
-            } else {
-                inPlaceEditorParams.append(", cssclass: 'inplaceeditor-form'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingText())) {
-                inPlaceEditorParams.append(", indicator: '" + inPlaceEditor.getLoadingText() + "'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getOkControl())) {
-                inPlaceEditorParams.append(", submit: ");
-                if (!"false".equals(inPlaceEditor.getOkControl())) {
-                    inPlaceEditorParams.append("'");
-                }
-                inPlaceEditorParams.append(inPlaceEditor.getOkControl());
-                if (!"false".equals(inPlaceEditor.getOkControl())) {
-                    inPlaceEditorParams.append("'");
-                }
-            } else {
-                inPlaceEditorParams.append(", submit: 'OK'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getRows())) {
-                inPlaceEditorParams.append(", rows: '" + inPlaceEditor.getRows() + "'");
-            }
-            if (UtilValidate.isNotEmpty(inPlaceEditor.getCols())) {
-                inPlaceEditorParams.append(", cols: '" + inPlaceEditor.getCols() + "'");
-            }
-            inPlaceEditorParams.append("}");
-            sr.append(inPlaceEditorParams.toString());
-        }
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        if (displayField instanceof DisplayEntityField) {
-            makeHyperlinkString(writer, ((DisplayEntityField) displayField).getSubHyperlink(), context);
-        }
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
-        this.request.setAttribute("image", hyperlinkField.getImageLocation(context));
-        ModelFormField modelFormField = hyperlinkField.getModelFormField();
-        String encodedAlternate = encode(hyperlinkField.getAlternate(context), modelFormField, context);
-        String encodedImageTitle = encode(hyperlinkField.getImageTitle(context), modelFormField, context);
-        this.request.setAttribute("alternate", encodedAlternate);
-        this.request.setAttribute("imageTitle", encodedImageTitle);
-        this.request.setAttribute("descriptionSize", hyperlinkField.getSize());
-        makeHyperlinkByType(writer, hyperlinkField.getLinkType(), modelFormField.getWidgetStyle(), hyperlinkField.getUrlMode(), hyperlinkField.getTarget(context), hyperlinkField.getParameterMap(context), hyperlinkField.getDescription(context), hyperlinkField.getTargetWindow(context),
-                hyperlinkField.getConfirmation(context), modelFormField, this.request, this.response, context);
-        this.appendTooltip(writer, context, modelFormField);
-        this.request.removeAttribute("image");
-        this.request.removeAttribute("descriptionSize");
-    }
-
-    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-        String name = modelFormField.getParameterName(context);
-        String className = "";
-        String alert = "false";
-        String mask = "";
-        String placeholder = textField.getPlaceholder(context);
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
-        String textSize = Integer.toString(textField.getSize());
-        String maxlength = "";
-        if (textField.getMaxlength() != null) {
-            maxlength = Integer.toString(textField.getMaxlength());
-        }
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        String id = modelFormField.getCurrentContainerId(context);
-        String clientAutocomplete = "false";
-        //check for required field style on single forms
-        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
-            String requiredStyle = modelFormField.getRequiredFieldStyle();
-            if (UtilValidate.isEmpty(requiredStyle))
-                requiredStyle = "required";
-            if (UtilValidate.isEmpty(className))
-                className = requiredStyle;
-            else
-                className = requiredStyle + " " + className;
-        }
-        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
-        boolean ajaxEnabled = updateAreas != null && this.javaScriptEnabled;
-        if (textField.getClientAutocompleteField() || ajaxEnabled) {
-            clientAutocomplete = "true";
-        }
-        if (UtilValidate.isNotEmpty(textField.getMask())) {
-            mask = textField.getMask();
-        }
-        String ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "", context);
-        boolean disabled = textField.getDisabled();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderTextField ");
-        sr.append("name=\"");
-        sr.append(name);
-        sr.append("\" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" textSize=\"");
-        sr.append(textSize);
-        sr.append("\" maxlength=\"");
-        sr.append(maxlength);
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" event=\"");
-        if (event != null) {
-            sr.append(event);
-        }
-        sr.append("\" action=\"");
-        if (action != null) {
-            sr.append(action);
-        }
-        sr.append("\" disabled=");
-        sr.append(Boolean.toString(disabled));
-        sr.append(" clientAutocomplete=\"");
-        sr.append(clientAutocomplete);
-        sr.append("\" ajaxUrl=\"");
-        sr.append(ajaxUrl);
-        sr.append("\" ajaxEnabled=");
-        sr.append(Boolean.toString(ajaxEnabled));
-        sr.append(" mask=\"");
-        sr.append(mask);
-        sr.append("\" placeholder=\"");
-        sr.append(placeholder);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        ModelFormField.SubHyperlink subHyperlink = textField.getSubHyperlink();
-        if (subHyperlink != null && subHyperlink.shouldUse(context)) {
-            makeHyperlinkString(writer, subHyperlink, context);
-        }
-        this.addAsterisks(writer, context, modelFormField);
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
-        ModelFormField modelFormField = textareaField.getModelFormField();
-        String name = modelFormField.getParameterName(context);
-        String cols = Integer.toString(textareaField.getCols());
-        String rows = Integer.toString(textareaField.getRows());
-        String id = modelFormField.getCurrentContainerId(context);
-        String className = "";
-        String alert = "false";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        //check for required field style on single forms
-        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
-            String requiredStyle = modelFormField.getRequiredFieldStyle();
-            if (UtilValidate.isEmpty(requiredStyle))
-                requiredStyle = "required";
-            if (UtilValidate.isEmpty(className))
-                className = requiredStyle;
-            else
-                className = requiredStyle + " " + className;
-        }
-        String visualEditorEnable = "";
-        String buttons = "";
-        if (textareaField.getVisualEditorEnable()) {
-            visualEditorEnable = "true";
-            buttons = textareaField.getVisualEditorButtons(context);
-            if (UtilValidate.isEmpty(buttons)) {
-                buttons = "maxi";
-            }
-        }
-        String readonly = "";
-        if (textareaField.isReadOnly()) {
-            readonly = "readonly";
-        }
-        Map<String, Object> userLogin = UtilGenerics.checkMap(context.get("userLogin"));
-        String language = "en";
-        if (userLogin != null) {
-            language = UtilValidate.isEmpty((String) userLogin.get("lastLocale")) ? "en" : (String) userLogin.get("lastLocale");
-        }
-        String value = modelFormField.getEntry(context, textareaField.getDefaultValue(context));
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderTextareaField ");
-        sr.append("name=\"");
-        sr.append(name);
-        sr.append("\" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" cols=\"");
-        sr.append(cols);
-        sr.append("\" rows=\"");
-        sr.append(rows);
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" readonly=\"");
-        sr.append(readonly);
-        sr.append("\" visualEditorEnable=\"");
-        sr.append(visualEditorEnable);
-        sr.append("\" language=\"");
-        sr.append(language);
-        sr.append("\" buttons=\"");
-        sr.append(buttons);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.addAsterisks(writer, context, modelFormField);
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
-        ModelFormField modelFormField = dateTimeField.getModelFormField();
-        String paramName = modelFormField.getParameterName(context);
-        String defaultDateTimeString = dateTimeField.getDefaultDateTimeString(context);
-        String className = "";
-        String alert = "false";
-        String name = "";
-        String formattedMask = "";
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        boolean useTimeDropDown = "time-dropdown".equals(dateTimeField.getInputMethod());
-        String stepString = dateTimeField.getStep();
-        int step = 1;
-        StringBuilder timeValues = new StringBuilder();
-        if (useTimeDropDown && UtilValidate.isNotEmpty(step)) {
-            try {
-                step = Integer.valueOf(stepString).intValue();
-            } catch (IllegalArgumentException e) {
-                Debug.logWarning("Inavalid value for step property for field[" + paramName + "] with input-method=\"time-dropdown\" " + " Found Value [" + stepString + "]  " + e.getMessage(), module);
-            }
-            timeValues.append("[");
-            for (int i = 0; i <= 59;) {
-                if (i != 0) {
-                    timeValues.append(", ");
-                }
-                timeValues.append(i);
-                i += step;
-            }
-            timeValues.append("]");
-        }
-        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        }
-        String localizedInputTitle = "", localizedIconTitle = "";
-        // whether the date field is short form, yyyy-mm-dd
-        boolean shortDateInput = ("date".equals(dateTimeField.getType()) || useTimeDropDown ? true : false);
-        if (useTimeDropDown) {
-            name = UtilHttp.makeCompositeParam(paramName, "date");
-        } else {
-            name = paramName;
-        }
-        // the default values for a timestamp
-        int size = 25;
-        int maxlength = 30;
-        if (shortDateInput) {
-            size = maxlength = 10;
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatDate");
-            }
-        } else if ("time".equals(dateTimeField.getType())) {
-            size = maxlength = 8;
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatTime");
-            }
-        } else {
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatDateTime");
-            }
-        }
-        /*
-         * FIXME: Using a builder here is a hack. Replace the builder with appropriate code.
-         */
-        ModelFormFieldBuilder builder = new ModelFormFieldBuilder(modelFormField);
-        boolean memEncodeOutput = modelFormField.getEncodeOutput();
-        if (useTimeDropDown)
-            // If time-dropdown deactivate encodingOutput for found hour and minutes
-            // FIXME: Encoding should be controlled by the renderer, not by the model.
-            builder.setEncodeOutput(false);
-        // FIXME: modelFormField.getEntry ignores shortDateInput when converting Date objects to Strings.
-        if (useTimeDropDown) {
-            builder.setEncodeOutput(memEncodeOutput);
-        }
-        modelFormField = builder.build();
-        String contextValue = modelFormField.getEntry(context, dateTimeField.getDefaultValue(context));
-        String value = contextValue;
-        if (UtilValidate.isNotEmpty(value)) {
-            if (value.length() > maxlength) {
-                value = value.substring(0, maxlength);
-            }
-        }
-        String id = modelFormField.getCurrentContainerId(context);
-        ModelForm modelForm = modelFormField.getModelForm();
-        String formName = FormRenderer.getCurrentFormName(modelForm, context);
-        String timeDropdown = dateTimeField.getInputMethod();
-        String timeDropdownParamName = "";
-        String classString = "";
-        boolean isTwelveHour = false;
-        String timeHourName = "";
-        int hour2 = 0, hour1 = 0, minutes = 0;
-        String timeMinutesName = "";
-        String amSelected = "", pmSelected = "", ampmName = "";
-        String compositeType = "";
-        // search for a localized label for the icon
-        if (uiLabelMap != null) {
-            localizedIconTitle = uiLabelMap.get("CommonViewCalendar");
-        }
-        if (!"time".equals(dateTimeField.getType())) {
-            String tempParamName;
-            if (useTimeDropDown) {
-                tempParamName = UtilHttp.makeCompositeParam(paramName, "date");
-            } else {
-                tempParamName = paramName;
-            }
-            timeDropdownParamName = tempParamName;
-            defaultDateTimeString = UtilHttp.encodeBlanks(modelFormField.getEntry(context, defaultDateTimeString));
-        }
-        // if we have an input method of time-dropdown, then render two
-        // dropdowns
-        if (useTimeDropDown) {
-            className = modelFormField.getWidgetStyle();
-            classString = (className != null ? className : "");
-            isTwelveHour = "12".equals(dateTimeField.getClock());
-            // set the Calendar to the default time of the form or now()
-            Calendar cal = null;
-            try {
-                Timestamp defaultTimestamp = Timestamp.valueOf(contextValue);
-                cal = Calendar.getInstance();
-                cal.setTime(defaultTimestamp);
-            } catch (IllegalArgumentException e) {
-                Debug.logWarning("Form widget field [" + paramName + "] with input-method=\"time-dropdown\" was not able to understand the default time [" + defaultDateTimeString + "]. The parsing error was: " + e.getMessage(), module);
-            }
-            timeHourName = UtilHttp.makeCompositeParam(paramName, "hour");
-            if (cal != null) {
-                int hour = cal.get(Calendar.HOUR_OF_DAY);
-                hour2 = hour;
-                if (hour == 0) {
-                    hour = 12;
-                }
-                if (hour > 12) {
-                    hour -= 12;
-                }
-                hour1 = hour;
-                minutes = cal.get(Calendar.MINUTE);
-            }
-            timeMinutesName = UtilHttp.makeCompositeParam(paramName, "minutes");
-            compositeType = UtilHttp.makeCompositeParam(paramName, "compositeType");
-            // if 12 hour clock, write the AM/PM selector
-            if (isTwelveHour) {
-                amSelected = ((cal != null && cal.get(Calendar.AM_PM) == Calendar.AM) ? "selected" : "");
-                pmSelected = ((cal != null && cal.get(Calendar.AM_PM) == Calendar.PM) ? "selected" : "");
-                ampmName = UtilHttp.makeCompositeParam(paramName, "ampm");
-            }
-        }
-        //check for required field style on single forms
-        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
-            String requiredStyle = modelFormField.getRequiredFieldStyle();
-            if (UtilValidate.isEmpty(requiredStyle))
-                requiredStyle = "required";
-            if (UtilValidate.isEmpty(className))
-                className = requiredStyle;
-            else
-                className = requiredStyle + " " + className;
-        }
-        String mask = dateTimeField.getMask();
-        if ("Y".equals(mask)) {
-            if ("date".equals(dateTimeField.getType())) {
-                formattedMask = "9999-99-99";
-            } else if ("time".equals(dateTimeField.getType())) {
-                formattedMask = "99:99:99";
-            } else if ("timestamp".equals(dateTimeField.getType())) {
-                formattedMask = "9999-99-99 99:99:99";
-            }
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderDateTimeField ");
-        sr.append("name=\"");
-        sr.append(name);
-        sr.append("\" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" title=\"");
-        sr.append(localizedInputTitle);
-        sr.append("\" size=\"");
-        sr.append(Integer.toString(size));
-        sr.append("\" maxlength=\"");
-        sr.append(Integer.toString(maxlength));
-        sr.append("\" step=\"");
-        sr.append(Integer.toString(step));
-        sr.append("\" timeValues=\"");
-        sr.append(timeValues.toString());
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" event=\"");
-        sr.append(event);
-        sr.append("\" action=\"");
-        sr.append(action);
-        sr.append("\" dateType=\"");
-        sr.append(dateTimeField.getType());
-        sr.append("\" shortDateInput=");
-        sr.append(Boolean.toString(shortDateInput));
-        sr.append(" timeDropdownParamName=\"");
-        sr.append(timeDropdownParamName);
-        sr.append("\" defaultDateTimeString=\"");
-        sr.append(defaultDateTimeString);
-        sr.append("\" localizedIconTitle=\"");
-        sr.append(localizedIconTitle);
-        sr.append("\" timeDropdown=\"");
-        sr.append(timeDropdown);
-        sr.append("\" timeHourName=\"");
-        sr.append(timeHourName);
-        sr.append("\" classString=\"");
-        sr.append(classString);
-        sr.append("\" hour1=");
-        sr.append(Integer.toString(hour1));
-        sr.append(" hour2=");
-        sr.append(Integer.toString(hour2));
-        sr.append(" timeMinutesName=\"");
-        sr.append(timeMinutesName);
-        sr.append("\" minutes=");
-        sr.append(Integer.toString(minutes));
-        sr.append(" isTwelveHour=");
-        sr.append(Boolean.toString(isTwelveHour));
-        sr.append(" ampmName=\"");
-        sr.append(ampmName);
-        sr.append("\" amSelected=\"");
-        sr.append(amSelected);
-        sr.append("\" pmSelected=\"");
-        sr.append(pmSelected);
-        sr.append("\" compositeType=\"");
-        sr.append(compositeType);
-        sr.append("\" formName=\"");
-        sr.append(formName);
-        sr.append("\" mask=\"");
-        sr.append(formattedMask);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.addAsterisks(writer, context, modelFormField);
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
-        ModelFormField modelFormField = dropDownField.getModelFormField();
-        ModelForm modelForm = modelFormField.getModelForm();
-        String currentValue = modelFormField.getEntry(context);
-        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-        ModelFormField.AutoComplete autoComplete = dropDownField.getAutoComplete();
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        Integer textSize = Integer.valueOf(0);
-        if (UtilValidate.isNotEmpty(dropDownField.getTextSize())) {
-            try {
-                textSize = Integer.parseInt(dropDownField.getTextSize());
-            } catch (NumberFormatException nfe) {
-                Debug.logError(nfe, "Error reading size of a field fieldName=" + dropDownField.getModelFormField().getFieldName() + " FormName= " + dropDownField.getModelFormField().getModelForm().getName(), module);
-            }
-            if (textSize > 0 && UtilValidate.isNotEmpty(currentValue) && currentValue.length() > textSize) {
-                currentValue = currentValue.substring(0, textSize - 8) + "..." + currentValue.substring(currentValue.length() - 5);
-            }
-        }
-        boolean ajaxEnabled = autoComplete != null && this.javaScriptEnabled;
-        String className = "";
-        String alert = "false";
-        String name = modelFormField.getParameterName(context);
-        String id = modelFormField.getCurrentContainerId(context);
-        String multiple = dropDownField.getAllowMultiple() ? "multiple" : "";
-        String otherFieldName = "";
-        String formName = modelForm.getName();
-        String size = dropDownField.getSize();
-        String dDFCurrent = dropDownField.getCurrent();
-        String firstInList = "";
-        String explicitDescription = "";
-        String allowEmpty = "";
-        StringBuilder options = new StringBuilder();
-        StringBuilder ajaxOptions = new StringBuilder();
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        //check for required field style on single forms
-        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
-            String requiredStyle = modelFormField.getRequiredFieldStyle();
-            if (UtilValidate.isEmpty(requiredStyle))
-                requiredStyle = "required";
-            if (UtilValidate.isEmpty(className))
-                className = requiredStyle;
-            else
-                className = requiredStyle + " " + className;
-        }
-        String currentDescription = null;
-        if (UtilValidate.isNotEmpty(currentValue)) {
-            for (ModelFormField.OptionValue optionValue : allOptionValues) {
-                if (optionValue.getKey().equals(currentValue)) {
-                    currentDescription = optionValue.getDescription();
-                    break;
-                }
-            }
-        }
-        int otherFieldSize = dropDownField.getOtherFieldSize();
-        if (otherFieldSize > 0) {
-            otherFieldName = dropDownField.getParameterNameOther(context);
-        }
-        // if the current value should go first, stick it in
-        if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
-            firstInList = "first-in-list";
-        }
-        explicitDescription = (currentDescription != null ? currentDescription : dropDownField.getCurrentDescription(context));
-        if (UtilValidate.isEmpty(explicitDescription)) {
-            explicitDescription = (FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues));
-        }
-        if (textSize > 0 && UtilValidate.isNotEmpty(explicitDescription) && explicitDescription.length() > textSize) {
-            explicitDescription = explicitDescription.substring(0, textSize - 8) + "..." + explicitDescription.substring(explicitDescription.length() - 5);
-        }
-        explicitDescription = encode(explicitDescription, modelFormField, context);
-        // if allow empty is true, add an empty option
-        if (dropDownField.getAllowEmpty()) {
-            allowEmpty = "Y";
-        }
-        List<String> currentValueList = null;
-        if (UtilValidate.isNotEmpty(currentValue) && dropDownField.getAllowMultiple()) {
-            // If currentValue is Array, it will start with [
-            if (currentValue.startsWith("[")) {
-                currentValueList = StringUtil.toList(currentValue);
-            } else {
-                currentValueList = UtilMisc.toList(currentValue);
-            }
-        }
-        options.append("[");
-        Iterator<ModelFormField.OptionValue> optionValueIter = allOptionValues.iterator();
-        int count = 0;
-        while (optionValueIter.hasNext()) {
-            ModelFormField.OptionValue optionValue = optionValueIter.next();
-            if (options.length() > 1) {
-                options.append(",");
-            }
-            options.append("{'key':'");
-            String key = encode(optionValue.getKey(), modelFormField, context);
-            options.append(key);
-            options.append("'");
-            options.append(",'description':'");
-            String description = optionValue.getDescription();
-            if (textSize > 0 && description.length() > textSize) {
-                description = description.substring(0, textSize - 8) + "..." + description.substring(description.length() - 5);
-            }
-            options.append(encode(description, modelFormField, context));
-
-            if (UtilValidate.isNotEmpty(currentValueList)) {
-                options.append("'");
-                options.append(",'selected':'");
-                if (currentValueList.contains(optionValue.getKey())) {
-                    options.append("selected");
-                } else {
-                    options.append("");
-                }
-            }
-
-            options.append("'}");
-            if (ajaxEnabled) {
-                count++;
-                ajaxOptions.append(optionValue.getKey()).append(": ");
-                ajaxOptions.append(" '").append(optionValue.getDescription()).append("'");
-                if (count != allOptionValues.size()) {
-                    ajaxOptions.append(", ");
-                }
-            }
-        }
-        options.append("]");
-        String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
-        String otherValue = "", fieldName = "";
-        // Adapted from work by Yucca Korpela
-        // http://www.cs.tut.fi/~jkorpela/forms/combo.html
-        if (otherFieldSize > 0) {
-            fieldName = modelFormField.getParameterName(context);
-            Map<String, ? extends Object> dataMap = modelFormField.getMap(context);
-            if (dataMap == null) {
-                dataMap = context;
-            }
-            Object otherValueObj = dataMap.get(otherFieldName);
-            otherValue = (otherValueObj == null) ? "" : otherValueObj.toString();
-        }
-        String frequency = "";
-        String minChars = "";
-        String choices = "";
-        String autoSelect = "";
-        String partialSearch = "";
-        String partialChars = "";
-        String ignoreCase = "";
-        String fullSearch = "";
-        if (ajaxEnabled) {
-            frequency = autoComplete.getFrequency();
-            minChars = autoComplete.getMinChars();
-            choices = autoComplete.getChoices();
-            autoSelect = autoComplete.getAutoSelect();
-            partialSearch = autoComplete.getPartialSearch();
-            partialChars = autoComplete.getPartialChars();
-            ignoreCase = autoComplete.getIgnoreCase();
-            fullSearch = autoComplete.getFullSearch();
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderDropDownField ");
-        sr.append("name=\"");
-        sr.append(name);
-        sr.append("\" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" multiple=\"");
-        sr.append(multiple);
-        sr.append("\" formName=\"");
-        sr.append(formName);
-        sr.append("\" otherFieldName=\"");
-        sr.append(otherFieldName);
-        sr.append("\" event=\"");
-        if (event != null) {
-            sr.append(event);
-        }
-        sr.append("\" action=\"");
-        if (action != null) {
-            sr.append(action);
-        }
-        sr.append("\" size=\"");
-        sr.append(size);
-        sr.append("\" firstInList=\"");
-        sr.append(firstInList);
-        sr.append("\" currentValue=\"");
-        sr.append(currentValue);
-        sr.append("\" explicitDescription=\"");
-        sr.append(explicitDescription);
-        sr.append("\" allowEmpty=\"");
-        sr.append(allowEmpty);
-        sr.append("\" options=");
-        sr.append(options.toString());
-        sr.append(" fieldName=\"");
-        sr.append(fieldName);
-        sr.append("\" otherFieldName=\"");
-        sr.append(otherFieldName);
-        sr.append("\" otherValue=\"");
-        sr.append(otherValue);
-        sr.append("\" otherFieldSize=");
-        sr.append(Integer.toString(otherFieldSize));
-        sr.append(" dDFCurrent=\"");
-        sr.append(dDFCurrent);
-        sr.append("\" ajaxEnabled=");
-        sr.append(Boolean.toString(ajaxEnabled));
-        sr.append(" noCurrentSelectedKey=\"");
-        sr.append(noCurrentSelectedKey);
-        sr.append("\" ajaxOptions=\"");
-        sr.append(ajaxOptions.toString());
-        sr.append("\" frequency=\"");
-        sr.append(frequency);
-        sr.append("\" minChars=\"");
-        sr.append(minChars);
-        sr.append("\" choices=\"");
-        sr.append(choices);
-        sr.append("\" autoSelect=\"");
-        sr.append(autoSelect);
-        sr.append("\" partialSearch=\"");
-        sr.append(partialSearch);
-        sr.append("\" partialChars=\"");
-        sr.append(partialChars);
-        sr.append("\" ignoreCase=\"");
-        sr.append(ignoreCase);
-        sr.append("\" fullSearch=\"");
-        sr.append(fullSearch);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        ModelFormField.SubHyperlink subHyperlink = dropDownField.getSubHyperlink();
-        if (subHyperlink != null && subHyperlink.shouldUse(context)) {
-            makeHyperlinkString(writer, subHyperlink, context);
-        }
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
-        ModelFormField modelFormField = checkField.getModelFormField();
-        modelFormField.getModelForm();
-        String currentValue = modelFormField.getEntry(context);
-        Boolean allChecked = checkField.isAllChecked(context);
-        String id = modelFormField.getCurrentContainerId(context);
-        String className = "";
-        String alert = "false";
-        String name = modelFormField.getParameterName(context);
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        StringBuilder items = new StringBuilder();
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        List<ModelFormField.OptionValue> allOptionValues = checkField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-        items.append("[");
-        for (ModelFormField.OptionValue optionValue : allOptionValues) {
-            if (items.length() > 1) {
-                items.append(",");
-            }
-            items.append("{'value':'");
-            items.append(optionValue.getKey());
-            items.append("', 'description':'" + encode(optionValue.getDescription(), modelFormField, context));
-            items.append("'}");
-        }
-        items.append("]");
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderCheckField ");
-        sr.append("items=");
-        sr.append(items.toString());
-        sr.append(" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" allChecked=");
-        sr.append((allChecked != null ? Boolean.toString(allChecked) : "\"\""));
-        sr.append(" currentValue=\"");
-        sr.append(currentValue);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" event=\"");
-        if (event != null) {
-            sr.append(event);
-        }
-        sr.append("\" action=\"");
-        if (action != null) {
-            sr.append(action);
-        }
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
-        ModelFormField modelFormField = radioField.getModelFormField();
-        modelFormField.getModelForm();
-        List<ModelFormField.OptionValue> allOptionValues = radioField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-        String currentValue = modelFormField.getEntry(context);
-        String className = "";
-        String alert = "false";
-        String name = modelFormField.getParameterName(context);
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        StringBuilder items = new StringBuilder();
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        String noCurrentSelectedKey = radioField.getNoCurrentSelectedKey(context);
-        items.append("[");
-        for (ModelFormField.OptionValue optionValue : allOptionValues) {
-            if (items.length() > 1) {
-                items.append(",");
-            }
-            items.append("{'key':'");
-            items.append(optionValue.getKey());
-            items.append("', 'description':'" + encode(optionValue.getDescription(), modelFormField, context));
-            items.append("'}");
-        }
-        items.append("]");
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderRadioField ");
-        sr.append("items=");
-        sr.append(items.toString());
-        sr.append(" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" currentValue=\"");
-        sr.append(currentValue);
-        sr.append("\" noCurrentSelectedKey=\"");
-        sr.append(noCurrentSelectedKey);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" event=\"");
-        if (event != null) {
-            sr.append(event);
-        }
-        sr.append("\" action=\"");
-        if (action != null) {
-            sr.append(action);
-        }
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
-        ModelFormField modelFormField = submitField.getModelFormField();
-        ModelForm modelForm = modelFormField.getModelForm();
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        String title = modelFormField.getTitle(context);
-        String name = modelFormField.getParameterName(context);
-        String buttonType = submitField.getButtonType();
-        String formName = FormRenderer.getCurrentFormName(modelForm, context);
-        String imgSrc = submitField.getImageLocation(context);
-        String confirmation = submitField.getConfirmation(context);
-        String className = "";
-        String alert = "false";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        String formId = FormRenderer.getCurrentContainerId(modelForm, context);
-        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnSubmitUpdateAreas();
-        // This is here for backwards compatibility. Use on-event-update-area
-        // elements instead.
-        String backgroundSubmitRefreshTarget = submitField.getBackgroundSubmitRefreshTarget(context);
-        if (UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) {
-            if (updateAreas == null) {
-                updateAreas = new LinkedList<ModelForm.UpdateArea>();
-            }
-            updateAreas.add(new ModelForm.UpdateArea("submit", formId, backgroundSubmitRefreshTarget));
-        }
-        boolean ajaxEnabled = (UtilValidate.isNotEmpty(updateAreas) || UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) && this.javaScriptEnabled;
-        String ajaxUrl = "";
-        if (ajaxEnabled) {
-            ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "", context);
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderSubmitField ");
-        sr.append("buttonType=\"");
-        sr.append(buttonType);
-        sr.append("\" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" formName=\"");
-        sr.append(formName);
-        sr.append("\" title=\"");
-        sr.append(encode(title, modelFormField, context));
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" event=\"");
-        if (event != null) {
-            sr.append(event);
-        }
-        sr.append("\" action=\"");
-        if (action != null) {
-            sr.append(action);
-        }
-        sr.append("\" imgSrc=\"");
-        sr.append(imgSrc);
-        sr.append("\" containerId=\"");
-        if (ajaxEnabled) {
-            sr.append(formId);
-        }
-        sr.append("\" confirmation =\"");
-        sr.append(confirmation);
-        sr.append("\" ajaxUrl=\"");
-        if (ajaxEnabled) {
-            sr.append(ajaxUrl);
-        }
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
-        ModelFormField modelFormField = resetField.getModelFormField();
-        String name = modelFormField.getParameterName(context);
-        String className = "";
-        String alert = "false";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        String title = modelFormField.getTitle(context);
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderResetField ");
-        sr.append(" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" title=\"");
-        sr.append(title);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
-        ModelFormField modelFormField = hiddenField.getModelFormField();
-        String value = hiddenField.getValue(context);
-        this.renderHiddenField(writer, context, modelFormField, value);
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
-        String name = modelFormField.getParameterName(context);
-        String action = modelFormField.getAction(context);
-        String event = modelFormField.getEvent();
-        String id = modelFormField.getCurrentContainerId(context);
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderHiddenField ");
-        sr.append(" name=\"");
-        sr.append(name);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" event=\"");
-        if (event != null) {
-            sr.append(event);
-        }
-        sr.append("\" action=\"");
-        if (action != null) {
-            sr.append(action);
-        }
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) {
-        // do nothing, it's an ignored field; could add a comment or something if we wanted to
-    }
-
-    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        String titleText = modelFormField.getTitle(context);
-        String style = modelFormField.getTitleStyle();
-        String id = modelFormField.getCurrentContainerId(context);
-        StringBuilder sb = new StringBuilder();
-        if (UtilValidate.isNotEmpty(titleText)) {
-            if (" ".equals(titleText)) {
-                executeMacro(writer, "<@renderFormatEmptySpace />");
-            } else {
-                titleText = UtilHttp.encodeAmpersands(titleText);
-                titleText = encode(titleText, modelFormField, context);
-                if (UtilValidate.isNotEmpty(modelFormField.getHeaderLink())) {
-                    StringBuilder targetBuffer = new StringBuilder();
-                    FlexibleStringExpander target = FlexibleStringExpander.getInstance(modelFormField.getHeaderLink());
-                    String fullTarget = target.expandString(context);
-                    targetBuffer.append(fullTarget);
-                    String targetType = CommonWidgetModels.Link.DEFAULT_URL_MODE;
-                    if (UtilValidate.isNotEmpty(targetBuffer.toString()) && targetBuffer.toString().toLowerCase().startsWith("javascript:")) {
-                        targetType = "plain";
-                    }
-                    StringWriter sr = new StringWriter();
-                    makeHyperlinkString(sr, modelFormField.getHeaderLinkStyle(), targetType, targetBuffer.toString(), null, titleText, "", modelFormField, this.request, this.response, context, "");
-                    String title = sr.toString().replace("\"", "\'");
-                    sr = new StringWriter();
-                    sr.append("<@renderHyperlinkTitle ");
-                    sr.append(" name=\"");
-                    sr.append(modelFormField.getModelForm().getName());
-                    sr.append("\" title=\"");
-                    sr.append(FreeMarkerWorker.encodeDoubleQuotes(title));
-                    sr.append("\" />");
-                    executeMacro(writer, sr.toString());
-                } else if (modelFormField.isSortField()) {
-                    renderSortField(writer, context, modelFormField, titleText);
-                } else if (modelFormField.isRowSubmit()) {
-                    StringWriter sr = new StringWriter();
-                    sr.append("<@renderHyperlinkTitle ");
-                    sr.append(" name=\"");
-                    sr.append(modelFormField.getModelForm().getName());
-                    sr.append("\" title=\"");
-                    sr.append(titleText);
-                    sr.append("\" showSelectAll=\"Y\"/>");
-                    executeMacro(writer, sr.toString());
-                } else {
-                    sb.append(titleText);
-                }
-            }
-        }
-        if (!sb.toString().isEmpty()) {
-            //check for required field style on single forms
-            if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
-                String requiredStyle = modelFormField.getRequiredFieldStyle();
-                if (UtilValidate.isNotEmpty(requiredStyle)) {
-                    style = requiredStyle;
-                }
-            }
-            StringWriter sr = new StringWriter();
-            sr.append("<@renderFieldTitle ");
-            sr.append(" style=\"");
-            sr.append(style);
-            String displayHelpText = UtilProperties.getPropertyValue("widget.properties", "widget.form.displayhelpText");
-            if ("Y".equals(displayHelpText)) {
-                Delegator delegator = WidgetWorker.getDelegator(context);
-                Locale locale = (Locale) context.get("locale");
-                String entityName = modelFormField.getEntityName();
-                String fieldName = modelFormField.getFieldName();
-                String helpText = UtilHelpText.getEntityFieldDescription(entityName, fieldName, delegator, locale);
-
-                sr.append("\" fieldHelpText=\"");
-                sr.append(FreeMarkerWorker.encodeDoubleQuotes(helpText));
-            }
-            sr.append("\" title=\"");
-            sr.append(sb.toString());
-            if (UtilValidate.isNotEmpty(id)) {
-                sr.append("\" id=\"");
-                sr.append(id);
-                sr.append("_title");
-                // Render "for"
-                sr.append("\" for=\"");
-                sr.append(id);
-            }
-            sr.append("\" />");
-            executeMacro(writer, sr.toString());
-        }
-    }
-
-    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        renderFieldTitle(writer, context, modelFormField);
-    }
-
-    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        renderBeginningBoundaryComment(writer, "Form Widget - Form Element", modelForm);
-        String targetType = modelForm.getTargetType();
-        String targ = modelForm.getTarget(context, targetType);
-        StringBuilder linkUrl = new StringBuilder();
-        if (UtilValidate.isNotEmpty(targ)) {
-            //this.appendOfbizUrl(writer, "/" + targ);
-            WidgetWorker.buildHyperlinkUrl(linkUrl, targ, targetType, null, null, false, false, true, request, response, context);
-        }
-        String formType = modelForm.getType();
-        String targetWindow = modelForm.getTargetWindow(context);
-        String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
-        String containerStyle = modelForm.getContainerStyle();
-        String autocomplete = "";
-        String name = FormRenderer.getCurrentFormName(modelForm, context);
-        String viewIndexField = modelForm.getMultiPaginateIndexField(context);
-        String viewSizeField = modelForm.getMultiPaginateSizeField(context);
-        int viewIndex = Paginator.getViewIndex(modelForm, context);
-        int viewSize = Paginator.getViewSize(modelForm, context);
-        boolean useRowSubmit = modelForm.getUseRowSubmit();
-        if (!modelForm.getClientAutocompleteFields()) {
-            autocomplete = "off";
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormOpen ");
-        sr.append(" linkUrl=\"");
-        sr.append(linkUrl);
-        sr.append("\" formType=\"");
-        sr.append(formType);
-        sr.append("\" targetWindow=\"");
-        sr.append(targetWindow);
-        sr.append("\" containerId=\"");
-        sr.append(containerId);
-        sr.append("\" containerStyle=\"");
-        sr.append(containerStyle);
-        sr.append("\" autocomplete=\"");
-        sr.append(autocomplete);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" viewIndexField=\"");
-        sr.append(viewIndexField);
-        sr.append("\" viewSizeField=\"");
-        sr.append(viewSizeField);
-        sr.append("\" viewIndex=\"");
-        sr.append(Integer.toString(viewIndex));
-        sr.append("\" viewSize=\"");
-        sr.append(Integer.toString(viewSize));
-        sr.append("\" useRowSubmit=");
-        sr.append(Boolean.toString(useRowSubmit));
-        sr.append(" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        String focusFieldName = FormRenderer.getFocusFieldName(modelForm, context);
-        String formName = FormRenderer.getCurrentFormName(modelForm, context);
-        String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
-        String hasRequiredField = "";
-        for (ModelFormField formField : modelForm.getFieldList()) {
-            if (formField.getRequiredField()) {
-                hasRequiredField = "Y";
-                break;
-            }
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormClose ");
-        sr.append(" focusFieldName=\"");
-        sr.append(focusFieldName);
-        sr.append("\" formName=\"");
-        sr.append(formName);
-        sr.append("\" containerId=\"");
-        sr.append(containerId);
-        sr.append("\" hasRequiredField=\"");
-        sr.append(hasRequiredField);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
-    }
-
-    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        //FIXME copy from HtmlFormRenderer.java (except for the closing form tag itself, that is now converted)
-        Iterator<ModelFormField> submitFields = modelForm.getMultiSubmitFields().iterator();
-        while (submitFields.hasNext()) {
-            ModelFormField submitField = submitFields.next();
-            if (submitField != null && submitField.shouldUse(context)) {
-                // Threw this in that as a hack to keep the submit button from expanding the first field
-                // Needs a more rugged solution
-                // WARNING: this method (renderMultiFormClose) must be called after the
-                // table that contains the list has been closed (to avoid validation errors) so
-                // we cannot call here the methods renderFormatItemRowCell*: for this reason
-                // they are now commented.
-                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
-                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);
-                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
-                submitField.renderFieldString(writer, context, this);
-                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);
-            }
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderMultiFormClose />");
-        executeMacro(writer, sr.toString());
-        // see if there is anything that needs to be added outside of the multi-form
-        Map<String, Object> wholeFormContext = UtilGenerics.checkMap(context.get("wholeFormContext"));
-        Appendable postMultiFormWriter = wholeFormContext != null ? (Appendable) wholeFormContext.get("postMultiFormWriter") : null;
-        if (postMultiFormWriter != null) {
-            writer.append(postMultiFormWriter.toString());
-            appendWhitespace(writer);
-        }
-        renderEndingBoundaryComment(writer, "Form Widget - Form Element (Multi)", modelForm);
-    }
-
-    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters"));
-        Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap"));
-        if (UtilValidate.isNotEmpty(queryStringMap)) {
-            inputFields.putAll(queryStringMap);
-        }
-        if (modelForm.getType().equals("multi")) {
-            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
-        }
-        String queryString = UtilHttp.urlEncodeArgs(inputFields);
-        context.put("_QBESTRING_", queryString);
-        renderBeginningBoundaryComment(writer, "Form Widget", modelForm);
-        if (this.renderPagination) {
-            this.renderNextPrev(writer, context, modelForm);
-        }
-        List<ModelFormField> childFieldList = modelForm.getFieldList();
-        List<String> columnStyleList = new LinkedList<String>();
-        List<String> fieldNameList = new LinkedList<String>();
-        for (ModelFormField childField : childFieldList) {
-            int childFieldType = childField.getFieldInfo().getFieldType();
-            if (childFieldType == FieldInfo.HIDDEN || childFieldType == FieldInfo.IGNORED) {
-                continue;
-            }
-            String areaStyle = childField.getTitleAreaStyle();
-            if (UtilValidate.isEmpty(areaStyle)) {
-                areaStyle = "";
-            }
-            if (fieldNameList.contains(childField.getName())) {
-                if (UtilValidate.isNotEmpty(areaStyle)) {
-                    columnStyleList.set(fieldNameList.indexOf(childField.getName()), areaStyle);
-                }
-            } else {
-                columnStyleList.add(areaStyle);
-                fieldNameList.add(childField.getName());
-            }
-        }
-        columnStyleList = StringUtil.quoteStrList(columnStyleList);
-        String columnStyleListString = StringUtil.join(columnStyleList, ", ");
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatListWrapperOpen ");
-        sr.append(" formName=\"");
-        sr.append(modelForm.getName());
-        sr.append("\" style=\"");
-        sr.append(FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context));
-        sr.append("\" columnStyles=[");
-        if (UtilValidate.isNotEmpty(columnStyleListString)) {
-            // this is a fix for forms with no fields
-            sr.append(columnStyleListString);
-        }
-        sr.append("] />");
-        executeMacro(writer, sr.toString());
-
-    }
-
-    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatListWrapperClose");
-        sr.append(" formName=\"");
-        sr.append(modelForm.getName());
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        if (this.renderPagination) {
-            this.renderNextPrev(writer, context, modelForm);
-        }
-        renderEndingBoundaryComment(writer, "Form Widget - Formal List Wrapper", modelForm);
-    }
-
-    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        String headerStyle = FlexibleStringExpander.expandString(modelForm.getHeaderRowStyle(), context);
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatHeaderRowOpen ");
-        sr.append(" style=\"");
-        sr.append(headerStyle);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatHeaderRowClose />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
-        String areaStyle = modelFormField.getTitleAreaStyle();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatHeaderRowCellOpen ");
-        sr.append(" style=\"");
-        sr.append(areaStyle);
-        sr.append("\" positionSpan=");
-        sr.append(Integer.toString(positionSpan));
-        sr.append(" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatHeaderRowCellClose />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        String areaStyle = modelForm.getFormTitleAreaStyle();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatHeaderRowFormCellOpen ");
-        sr.append(" style=\"");
-        sr.append(areaStyle);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatHeaderRowFormCellClose />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {
-        String titleStyle = modelFormField.getTitleStyle();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatHeaderRowFormCellTitleSeparator ");
-        sr.append(" style=\"");
-        sr.append(titleStyle);
-        sr.append("\" isLast=");
-        sr.append(Boolean.toString(isLast));
-        sr.append(" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        Integer itemIndex = (Integer) context.get("itemIndex");
-        String altRowStyles = "";
-        String evenRowStyle = "";
-        String oddRowStyle = "";
-        if (itemIndex != null) {
-            altRowStyles = modelForm.getStyleAltRowStyle(context);
-            if (itemIndex.intValue() % 2 == 0) {
-                evenRowStyle = modelForm.getEvenRowStyle();
-            } else {
-                oddRowStyle = FlexibleStringExpander.expandString(modelForm.getOddRowStyle(), context);
-            }
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatItemRowOpen ");
-        sr.append(" formName=\"");
-        sr.append(modelForm.getName());
-        sr.append("\" itemIndex=");
-        sr.append(Integer.toString(itemIndex));
-        sr.append(" altRowStyles=\"");
-        sr.append(altRowStyles);
-        sr.append("\" evenRowStyle=\"");
-        sr.append(evenRowStyle);
-        sr.append("\" oddRowStyle=\"");
-        sr.append(oddRowStyle);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatItemRowClose ");
-        sr.append(" formName=\"");
-        sr.append(modelForm.getName());
-        sr.append("\"/>");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
-        String areaStyle = modelFormField.getWidgetAreaStyle();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatItemRowCellOpen ");
-        sr.append(" fieldName=\"");
-        sr.append(modelFormField.getName());
-        sr.append("\" style=\"");
-        sr.append(areaStyle);
-        sr.append("\" positionSpan=");
-        sr.append(Integer.toString(positionSpan));
-        sr.append(" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatItemRowCellClose");
-        sr.append(" fieldName=\"");
-        sr.append(modelFormField.getName());
-        sr.append("\"/>");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        String areaStyle = modelForm.getFormTitleAreaStyle();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatItemRowFormCellOpen ");
-        sr.append(" style=\"");
-        sr.append(areaStyle);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatItemRowFormCellClose />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        String style = FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context);
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatSingleWrapperOpen ");
-        sr.append(" formName=\"");
-        sr.append(modelForm.getName());
-        sr.append("\" style=\"");
-        sr.append(style);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatSingleWrapperClose");
-        sr.append(" formName=\"");
-        sr.append(modelForm.getName());
-        sr.append("\"/>");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatFieldRowOpen />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatFieldRowClose />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        String style = modelFormField.getTitleAreaStyle();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatFieldRowTitleCellOpen ");
-        sr.append(" style=\"");
-        sr.append(style);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatFieldRowTitleCellClose />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-    }
-
-    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
-        String areaStyle = modelFormField.getWidgetAreaStyle();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatFieldRowWidgetCellOpen ");
-        sr.append(" positionSpan=");
-        sr.append(Integer.toString(positionSpan));
-        sr.append(" style=\"");
-        sr.append(areaStyle);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatFieldRowWidgetCellClose />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFormatEmptySpace />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
-        ModelFormField modelFormField = textFindField.getModelFormField();
-        String defaultOption = textFindField.getDefaultOption();
-        String className = "";
-        String alert = "false";
-        String opEquals = "";
-        String opBeginsWith = "";
-        String opContains = "";
-        String opIsEmpty = "";
-        String opNotEqual = "";
-        String name = modelFormField.getParameterName(context);
-        String size = Integer.toString(textFindField.getSize());
-        String maxlength = "";
-        String autocomplete = "";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        Locale locale = (Locale) context.get("locale");
-        if (!textFindField.getHideOptions()) {
-            opEquals = UtilProperties.getMessage("conditional", "equals", locale);
-            opBeginsWith = UtilProperties.getMessage("conditional", "begins_with", locale);
-            opContains = UtilProperties.getMessage("conditional", "contains", locale);
-            opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
-            opNotEqual = UtilProperties.getMessage("conditional", "not_equal", locale);
-        }
-        String value = modelFormField.getEntry(context, textFindField.getDefaultValue(context));
-        if (value == null) {
-            value = "";
-        }
-        if (textFindField.getMaxlength() != null) {
-            maxlength = textFindField.getMaxlength().toString();
-        }
-        if (!textFindField.getClientAutocompleteField()) {
-            autocomplete = "off";
-        }
-        String titleStyle = "";
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            titleStyle = modelFormField.getTitleStyle();
-        }
-        String ignoreCase = UtilProperties.getMessage("conditional", "ignore_case", locale);
-        boolean ignCase = textFindField.getIgnoreCase();
-        boolean hideIgnoreCase = textFindField.getHideIgnoreCase();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderTextFindField ");
-        sr.append(" name=\"");
-        sr.append(name);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" defaultOption=\"");
-        sr.append(defaultOption);
-        sr.append("\" opEquals=\"");
-        sr.append(opEquals);
-        sr.append("\" opBeginsWith=\"");
-        sr.append(opBeginsWith);
-        sr.append("\" opContains=\"");
-        sr.append(opContains);
-        sr.append("\" opIsEmpty=\"");
-        sr.append(opIsEmpty);
-        sr.append("\" opNotEqual=\"");
-        sr.append(opNotEqual);
-        sr.append("\" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" size=\"");
-        sr.append(size);
-        sr.append("\" maxlength=\"");
-        sr.append(maxlength);
-        sr.append("\" autocomplete=\"");
-        sr.append(autocomplete);
-        sr.append("\" titleStyle=\"");
-        sr.append(titleStyle);
-        sr.append("\" hideIgnoreCase=");
-        sr.append(Boolean.toString(hideIgnoreCase));
-        sr.append(" ignCase=");
-        sr.append(Boolean.toString(ignCase));
-        sr.append(" ignoreCase=\"");
-        sr.append(ignoreCase);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
-        ModelFormField modelFormField = rangeFindField.getModelFormField();
-        Locale locale = (Locale) context.get("locale");
-        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
-        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
-        String opGreaterThanEquals = UtilProperties.getMessage("conditional", "greater_than_equals", locale);
-        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
-        String opLessThanEquals = UtilProperties.getMessage("conditional", "less_than_equals", locale);
-        //String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
-        String className = "";
-        String alert = "false";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        String name = modelFormField.getParameterName(context);
-        String size = Integer.toString(rangeFindField.getSize());
-        String value = modelFormField.getEntry(context, rangeFindField.getDefaultValue(context));
-        if (value == null) {
-            value = "";
-        }
-        Integer maxlength = rangeFindField.getMaxlength();
-        String autocomplete = "";
-
-        if (!rangeFindField.getClientAutocompleteField()) {
-            autocomplete = "off";
-        }
-        String titleStyle = modelFormField.getTitleStyle();
-
-        if (titleStyle == null) {
-            titleStyle = "";
-        }
-        String defaultOptionFrom = rangeFindField.getDefaultOptionFrom();
-        String value2 = modelFormField.getEntry(context);
-        if (value2 == null) {
-            value2 = "";
-        }
-        String defaultOptionThru = rangeFindField.getDefaultOptionThru();
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderRangeFindField ");
-        sr.append(" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" size=\"");
-        sr.append(size);
-        sr.append("\" maxlength=\"");
-        if (maxlength != null) {
-            sr.append(Integer.toString(maxlength));
-        }
-        sr.append("\" autocomplete=\"");
-        sr.append(autocomplete);
-        sr.append("\" titleStyle=\"");
-        sr.append(titleStyle);
-        sr.append("\" defaultOptionFrom=\"");
-        sr.append(defaultOptionFrom);
-        sr.append("\" opEquals=\"");
-        sr.append(opEquals);
-        sr.append("\" opGreaterThan=\"");
-        sr.append(opGreaterThan);
-        sr.append("\" opGreaterThanEquals=\"");
-        sr.append(opGreaterThanEquals);
-        sr.append("\" opLessThan=\"");
-        sr.append(opLessThan);
-        sr.append("\" opLessThanEquals=\"");
-        sr.append(opLessThanEquals);
-        sr.append("\" value2=\"");
-        sr.append(value2);
-        sr.append("\" defaultOptionThru=\"");
-        sr.append(defaultOptionThru);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
-        ModelFormField modelFormField = dateFindField.getModelFormField();
-        Locale locale = (Locale) context.get("locale");
-        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
-        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
-        String opSameDay = UtilProperties.getMessage("conditional", "same_day", locale);
-        String opGreaterThanFromDayStart = UtilProperties.getMessage("conditional", "greater_than_from_day_start", locale);
-        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
-        String opUpToDay = UtilProperties.getMessage("conditional", "up_to_day", locale);
-        String opUpThruDay = UtilProperties.getMessage("conditional", "up_thru_day", locale);
-        String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
-        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        }
-        String localizedInputTitle = "", localizedIconTitle = "";
-        String className = "";
-        String alert = "false";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        String name = modelFormField.getParameterName(context);
-        // the default values for a timestamp
-        int size = 25;
-        int maxlength = 30;
-        String dateType = dateFindField.getType();
-        if ("date".equals(dateType)) {
-            size = maxlength = 10;
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatDate");
-            }
-        } else if ("time".equals(dateFindField.getType())) {
-            size = maxlength = 8;
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatTime");
-            }
-        } else {
-            if (uiLabelMap != null) {
-                localizedInputTitle = uiLabelMap.get("CommonFormatDateTime");
-            }
-        }
-        String value = modelFormField.getEntry(context, dateFindField.getDefaultValue(context));
-        if (value == null) {
-            value = "";
-        }
-        // search for a localized label for the icon
-        if (uiLabelMap != null) {
-            localizedIconTitle = uiLabelMap.get("CommonViewCalendar");
-        }
-        String formName = "";
-        String defaultDateTimeString = "";
-        StringBuilder imgSrc = new StringBuilder();
-        // add calendar pop-up button and seed data IF this is not a "time" type date-find
-        if (!"time".equals(dateFindField.getType())) {
-            ModelForm modelForm = modelFormField.getModelForm();
-            formName = FormRenderer.getCurrentFormName(modelForm, context);
-            defaultDateTimeString = UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context)));
-            this.appendContentUrl(imgSrc, "/images/cal.gif");
-        }
-        String defaultOptionFrom = dateFindField.getDefaultOptionFrom();
-        String defaultOptionThru = dateFindField.getDefaultOptionThru();
-        String value2 = modelFormField.getEntry(context);
-        if (value2 == null) {
-            value2 = "";
-        }
-        String titleStyle = "";
-        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
-            titleStyle = modelFormField.getTitleStyle();
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderDateFindField ");
-        sr.append(" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" localizedInputTitle=\"");
-        sr.append(localizedInputTitle);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" size=\"");
-        sr.append(Integer.toString(size));
-        sr.append("\" maxlength=\"");
-        sr.append(Integer.toString(maxlength));
-        sr.append("\" dateType=\"");
-        sr.append(dateType);
-        sr.append("\" formName=\"");
-        sr.append(formName);
-        sr.append("\" defaultDateTimeString=\"");
-        sr.append(defaultDateTimeString);
-        sr.append("\" imgSrc=\"");
-        sr.append(imgSrc.toString());
-        sr.append("\" localizedIconTitle=\"");
-        sr.append(localizedIconTitle);
-        sr.append("\" titleStyle=\"");
-        sr.append(titleStyle);
-        sr.append("\" defaultOptionFrom=\"");
-        sr.append(defaultOptionFrom);
-        sr.append("\" defaultOptionThru=\"");
-        sr.append(defaultOptionThru);
-        sr.append("\" opEquals=\"");
-        sr.append(opEquals);
-        sr.append("\" opSameDay=\"");
-        sr.append(opSameDay);
-        sr.append("\" opGreaterThanFromDayStart=\"");
-        sr.append(opGreaterThanFromDayStart);
-        sr.append("\" opGreaterThan=\"");
-        sr.append(opGreaterThan);
-        sr.append("\" opGreaterThan=\"");
-        sr.append(opGreaterThan);
-        sr.append("\" opLessThan=\"");
-        sr.append(opLessThan);
-        sr.append("\" opUpToDay=\"");
-        sr.append(opUpToDay);
-        sr.append("\" opUpThruDay=\"");
-        sr.append(opUpThruDay);
-        sr.append("\" opIsEmpty=\"");
-        sr.append(opIsEmpty);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
-        ModelFormField modelFormField = lookupField.getModelFormField();
-        String lookupFieldFormName = lookupField.getFormName(context);
-        String className = "";
-        String alert = "false";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        //check for required field style on single forms
-        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
-            String requiredStyle = modelFormField.getRequiredFieldStyle();
-            if (UtilValidate.isEmpty(requiredStyle))
-                requiredStyle = "required";
-            if (UtilValidate.isEmpty(className))
-                className = requiredStyle;
-            else
-                className = requiredStyle + " " + className;
-        }
-        String name = modelFormField.getParameterName(context);
-        String value = modelFormField.getEntry(context, lookupField.getDefaultValue(context));
-        if (value == null) {
-            value = "";
-        }
-        String size = Integer.toString(lookupField.getSize());
-        Integer maxlength = lookupField.getMaxlength();
-        String id = modelFormField.getCurrentContainerId(context);
-        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
-        //add default ajax auto completer to all lookup fields
-        if (UtilValidate.isEmpty(updateAreas) && UtilValidate.isNotEmpty(lookupFieldFormName)) {
-            String autoCompleterTarget = null;
-            if (lookupFieldFormName.indexOf('?') == -1) {
-                autoCompleterTarget = lookupFieldFormName + "?";
-            } else {
-                autoCompleterTarget = lookupFieldFormName + "&amp;amp;";
-            }
-            autoCompleterTarget = autoCompleterTarget + "ajaxLookup=Y";
-            updateAreas = new LinkedList<ModelForm.UpdateArea>();
-            updateAreas.add(new ModelForm.UpdateArea("change", id, autoCompleterTarget));
-        }
-        boolean ajaxEnabled = UtilValidate.isNotEmpty(updateAreas) && this.javaScriptEnabled;
-        String autocomplete = "";
-        if (!lookupField.getClientAutocompleteField() || !ajaxEnabled) {
-            autocomplete = "off";
-        }
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        boolean readonly = lookupField.getReadonly();
-        // add lookup pop-up button
-        String descriptionFieldName = lookupField.getDescriptionFieldName();
-        ModelForm modelForm = modelFormField.getModelForm();
-        String formName = FormRenderer.getCurrentFormName(modelForm, context);
-        StringBuilder targetParameterIter = new StringBuilder();
-        StringBuilder imgSrc = new StringBuilder();
-        // FIXME: refactor using the StringUtils methods
-        List<String> targetParameterList = lookupField.getTargetParameterList();
-        targetParameterIter.append("[");
-        for (String targetParameter : targetParameterList) {
-            if (targetParameterIter.length() > 1) {
-                targetParameterIter.append(",");
-            }
-            targetParameterIter.append("'");
-            targetParameterIter.append(targetParameter);
-            targetParameterIter.append("'");
-        }
-        targetParameterIter.append("]");
-        this.appendContentUrl(imgSrc, "/images/fieldlookup.gif");
-        String ajaxUrl = "";
-        if (ajaxEnabled) {
-            ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "", context);
-        }
-        String lookupPresentation = lookupField.getLookupPresentation();
-        if (UtilValidate.isEmpty(lookupPresentation)) {
-            lookupPresentation = "";
-        }
-        String lookupHeight = lookupField.getLookupHeight();
-        if (UtilValidate.isEmpty(lookupHeight)) {
-            lookupHeight = "";
-        }
-        String lookupWidth = lookupField.getLookupWidth();
-        if (UtilValidate.isEmpty(lookupWidth)) {
-            lookupWidth = "";
-        }
-        String lookupPosition = lookupField.getLookupPosition();
-        if (UtilValidate.isEmpty(lookupPosition)) {
-            lookupPosition = "";
-        }
-        String fadeBackground = lookupField.getFadeBackground();
-        if (UtilValidate.isEmpty(fadeBackground)) {
-            fadeBackground = "false";
-        }
-        Boolean isInitiallyCollapsed = lookupField.getInitiallyCollapsed();
-        String clearText = "";
-        Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-        if (uiLabelMap != null) {
-            clearText = (String) uiLabelMap.get("CommonClear");
-        } else {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        }
-        Boolean showDescription = lookupField.getShowDescription();
-        if (showDescription == null) {
-            showDescription = "Y".equals(UtilProperties.getPropertyValue("widget", "widget.lookup.showDescription", "Y"));
-        }
-        // lastViewName, used by lookup to remember the real last view name
-        String lastViewName = request.getParameter("_LAST_VIEW_NAME_"); // Try to get it from parameters firstly
-        if (UtilValidate.isEmpty(lastViewName)) { // get from session
-            lastViewName = (String) request.getSession().getAttribute("_LAST_VIEW_NAME_");
-        }
-        if (UtilValidate.isEmpty(lastViewName)) {
-            lastViewName = "";
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderLookupField ");
-        sr.append(" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" size=\"");
-        sr.append(size);
-        sr.append("\" maxlength=\"");
-        sr.append((maxlength != null ? Integer.toString(maxlength) : ""));
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" event=\"");
-        if (event != null) {
-            sr.append(event);
-        }
-        sr.append("\" action=\"");
-        if (action != null) {
-            sr.append(action);
-        }
-        sr.append("\" readonly=");
-        sr.append(Boolean.toString(readonly));
-        sr.append(" autocomplete=\"");
-        sr.append(autocomplete);
-        sr.append("\" descriptionFieldName=\"");
-        sr.append(descriptionFieldName);
-        sr.append("\" formName=\"");
-        sr.append(formName);
-        sr.append("\" fieldFormName=\"");
-        sr.append(lookupFieldFormName);
-        sr.append("\" targetParameterIter=");
-        sr.append(targetParameterIter.toString());
-        sr.append(" imgSrc=\"");
-        sr.append(imgSrc.toString());
-        sr.append("\" ajaxUrl=\"");
-        sr.append(ajaxUrl);
-        sr.append("\" ajaxEnabled=");
-        sr.append(Boolean.toString(ajaxEnabled));
-        sr.append(" presentation=\"");
-        sr.append(lookupPresentation);
-        sr.append("\" height=\"");
-        sr.append(lookupHeight);
-        sr.append("\" width=\"");
-        sr.append(lookupWidth);
-        sr.append("\" position=\"");
-        sr.append(lookupPosition);
-        sr.append("\" fadeBackground=\"");
-        sr.append(fadeBackground);
-        sr.append("\" clearText=\"");
-        sr.append(clearText);
-        sr.append("\" showDescription=\"");
-        sr.append(Boolean.toString(showDescription));
-        sr.append("\" initiallyCollapsed=\"");
-        sr.append(Boolean.toString(isInitiallyCollapsed));
-        sr.append("\" lastViewName=\"");
-        sr.append(lastViewName);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.addAsterisks(writer, context, modelFormField);
-        this.makeHyperlinkString(writer, lookupField.getSubHyperlink(), context);
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    protected String appendExternalLoginKey(String target) {
-        String result = target;
-        String sessionId = ";jsessionid=" + request.getSession().getId();
-        int questionIndex = target.indexOf("?");
-        if (questionIndex == -1) {
-            result += sessionId;
-        } else {
-            result = result.replace("?", sessionId + "?");
-        }
-        return result;
-    }
-
-    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        boolean ajaxEnabled = false;
-        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnPaginateUpdateAreas();
-        String targetService = modelForm.getPaginateTarget(context);
-        if (this.javaScriptEnabled) {
-            if (UtilValidate.isNotEmpty(updateAreas)) {
-                ajaxEnabled = true;
-            }
-        }
-        if (targetService == null) {
-            targetService = "${targetService}";
-        }
-        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
-            Debug.logWarning("Cannot paginate because TargetService is empty for the form: " + modelForm.getName(), module);
-            return;
-        }
-        // get the parameterized pagination index and size fields
-        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
-        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
-        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
-        int viewIndex = Paginator.getViewIndex(modelForm, context);
-        int viewSize = Paginator.getViewSize(modelForm, context);
-        int listSize = Paginator.getListSize(context);
-        int lowIndex = Paginator.getLowIndex(context);
-        int highIndex = Paginator.getHighIndex(context);
-        int actualPageSize = Paginator.getActualPageSize(context);
-        // needed for the "Page" and "rows" labels
-        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-        String pageLabel = "";
-        String commonDisplaying = "";
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        } else {
-            pageLabel = uiLabelMap.get("CommonPage");
-            Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize));
-            commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale"));
-        }
-        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
-        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber))
-            viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
-        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber))
-            viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;
-        String str = (String) context.get("_QBESTRING_");
-        // strip legacy viewIndex/viewSize params from the query string
-        String queryString = UtilHttp.stripViewParamsFromQueryString(str, "" + paginatorNumber);
-        // strip parameterized index/size params from the query string
-        HashSet<String> paramNames = new HashSet<String>();
-        paramNames.add(viewIndexParam);
-        paramNames.add(viewSizeParam);
-        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);
-        String anchor = "";
-        String paginateAnchor = modelForm.getPaginateTargetAnchor();
-        if (UtilValidate.isNotEmpty(paginateAnchor))
-            anchor = "#" + paginateAnchor;
-        // Create separate url path String and request parameters String,
-        // add viewIndex/viewSize parameters to request parameter String
-        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
-        String prepLinkText = UtilHttp.getQueryStringFromTarget(targetService);
-        String prepLinkSizeText;
-        if (UtilValidate.isNotEmpty(queryString)) {
-            queryString = UtilHttp.encodeAmpersands(queryString);
-        }
-        if (prepLinkText == null) {
-            prepLinkText = "";
-        }
-        if (prepLinkText.indexOf("?") < 0) {
-            prepLinkText += "?";
-        } else if (!prepLinkText.endsWith("?")) {
-            prepLinkText += "&amp;";
-        }
-        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
-            prepLinkText += queryString + "&amp;";
-        }
-        prepLinkSizeText = prepLinkText + viewSizeParam + "='+this.value+'" + "&amp;" + viewIndexParam + "=0";
-        prepLinkText += viewSizeParam + "=" + viewSize + "&amp;" + viewIndexParam + "=";
-        if (ajaxEnabled) {
-            // Prepare params for prototype.js
-            prepLinkText = prepLinkText.replace("?", "");
-            prepLinkText = prepLinkText.replace("&amp;", "&");
-        }
-        String linkText;
-        String paginateStyle = modelForm.getPaginateStyle();
-        String paginateFirstStyle = modelForm.getPaginateFirstStyle();
-        String paginateFirstLabel = modelForm.getPaginateFirstLabel(context);
-        String firstUrl = "";
-        String ajaxFirstUrl = "";
-        String paginatePreviousStyle = modelForm.getPaginatePreviousStyle();
-        String paginatePreviousLabel = modelForm.getPaginatePreviousLabel(context);
-        String previousUrl = "";
-        String ajaxPreviousUrl = "";
-        String selectUrl = "";
-        String ajaxSelectUrl = "";
-        String paginateViewSizeLabel = modelForm.getPaginateViewSizeLabel(context);
-        String selectSizeUrl = "";
-        String ajaxSelectSizeUrl = "";
-        String paginateNextStyle = modelForm.getPaginateNextStyle();
-        String paginateNextLabel = modelForm.getPaginateNextLabel(context);
-        String nextUrl = "";
-        String ajaxNextUrl = "";
-        String paginateLastStyle = modelForm.getPaginateLastStyle();
-        String paginateLastLabel = modelForm.getPaginateLastLabel(context);
-        String lastUrl = "";
-        String ajaxLastUrl = "";
-        if (viewIndex > 0) {
-            if (ajaxEnabled) {
-                ajaxFirstUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + 0 + anchor, context);
-            } else {
-                linkText = prepLinkText + 0 + anchor;
-                firstUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
-            }
-        }
-        if (viewIndex > 0) {
-            if (ajaxEnabled) {
-                ajaxPreviousUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex - 1) + anchor, context);
-            } else {
-                linkText = prepLinkText + (viewIndex - 1) + anchor;
-                previousUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
-            }
-        }
-        // Page select dropdown
-        if (listSize > 0 && this.javaScriptEnabled) {
-            if (ajaxEnabled) {
-                ajaxSelectUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + "' + this.value + '", context);
-            } else {
-                linkText = prepLinkText;
-                if (linkText.startsWith("/")) {
-                    linkText = linkText.substring(1);
-                }
-                selectUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
-            }
-        }
-        // Next button
-        if (highIndex < listSize) {
-            if (ajaxEnabled) {
-                ajaxNextUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex + 1) + anchor, context);
-            } else {
-                linkText = prepLinkText + (viewIndex + 1) + anchor;
-                nextUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
-            }
-        }
-        // Last button
-        if (highIndex < listSize) {
-            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
-            if (ajaxEnabled) {
-                ajaxLastUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + lastIndex + anchor, context);
-            } else {
-                linkText = prepLinkText + lastIndex + anchor;
-                lastUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
-            }
-        }
-        // Page size select dropdown
-        if (listSize > 0 && this.javaScriptEnabled) {
-            if (ajaxEnabled) {
-                ajaxSelectSizeUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkSizeText + anchor, context);
-            } else {
-                linkText = prepLinkSizeText;
-                if (linkText.startsWith("/")) {
-                    linkText = linkText.substring(1);
-                }
-                selectSizeUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
-            }
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderNextPrev ");
-        sr.append(" paginateStyle=\"");
-        sr.append(paginateStyle);
-        sr.append("\" paginateFirstStyle=\"");
-        sr.append(paginateFirstStyle);
-        sr.append("\" viewIndex=");
-        sr.append(Integer.toString(viewIndex));
-        sr.append(" highIndex=");
-        sr.append(Integer.toString(highIndex));
-        sr.append(" listSize=");
-        sr.append(Integer.toString(listSize));
-        sr.append(" viewSize=");
-        sr.append(Integer.toString(viewSize));
-        sr.append(" ajaxEnabled=");
-        sr.append(Boolean.toString(ajaxEnabled));
-        sr.append(" javaScriptEnabled=");
-        sr.append(Boolean.toString(javaScriptEnabled));
-        sr.append(" ajaxFirstUrl=\"");
-        sr.append(ajaxFirstUrl);
-        sr.append("\" ajaxFirstUrl=\"");
-        sr.append(ajaxFirstUrl);
-        sr.append("\" ajaxFirstUrl=\"");
-        sr.append(ajaxFirstUrl);
-        sr.append("\" firstUrl=\"");
-        sr.append(firstUrl);
-        sr.append("\" paginateFirstLabel=\"");
-        sr.append(paginateFirstLabel);
-        sr.append("\" paginatePreviousStyle=\"");
-        sr.append(paginatePreviousStyle);
-        sr.append("\" ajaxPreviousUrl=\"");
-        sr.append(ajaxPreviousUrl);
-        sr.append("\" previousUrl=\"");
-        sr.append(previousUrl);
-        sr.append("\" paginatePreviousLabel=\"");
-        sr.append(paginatePreviousLabel);
-        sr.append("\" pageLabel=\"");
-        sr.append(pageLabel);
-        sr.append("\" ajaxSelectUrl=\"");
-        sr.append(ajaxSelectUrl);
-        sr.append("\" selectUrl=\"");
-        sr.append(selectUrl);
-        sr.append("\" ajaxSelectSizeUrl=\"");
-        sr.append(ajaxSelectSizeUrl);
-        sr.append("\" selectSizeUrl=\"");
-        sr.append(selectSizeUrl);
-        sr.append("\" commonDisplaying=\"");
-        sr.append(commonDisplaying);
-        sr.append("\" paginateNextStyle=\"");
-        sr.append(paginateNextStyle);
-        sr.append("\" ajaxNextUrl=\"");
-        sr.append(ajaxNextUrl);
-        sr.append("\" nextUrl=\"");
-        sr.append(nextUrl);
-        sr.append("\" paginateNextLabel=\"");
-        sr.append(paginateNextLabel);
-        sr.append("\" paginateLastStyle=\"");
-        sr.append(paginateLastStyle);
-        sr.append("\" ajaxLastUrl=\"");
-        sr.append(ajaxLastUrl);
-        sr.append("\" lastUrl=\"");
-        sr.append(lastUrl);
-        sr.append("\" paginateLastLabel=\"");
-        sr.append(paginateLastLabel);
-        sr.append("\" paginateViewSizeLabel=\"");
-        sr.append(paginateViewSizeLabel);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-        String className = "";
-        String alert = "false";
-        String name = modelFormField.getParameterName(context);
-        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
-        String size = Integer.toString(textField.getSize());
-        String maxlength = "";
-        String autocomplete = "";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        if (UtilValidate.isEmpty(value)) {
-            value = "";
-        }
-        if (textField.getMaxlength() != null) {
-            maxlength = textField.getMaxlength().toString();
-        }
-        if (!textField.getClientAutocompleteField()) {
-            autocomplete = "off";
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFileField ");
-        sr.append(" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" size=\"");
-        sr.append(size);
-        sr.append("\" maxlength=\"");
-        sr.append(maxlength);
-        sr.append("\" autocomplete=\"");
-        sr.append(autocomplete);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.makeHyperlinkString(writer, textField.getSubHyperlink(), context);
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
-        ModelFormField modelFormField = passwordField.getModelFormField();
-        String className = "";
-        String alert = "false";
-        String name = modelFormField.getParameterName(context);
-        String size = Integer.toString(passwordField.getSize());
-        String maxlength = "";
-        String id = modelFormField.getCurrentContainerId(context);
-        String autocomplete = "";
-        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
-            className = modelFormField.getWidgetStyle();
-            if (modelFormField.shouldBeRed(context)) {
-                alert = "true";
-            }
-        }
-        String value = modelFormField.getEntry(context, passwordField.getDefaultValue(context));
-        if (value == null) {
-            value = "";
-        }
-        if (passwordField.getMaxlength() != null) {
-            maxlength = passwordField.getMaxlength().toString();
-        }
-        if (id == null) {
-            id = "";
-        }
-        if (!passwordField.getClientAutocompleteField()) {
-            autocomplete = "off";
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderPasswordField ");
-        sr.append(" className=\"");
-        sr.append(className);
-        sr.append("\" alert=\"");
-        sr.append(alert);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" value=\"");
-        sr.append(value);
-        sr.append("\" size=\"");
-        sr.append(size);
-        sr.append("\" maxlength=\"");
-        sr.append(maxlength);
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" autocomplete=\"");
-        sr.append(autocomplete);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.addAsterisks(writer, context, modelFormField);
-        this.makeHyperlinkString(writer, passwordField.getSubHyperlink(), context);
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
-        ModelFormField modelFormField = imageField.getModelFormField();
-        String value = modelFormField.getEntry(context, imageField.getValue(context));
-        String description = imageField.getDescription(context);
-        String alternate = imageField.getAlternate(context);
-        String style = imageField.getStyle(context);
-        if (UtilValidate.isEmpty(description)) {
-            description = imageField.getModelFormField().getTitle(context);
-        }
-        if (UtilValidate.isEmpty(alternate)) {
-            alternate = description;
-        }
-        if (UtilValidate.isNotEmpty(value)) {
-            if (!value.startsWith("http")) {
-                StringBuilder buffer = new StringBuilder();
-                ContentUrlTag.appendContentPrefix(request, buffer);
-                buffer.append(value);
-                value = buffer.toString();
-            }
-        } else if (value == null) {
-            value = "";
-        }
-        String event = modelFormField.getEvent();
-        String action = modelFormField.getAction(context);
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderImageField ");
-        sr.append(" value=\"");
-        sr.append(value);
-        sr.append("\" description=\"");
-        sr.append(encode(description, modelFormField, context));
-        sr.append("\" alternate=\"");
-        sr.append(encode(alternate, modelFormField, context));
-        sr.append("\" style=\"");
-        sr.append(style);
-        sr.append("\" event=\"");
-        sr.append(event == null ? "" : event);
-        sr.append("\" action=\"");
-        sr.append(action == null ? "" : action);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-        this.makeHyperlinkString(writer, imageField.getSubHyperlink(), context);
-        this.appendTooltip(writer, context, modelFormField);
-    }
-
-    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
-        String style = fieldGroup.getStyle();
-        String id = fieldGroup.getId();
-        FlexibleStringExpander titleNotExpanded = FlexibleStringExpander.getInstance(fieldGroup.getTitle());
-        String title = titleNotExpanded.expandString(context);
-        Boolean collapsed = fieldGroup.initiallyCollapsed();
-        String collapsibleAreaId = fieldGroup.getId() + "_body";
-        Boolean collapsible = fieldGroup.collapsible();
-        String expandToolTip = "";
-        String collapseToolTip = "";
-        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id) || UtilValidate.isNotEmpty(title)) {
-            if (fieldGroup.collapsible()) {
-                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-                //Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
-                if (uiLabelMap != null) {
-                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
-                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
-                }
-            }
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFieldGroupOpen ");
-        sr.append(" style=\"");
-        if (style != null) {
-            sr.append(style);
-        }
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" title=\"");
-        sr.append(title);
-        sr.append("\" collapsed=");
-        sr.append(Boolean.toString(collapsed));
-        sr.append(" collapsibleAreaId=\"");
-        sr.append(collapsibleAreaId);
-        sr.append("\" collapsible=");
-        sr.append(Boolean.toString(collapsible));
-        sr.append(" expandToolTip=\"");
-        sr.append(expandToolTip);
-        sr.append("\" collapseToolTip=\"");
-        sr.append(collapseToolTip);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
-        String style = fieldGroup.getStyle();
-        String id = fieldGroup.getId();
-        FlexibleStringExpander titleNotExpanded = FlexibleStringExpander.getInstance(fieldGroup.getTitle());
-        String title = titleNotExpanded.expandString(context);
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderFieldGroupClose ");
-        sr.append(" style=\"");
-        if (style != null) {
-            sr.append(style);
-        }
-        sr.append("\" id=\"");
-        if (id != null) {
-            sr.append(id);
-        }
-        sr.append("\" title=\"");
-        if (title != null) {
-            sr.append(title);
-        }
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
-        String style = banner.getStyle(context);
-        String leftStyle = banner.getLeftTextStyle(context);
-        if (UtilValidate.isEmpty(leftStyle))
-            leftStyle = style;
-        String rightStyle = banner.getRightTextStyle(context);
-        if (UtilValidate.isEmpty(rightStyle))
-            rightStyle = style;
-        String leftText = banner.getLeftText(context);
-        if (leftText == null) {
-            leftText = "";
-        }
-        String text = banner.getText(context);
-        if (text == null) {
-            text = "";
-        }
-        String rightText = banner.getRightText(context);
-        if (rightText == null) {
-            rightText = "";
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderBanner ");
-        sr.append(" style=\"");
-        sr.append(style);
-        sr.append("\" leftStyle=\"");
-        sr.append(leftStyle);
-        sr.append("\" rightStyle=\"");
-        sr.append(rightStyle);
-        sr.append("\" leftText=\"");
-        sr.append(leftText);
-        sr.append("\" text=\"");
-        sr.append(text);
-        sr.append("\" rightText=\"");
-        sr.append(rightText);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    /**
-     * Renders the beginning boundary comment string.
-     * @param writer The writer to write to
-     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
-     * @param modelWidget The widget
-     */
-    public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
-        if (this.widgetCommentsEnabled) {
-            StringWriter sr = new StringWriter();
-            sr.append("<@formatBoundaryComment ");
-            sr.append(" boundaryType=\"");
-            sr.append("Begin");
-            sr.append("\" widgetType=\"");
-            sr.append(widgetType);
-            sr.append("\" widgetName=\"");
-            sr.append(modelWidget.getBoundaryCommentName());
-            sr.append("\" />");
-            executeMacro(writer, sr.toString());
-        }
-    }
-
-    /**
-     * Renders the ending boundary comment string.
-     * @param writer The writer to write to
-     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
-     * @param modelWidget The widget
-     */
-    public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
-        if (this.widgetCommentsEnabled) {
-            StringWriter sr = new StringWriter();
-            sr.append("<@formatBoundaryComment ");
-            sr.append(" boundaryType=\"");
-            sr.append("End");
-            sr.append("\" widgetType=\"");
-            sr.append(widgetType);
-            sr.append("\" widgetName=\"");
-            sr.append(modelWidget.getBoundaryCommentName());
-            sr.append("\" />");
-            executeMacro(writer, sr.toString());
-        }
-    }
-
-    public void renderSortField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
-        boolean ajaxEnabled = false;
-        ModelForm modelForm = modelFormField.getModelForm();
-        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnSortColumnUpdateAreas();
-        if (updateAreas == null) {
-            // For backward compatibility.
-            updateAreas = modelForm.getOnPaginateUpdateAreas();
-        }
-        if (this.javaScriptEnabled) {
-            if (UtilValidate.isNotEmpty(updateAreas)) {
-                ajaxEnabled = true;
-            }
-        }
-        String paginateTarget = modelForm.getPaginateTarget(context);
-        if (paginateTarget.isEmpty() && updateAreas == null) {
-            Debug.logWarning("Cannot sort because the paginate target URL is empty for the form: " + modelForm.getName(), module);
-            return;
-        }
-        String oldSortField = modelForm.getSortField(context);
-        String sortFieldStyle = modelFormField.getSortFieldStyle();
-        // if the entry-name is defined use this instead of field name
-        String columnField = modelFormField.getEntryName();
-        if (UtilValidate.isEmpty(columnField)) {
-            columnField = modelFormField.getFieldName();
-        }
-        // switch between asc/desc order
-        String newSortField = columnField;
-        if (UtilValidate.isNotEmpty(oldSortField)) {
-            if (oldSortField.equals(columnField)) {
-                newSortField = "-" + columnField;
-                sortFieldStyle = modelFormField.getSortFieldStyleDesc();
-            } else if (oldSortField.equals("-" + columnField)) {
-                newSortField = columnField;
-                sortFieldStyle = modelFormField.getSortFieldStyleAsc();
-            }
-        }
-        String queryString = UtilHttp.getQueryStringFromTarget(paginateTarget).replace("?", "");
-        Map<String, Object> paramMap = UtilHttp.getQueryStringOnlyParameterMap(queryString);
-        String qbeString = (String) context.get("_QBESTRING_");
-        if (qbeString != null) {
-            qbeString = qbeString.replaceAll("&amp;", "&");
-            paramMap.putAll(UtilHttp.getQueryStringOnlyParameterMap(qbeString));
-        }
-        paramMap.put(modelForm.getSortFieldParameterName(), newSortField);
-        UtilHttp.canonicalizeParameterMap(paramMap);
-        String linkUrl = null;
-        if (ajaxEnabled) {
-            linkUrl = createAjaxParamsFromUpdateAreas(updateAreas, paramMap, null, context);
-        } else {
-            StringBuilder sb = new StringBuilder("?");
-            Iterator<Map.Entry<String, Object>> iter = paramMap.entrySet().iterator();
-            while (iter.hasNext()) {
-                Map.Entry<String, Object> entry = iter.next();
-                sb.append(entry.getKey()).append("=").append(entry.getValue());
-                if (iter.hasNext()) {
-                    sb.append("&amp;");
-                }
-            }
-            String newQueryString = sb.toString();
-            String urlPath = UtilHttp.removeQueryStringFromTarget(paginateTarget);
-            linkUrl = rh.makeLink(this.request, this.response, urlPath.concat(newQueryString));
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderSortField ");
-        sr.append(" style=\"");
-        sr.append(sortFieldStyle);
-        sr.append("\" title=\"");
-        sr.append(titleText);
-        sr.append("\" linkUrl=\"");
-        sr.append(linkUrl);
-        sr.append("\" ajaxEnabled=");
-        sr.append(Boolean.toString(ajaxEnabled));
-        String tooltip = modelFormField.getSortFieldHelpText(context);
-        if (!tooltip.isEmpty()) {
-            sr.append(" tooltip=\"").append(tooltip).append("\"");
-        }
-        sr.append(" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea objects. See
-     * <code>selectall.js</code>.
-     * @param updateAreas
-     * @param extraParams Renderer-supplied additional target parameters
-     * @param context
-     * @return Parameter string or empty string if no UpdateArea objects were found
-     */
-    private String createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas, Map<String, Object> extraParams, String anchor, Map<String, ? extends Object> context) {
-        StringBuilder sb = new StringBuilder();
-        Iterator<ModelForm.UpdateArea> updateAreaIter = updateAreas.iterator();
-        while (updateAreaIter.hasNext()) {
-            ModelForm.UpdateArea updateArea = updateAreaIter.next();
-            sb.append(updateArea.getAreaId()).append(",");
-            String ajaxTarget = updateArea.getAreaTarget(context);
-            String urlPath = UtilHttp.removeQueryStringFromTarget(ajaxTarget);
-            sb.append(this.rh.makeLink(this.request, this.response,urlPath)).append(",");
-            String queryString = UtilHttp.getQueryStringFromTarget(ajaxTarget).replace("?", "");
-            Map<String, Object> parameters = UtilHttp.getQueryStringOnlyParameterMap(queryString);
-            Map<String, Object> ctx = UtilGenerics.checkMap(context);
-            Map<String, Object> updateParams = UtilGenerics.checkMap(updateArea.getParameterMap(ctx));
-            parameters.putAll(updateParams);
-            UtilHttp.canonicalizeParameterMap(parameters);
-            parameters.putAll(extraParams);
-            Iterator<Map.Entry<String, Object>> paramIter = parameters.entrySet().iterator();
-            while (paramIter.hasNext()) {
-                Map.Entry<String, Object> entry = paramIter.next();
-                sb.append(entry.getKey()).append("=").append(entry.getValue());
-                if (paramIter.hasNext()) {
-                    sb.append("&");
-                }
-            }
-            if (anchor != null) {
-                sb.append("#").append(anchor);
-            }
-            if (updateAreaIter.hasNext()) {
-                sb.append(",");
-            }
-        }
-        Locale locale = UtilMisc.ensureLocale(context.get("locale"));
-        return FlexibleStringExpander.expandString(sb.toString(), context, locale);
-    }
-
-    /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea objects. See
-     * <code>selectall.js</code>.
-     * @param updateAreas
-     * @param extraParams Renderer-supplied additional target parameters
-     * @param context
-     * @return Parameter string or empty string if no UpdateArea objects were found
-     */
-    public String createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas, String extraParams, Map<String, ? extends Object> context) {
-        //FIXME copy from HtmlFormRenderer.java
-        if (updateAreas == null) {
-            return "";
-        }
-        String ajaxUrl = "";
-        boolean firstLoop = true;
-        for (ModelForm.UpdateArea updateArea : updateAreas) {
-            if (firstLoop) {
-                firstLoop = false;
-            } else {
-                ajaxUrl += ",";
-            }
-            Map<String, Object> ctx = UtilGenerics.checkMap(context);
-            Map<String, String> parameters = updateArea.getParameterMap(ctx);
-            String targetUrl = updateArea.getAreaTarget(context);
-            String ajaxParams = getAjaxParamsFromTarget(targetUrl);
-            //add first parameters from updateArea parameters
-            if (UtilValidate.isNotEmpty(parameters)) {
-                if (UtilValidate.isEmpty(ajaxParams)) {
-                    ajaxParams = "";
-                }
-                for (Map.Entry<String, String> entry : parameters.entrySet()) {
-                    String key = entry.getKey();
-                    String value = entry.getValue();
-                    //test if ajax parameters are not already into extraParams, if so do not add it
-                    if (UtilValidate.isNotEmpty(extraParams) && extraParams.contains(value)) {
-                        continue;
-                    }
-                    if (ajaxParams.length() > 0 && ajaxParams.indexOf(key) < 0) {
-                        ajaxParams += "&";
-                    }
-                    if (ajaxParams.indexOf(key) < 0) {
-                        ajaxParams += key + "=" + value;
-                    }
-                }
-            }
-            //then add parameters from request. Those parameters could end with an anchor so we must set ajax parameters first
-            if (UtilValidate.isNotEmpty(extraParams)) {
-                if (ajaxParams.length() > 0 && !extraParams.startsWith("&")) {
-                    ajaxParams += "&";
-                }
-                ajaxParams += extraParams;
-            }
-            ajaxUrl += updateArea.getAreaId() + ",";
-            ajaxUrl += this.rh.makeLink(this.request, this.response, UtilHttp.removeQueryStringFromTarget(targetUrl));
-            ajaxUrl += "," + ajaxParams;
-        }
-        Locale locale = UtilMisc.ensureLocale(context.get("locale"));
-        return FlexibleStringExpander.expandString(ajaxUrl, context, locale);
-    }
-
-    /** Extracts parameters from a target URL string, prepares them for an Ajax
-     * JavaScript call. This method is currently set to return a parameter string
-     * suitable for the Prototype.js library.
-     * @param target Target URL string
-     * @return Parameter string
-     */
-    public static String getAjaxParamsFromTarget(String target) {
-        String targetParams = UtilHttp.getQueryStringFromTarget(target);
-        targetParams = targetParams.replace("?", "");
-        targetParams = targetParams.replace("&amp;", "&");
-        return targetParams;
-    }
-
-    public void appendTooltip(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        // render the tooltip, in other methods too
-        String tooltip = modelFormField.getTooltip(context);
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderTooltip ");
-        sr.append("tooltip=\"");
-        sr.append(FreeMarkerWorker.encodeDoubleQuotes(tooltip));
-        sr.append("\" tooltipStyle=\"");
-        sr.append(modelFormField.getTooltipStyle());
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void makeHyperlinkString(Appendable writer, ModelFormField.SubHyperlink subHyperlink, Map<String, Object> context) throws IOException {
-        if (subHyperlink == null) {
-            return;
-        }
-        if (subHyperlink.shouldUse(context)) {
-            writer.append(' ');
-            makeHyperlinkByType(writer, subHyperlink.getLinkType(), subHyperlink.getStyle(context), subHyperlink.getUrlMode(),
-                    subHyperlink.getTarget(context), subHyperlink.getParameterMap(context), subHyperlink.getDescription(context),
-                    subHyperlink.getTargetWindow(context), null, subHyperlink.getModelFormField(), this.request, this.response,
-                    context);
-        }
-    }
-
-    public void addAsterisks(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        String requiredField = "false";
-        String requiredStyle = "";
-        if (modelFormField.getRequiredField()) {
-            requiredField = "true";
-            requiredStyle = modelFormField.getRequiredFieldStyle();
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderAsterisks ");
-        sr.append("requiredField=\"");
-        sr.append(requiredField);
-        sr.append("\" requiredStyle=\"");
-        sr.append(requiredStyle);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void appendContentUrl(Appendable writer, String location) throws IOException {
-        StringBuilder buffer = new StringBuilder();
-        ContentUrlTag.appendContentPrefix(this.request, buffer);
-        writer.append(buffer.toString());
-        writer.append(location);
-    }
-
-    public void makeHyperlinkByType(Appendable writer, String linkType, String linkStyle, String targetType, String target, Map<String, String> parameterMap, String description, String targetWindow, String confirmation, ModelFormField modelFormField, HttpServletRequest request,
-            HttpServletResponse response, Map<String, Object> context) throws IOException {
-        String realLinkType = WidgetWorker.determineAutoLinkType(linkType, target, targetType, request);
-        String encodedDescription = encode(description, modelFormField, context);
-        // get the parameterized pagination index and size fields
-        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
-        ModelForm modelForm = modelFormField.getModelForm();
-        String viewIndexField = modelForm.getMultiPaginateIndexField(context);
-        String viewSizeField = modelForm.getMultiPaginateSizeField(context);
-        int viewIndex = Paginator.getViewIndex(modelForm, context);
-        int viewSize = Paginator.getViewSize(modelForm, context);
-        if (viewIndexField.equals("viewIndex" + "_" + paginatorNumber)) {
-            viewIndexField = "VIEW_INDEX" + "_" + paginatorNumber;
-        }
-        if (viewSizeField.equals("viewSize" + "_" + paginatorNumber)) {
-            viewSizeField = "VIEW_SIZE" + "_" + paginatorNumber;
-        }
-        if ("hidden-form".equals(realLinkType)) {
-            parameterMap.put(viewIndexField, Integer.toString(viewIndex));
-            parameterMap.put(viewSizeField, Integer.toString(viewSize));
-            if (modelFormField != null && "multi".equals(modelForm.getType())) {
-                WidgetWorker.makeHiddenFormLinkAnchor(writer, linkStyle, encodedDescription, confirmation, modelFormField, request, response, context);
-                // this is a bit trickier, since we can't do a nested form we'll have to put the link to submit the form in place, but put the actual form def elsewhere, ie after the big form is closed
-                Map<String, Object> wholeFormContext = UtilGenerics.checkMap(context.get("wholeFormContext"));
-                Appendable postMultiFormWriter = wholeFormContext != null ? (Appendable) wholeFormContext.get("postMultiFormWriter") : null;
-                if (postMultiFormWriter == null) {
-                    postMultiFormWriter = new StringWriter();
-                    wholeFormContext.put("postMultiFormWriter", postMultiFormWriter);
-                }
-                WidgetWorker.makeHiddenFormLinkForm(postMultiFormWriter, target, targetType, targetWindow, parameterMap, modelFormField, request, response, context);
-            } else {
-                WidgetWorker.makeHiddenFormLinkForm(writer, target, targetType, targetWindow, parameterMap, modelFormField, request, response, context);
-                WidgetWorker.makeHiddenFormLinkAnchor(writer, linkStyle, encodedDescription, confirmation, modelFormField, request, response, context);
-            }
-        } else {
-            makeHyperlinkString(writer, linkStyle, targetType, target, parameterMap, encodedDescription, confirmation, modelFormField, request, response, context, targetWindow);
-        }
-
-    }
-
-    public void makeHyperlinkString(Appendable writer, String linkStyle, String targetType, String target, Map<String, String> parameterMap, String description, String confirmation, ModelFormField modelFormField, HttpServletRequest request, HttpServletResponse response, Map<String, Object> context,
-            String targetWindow) throws IOException {
-        if (UtilValidate.isNotEmpty(description) || UtilValidate.isNotEmpty(request.getAttribute("image"))) {
-            StringBuilder linkUrl = new StringBuilder();
-            WidgetWorker.buildHyperlinkUrl(linkUrl, target, targetType, parameterMap, null, false, false, true, request, response, context);
-            String event = "";
-            String action = "";
-            String imgSrc = "";
-            String alt = "";
-            String imgTitle = "";
-            String hiddenFormName = WidgetWorker.makeLinkHiddenFormName(context, modelFormField);
-            if (UtilValidate.isNotEmpty(modelFormField.getEvent()) && UtilValidate.isNotEmpty(modelFormField.getAction(context))) {
-                event = modelFormField.getEvent();
-                action = modelFormField.getAction(context);
-            }
-            if (UtilValidate.isNotEmpty(request.getAttribute("image"))) {
-                imgSrc = request.getAttribute("image").toString();
-            }
-            if (UtilValidate.isNotEmpty(request.getAttribute("alternate"))) {
-                alt = request.getAttribute("alternate").toString();
-            }
-            if (UtilValidate.isNotEmpty(request.getAttribute("imageTitle"))) {
-                imgTitle = request.getAttribute("imageTitle").toString();
-            }
-            Integer size = Integer.valueOf("0");
-            if (UtilValidate.isNotEmpty(request.getAttribute("descriptionSize"))) {
-                size = Integer.valueOf(request.getAttribute("descriptionSize").toString());
-            }
-            if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) {
-                imgTitle = description;
-                description = description.substring(0, size - 8) + "..." + description.substring(description.length() - 5);
-            }
-            if (UtilValidate.isEmpty(imgTitle)) {
-                imgTitle = modelFormField.getTitle(context);
-            }
-            StringWriter sr = new StringWriter();
-            sr.append("<@makeHyperlinkString ");
-            sr.append("linkStyle=\"");
-            sr.append(linkStyle == null ? "" : linkStyle);
-            sr.append("\" hiddenFormName=\"");
-            sr.append(hiddenFormName == null ? "" : hiddenFormName);
-            sr.append("\" event=\"");
-            sr.append(event);
-            sr.append("\" action=\"");
-            sr.append(action);
-            sr.append("\" imgSrc=\"");
-            sr.append(imgSrc);
-            sr.append("\" title=\"");
-            sr.append(imgTitle);
-            sr.append("\" alternate=\"");
-            sr.append(alt);
-            sr.append("\" linkUrl=\"");
-            sr.append(linkUrl.toString());
-            sr.append("\" targetWindow=\"");
-            sr.append(targetWindow);
-            sr.append("\" description=\"");
-            sr.append(description);
-            sr.append("\" confirmation =\"");
-            sr.append(confirmation);
-            sr.append("\" />");
-            executeMacro(writer, sr.toString());
-        }
-    }
-
-    public void makeHiddenFormLinkAnchor(Appendable writer, String linkStyle, String description, String confirmation, ModelFormField modelFormField, HttpServletRequest request, HttpServletResponse response, Map<String, Object> context) throws IOException {
-        if (UtilValidate.isNotEmpty(description) || UtilValidate.isNotEmpty(request.getAttribute("image"))) {
-            String hiddenFormName = WidgetWorker.makeLinkHiddenFormName(context, modelFormField);
-            String event = "";
-            String action = "";
-            String imgSrc = "";
-            if (UtilValidate.isNotEmpty(modelFormField.getEvent()) && UtilValidate.isNotEmpty(modelFormField.getAction(context))) {
-                event = modelFormField.getEvent();
-                action = modelFormField.getAction(context);
-            }
-            if (UtilValidate.isNotEmpty(request.getAttribute("image"))) {
-                imgSrc = request.getAttribute("image").toString();
-            }
-            StringWriter sr = new StringWriter();
-            sr.append("<@makeHiddenFormLinkAnchor ");
-            sr.append("linkStyle=\"");
-            sr.append(linkStyle == null ? "" : linkStyle);
-            sr.append("\" hiddenFormName=\"");
-            sr.append(hiddenFormName == null ? "" : hiddenFormName);
-            sr.append("\" event=\"");
-            sr.append(event);
-            sr.append("\" action=\"");
-            sr.append(action);
-            sr.append("\" imgSrc=\"");
-            sr.append(imgSrc);
-            sr.append("\" description=\"");
-            sr.append(description);
-            sr.append("\" confirmation =\"");
-            sr.append(confirmation);
-            sr.append("\" />");
-            executeMacro(writer, sr.toString());
-        }
-    }
-
-    public void makeHiddenFormLinkForm(Appendable writer, String target, String targetType, String targetWindow, List<CommonWidgetModels.Parameter> parameterList, ModelFormField modelFormField, HttpServletRequest request, HttpServletResponse response, Map<String, Object> context) throws IOException {
-        StringBuilder actionUrl = new StringBuilder();
-        WidgetWorker.buildHyperlinkUrl(actionUrl, target, targetType, null, null, false, false, true, request, response, context);
-        String name = WidgetWorker.makeLinkHiddenFormName(context, modelFormField);
-        StringBuilder parameters = new StringBuilder();
-        parameters.append("[");
-        for (CommonWidgetModels.Parameter parameter : parameterList) {
-            if (parameters.length() > 1) {
-                parameters.append(",");
-            }
-            parameters.append("{'name':'");
-            parameters.append(parameter.getName());
-            parameters.append("'");
-            parameters.append(",'value':'");
-            parameters.append(UtilCodec.getEncoder("html").encode(parameter.getValue(context)));
-            parameters.append("'}");
-        }
-        parameters.append("]");
-        StringWriter sr = new StringWriter();
-        sr.append("<@makeHiddenFormLinkForm ");
-        sr.append("actionUrl=\"");
-        sr.append(actionUrl.toString());
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" parameters=");
-        sr.append(parameters.toString());
-        sr.append(" targetWindow=\"");
-        sr.append(targetWindow);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
-        String id = containerField.getModelFormField().getIdName();
-        String className = UtilFormatOut.checkNull(containerField.getModelFormField().getWidgetStyle());
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderContainerField ");
-        sr.append("id=\"");
-        sr.append(id);
-        sr.append("\" className=\"");
-        sr.append(className);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.macro;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.rmi.server.UID;
+import java.sql.Timestamp;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.base.util.template.FreeMarkerWorker;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.webapp.control.RequestHandler;
+import org.ofbiz.webapp.taglib.ContentUrlTag;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.CommonWidgetModels;
+import org.ofbiz.widget.model.FieldInfo;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelFormField;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayEntityField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
+import org.ofbiz.widget.model.ModelFormFieldBuilder;
+import org.ofbiz.widget.model.ModelScreenWidget;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.FormRenderer;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.Paginator;
+import org.ofbiz.widget.renderer.UtilHelpText;
+
+import com.ibm.icu.util.Calendar;
+
+import freemarker.core.Environment;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+/**
+ * Widget Library - Form Renderer implementation based on Freemarker macros
+ *
+ */
+public final class MacroFormRenderer implements FormStringRenderer {
+
+    public static final String module = MacroFormRenderer.class.getName();
+    private final Template macroLibrary;
+    private final WeakHashMap<Appendable, Environment> environments = new WeakHashMap<Appendable, Environment>();
+    private final UtilCodec.SimpleEncoder internalEncoder;
+    private final RequestHandler rh;
+    private final HttpServletRequest request;
+    private final HttpServletResponse response;
+    private final boolean javaScriptEnabled;
+    private boolean renderPagination = true;
+    private boolean widgetCommentsEnabled = false;
+
+    public MacroFormRenderer(String macroLibraryPath, HttpServletRequest request, HttpServletResponse response) throws TemplateException, IOException {
+        macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
+        this.request = request;
+        this.response = response;
+        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+        this.rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+        this.javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
+        internalEncoder = UtilCodec.getEncoder("string");
+    }
+
+    @Deprecated
+    public MacroFormRenderer(String macroLibraryPath, Appendable writer, HttpServletRequest request, HttpServletResponse response) throws TemplateException, IOException {
+        this(macroLibraryPath, request, response);
+    }
+
+    public boolean getRenderPagination() {
+        return this.renderPagination;
+    }
+
+    public void setRenderPagination(boolean renderPagination) {
+        this.renderPagination = renderPagination;
+    }
+
+    private void executeMacro(Appendable writer, String macro) throws IOException {
+        try {
+            Environment environment = getEnvironment(writer);
+            Reader templateReader = new StringReader(macro);
+            Template template = new Template(new UID().toString(), templateReader, FreeMarkerWorker.getDefaultOfbizConfig());
+            templateReader.close();
+            environment.include(template);
+        } catch (TemplateException e) {
+            Debug.logError(e, "Error rendering screen thru ftl macro: " + macro, module);
+        } catch (IOException e) {
+            Debug.logError(e, "Error rendering screen thru ftl, macro: " + macro, module);
+        }
+    }
+
+    private Environment getEnvironment(Appendable writer) throws TemplateException, IOException {
+        Environment environment = environments.get(writer);
+        if (environment == null) {
+            Map<String, Object> input = UtilMisc.toMap("key", null);
+            environment = FreeMarkerWorker.renderTemplate(macroLibrary, input, writer);
+            environments.put(writer, environment);
+        }
+        return environment;
+    }
+
+    private void appendWhitespace(Appendable writer) throws IOException {
+        // appending line ends for now, but this could be replaced with a simple space or something
+        writer.append("\r\n");
+        //writer.append(' ');
+    }
+
+    private String encode(String value, ModelFormField modelFormField, Map<String, Object> context) {
+        if (UtilValidate.isEmpty(value)) {
+            return value;
+        }
+        UtilCodec.SimpleEncoder encoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
+        if (modelFormField.getEncodeOutput() && encoder != null) {
+            value = encoder.encode(value);
+        } else {
+            value = internalEncoder.encode(value);
+        }
+        return value;
+    }
+
+    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException {
+        String labelText = label.getText(context);
+        if (UtilValidate.isEmpty(labelText)) {
+            // nothing to render
+            return;
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderLabel ");
+        sr.append("text=\"");
+        sr.append(labelText);
+        sr.append("\"");
+        sr.append(" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
+        ModelFormField modelFormField = displayField.getModelFormField();
+        String idName = modelFormField.getCurrentContainerId(context);
+        String description = displayField.getDescription(context);
+        String type = displayField.getType();
+        String imageLocation = displayField.getImageLocation(context);
+        Integer size = Integer.valueOf("0");
+        String title = "";
+        if (UtilValidate.isNotEmpty(displayField.getSize())) {
+            try {
+                size = Integer.parseInt(displayField.getSize());
+            } catch (NumberFormatException nfe) {
+                Debug.logError(nfe, "Error reading size of a field fieldName=" + displayField.getModelFormField().getFieldName() + " FormName= " + displayField.getModelFormField().getModelForm().getName(), module);
+            }
+        }
+        ModelFormField.InPlaceEditor inPlaceEditor = displayField.getInPlaceEditor();
+        boolean ajaxEnabled = inPlaceEditor != null && this.javaScriptEnabled;
+        if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) {
+            title = description;
+            description = description.substring(0, size - 8) + "..." + description.substring(description.length() - 5);
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderDisplayField ");
+        sr.append("type=\"");
+        sr.append(type);
+        sr.append("\" imageLocation=\"");
+        sr.append(imageLocation);
+        sr.append("\" idName=\"");
+        sr.append(idName);
+        sr.append("\" description=\"");
+        sr.append(FreeMarkerWorker.encodeDoubleQuotes(description));
+        sr.append("\" title=\"");
+        sr.append(title);
+        sr.append("\" class=\"");
+        sr.append(modelFormField.getWidgetStyle());
+        sr.append("\" alert=\"");
+        sr.append(modelFormField.shouldBeRed(context) ? "true" : "false");
+        if (ajaxEnabled) {
+            String url = inPlaceEditor.getUrl(context);
+            String extraParameter = "{";
+            Map<String, Object> fieldMap = inPlaceEditor.getFieldMap(context);
+            if (fieldMap != null) {
+                Set<Entry<String, Object>> fieldSet = fieldMap.entrySet();
+                Iterator<Entry<String, Object>> fieldIterator = fieldSet.iterator();
+                int count = 0;
+                while (fieldIterator.hasNext()) {
+                    count++;
+                    Entry<String, Object> field = fieldIterator.next();
+                    extraParameter += field.getKey() + ":'" + (String) field.getValue() + "'";
+                    if (count < fieldSet.size()) {
+                        extraParameter += ',';
+                    }
+                }
+
+            }
+            extraParameter += "}";
+            sr.append("\" inPlaceEditorUrl=\"");
+            sr.append(url);
+            sr.append("\" inPlaceEditorParams=\"");
+            StringWriter inPlaceEditorParams = new StringWriter();
+            inPlaceEditorParams.append("{name: '");
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getParamName())) {
+                inPlaceEditorParams.append(inPlaceEditor.getParamName());
+            } else {
+                inPlaceEditorParams.append(modelFormField.getFieldName());
+            }
+            inPlaceEditorParams.append("'");
+            inPlaceEditorParams.append(", method: 'POST'");
+            inPlaceEditorParams.append(", submitdata: " + extraParameter);
+            inPlaceEditorParams.append(", type: 'textarea'");
+            inPlaceEditorParams.append(", select: 'true'");
+            inPlaceEditorParams.append(", onreset: function(){jQuery('#cc_" + idName + "').css('background-color', 'transparent');}");
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getCancelText())) {
+                inPlaceEditorParams.append(", cancel: '" + inPlaceEditor.getCancelText() + "'");
+            } else {
+                inPlaceEditorParams.append(", cancel: 'Cancel'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getClickToEditText())) {
+                inPlaceEditorParams.append(", tooltip: '" + inPlaceEditor.getClickToEditText() + "'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getFormClassName())) {
+                inPlaceEditorParams.append(", cssclass: '" + inPlaceEditor.getFormClassName() + "'");
+            } else {
+                inPlaceEditorParams.append(", cssclass: 'inplaceeditor-form'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getLoadingText())) {
+                inPlaceEditorParams.append(", indicator: '" + inPlaceEditor.getLoadingText() + "'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getOkControl())) {
+                inPlaceEditorParams.append(", submit: ");
+                if (!"false".equals(inPlaceEditor.getOkControl())) {
+                    inPlaceEditorParams.append("'");
+                }
+                inPlaceEditorParams.append(inPlaceEditor.getOkControl());
+                if (!"false".equals(inPlaceEditor.getOkControl())) {
+                    inPlaceEditorParams.append("'");
+                }
+            } else {
+                inPlaceEditorParams.append(", submit: 'OK'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getRows())) {
+                inPlaceEditorParams.append(", rows: '" + inPlaceEditor.getRows() + "'");
+            }
+            if (UtilValidate.isNotEmpty(inPlaceEditor.getCols())) {
+                inPlaceEditorParams.append(", cols: '" + inPlaceEditor.getCols() + "'");
+            }
+            inPlaceEditorParams.append("}");
+            sr.append(inPlaceEditorParams.toString());
+        }
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        if (displayField instanceof DisplayEntityField) {
+            makeHyperlinkString(writer, ((DisplayEntityField) displayField).getSubHyperlink(), context);
+        }
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
+        this.request.setAttribute("image", hyperlinkField.getImageLocation(context));
+        ModelFormField modelFormField = hyperlinkField.getModelFormField();
+        String encodedAlternate = encode(hyperlinkField.getAlternate(context), modelFormField, context);
+        String encodedImageTitle = encode(hyperlinkField.getImageTitle(context), modelFormField, context);
+        this.request.setAttribute("alternate", encodedAlternate);
+        this.request.setAttribute("imageTitle", encodedImageTitle);
+        this.request.setAttribute("descriptionSize", hyperlinkField.getSize());
+        makeHyperlinkByType(writer, hyperlinkField.getLinkType(), modelFormField.getWidgetStyle(), hyperlinkField.getUrlMode(), hyperlinkField.getTarget(context), hyperlinkField.getParameterMap(context), hyperlinkField.getDescription(context), hyperlinkField.getTargetWindow(context),
+                hyperlinkField.getConfirmation(context), modelFormField, this.request, this.response, context);
+        this.appendTooltip(writer, context, modelFormField);
+        this.request.removeAttribute("image");
+        this.request.removeAttribute("descriptionSize");
+    }
+
+    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+        String name = modelFormField.getParameterName(context);
+        String className = "";
+        String alert = "false";
+        String mask = "";
+        String placeholder = textField.getPlaceholder(context);
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
+        String textSize = Integer.toString(textField.getSize());
+        String maxlength = "";
+        if (textField.getMaxlength() != null) {
+            maxlength = Integer.toString(textField.getMaxlength());
+        }
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        String id = modelFormField.getCurrentContainerId(context);
+        String clientAutocomplete = "false";
+        //check for required field style on single forms
+        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
+            String requiredStyle = modelFormField.getRequiredFieldStyle();
+            if (UtilValidate.isEmpty(requiredStyle))
+                requiredStyle = "required";
+            if (UtilValidate.isEmpty(className))
+                className = requiredStyle;
+            else
+                className = requiredStyle + " " + className;
+        }
+        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
+        boolean ajaxEnabled = updateAreas != null && this.javaScriptEnabled;
+        if (textField.getClientAutocompleteField() || ajaxEnabled) {
+            clientAutocomplete = "true";
+        }
+        if (UtilValidate.isNotEmpty(textField.getMask())) {
+            mask = textField.getMask();
+        }
+        String ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "", context);
+        boolean disabled = textField.getDisabled();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderTextField ");
+        sr.append("name=\"");
+        sr.append(name);
+        sr.append("\" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" textSize=\"");
+        sr.append(textSize);
+        sr.append("\" maxlength=\"");
+        sr.append(maxlength);
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" event=\"");
+        if (event != null) {
+            sr.append(event);
+        }
+        sr.append("\" action=\"");
+        if (action != null) {
+            sr.append(action);
+        }
+        sr.append("\" disabled=");
+        sr.append(Boolean.toString(disabled));
+        sr.append(" clientAutocomplete=\"");
+        sr.append(clientAutocomplete);
+        sr.append("\" ajaxUrl=\"");
+        sr.append(ajaxUrl);
+        sr.append("\" ajaxEnabled=");
+        sr.append(Boolean.toString(ajaxEnabled));
+        sr.append(" mask=\"");
+        sr.append(mask);
+        sr.append("\" placeholder=\"");
+        sr.append(placeholder);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        ModelFormField.SubHyperlink subHyperlink = textField.getSubHyperlink();
+        if (subHyperlink != null && subHyperlink.shouldUse(context)) {
+            makeHyperlinkString(writer, subHyperlink, context);
+        }
+        this.addAsterisks(writer, context, modelFormField);
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
+        ModelFormField modelFormField = textareaField.getModelFormField();
+        String name = modelFormField.getParameterName(context);
+        String cols = Integer.toString(textareaField.getCols());
+        String rows = Integer.toString(textareaField.getRows());
+        String id = modelFormField.getCurrentContainerId(context);
+        String className = "";
+        String alert = "false";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        //check for required field style on single forms
+        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
+            String requiredStyle = modelFormField.getRequiredFieldStyle();
+            if (UtilValidate.isEmpty(requiredStyle))
+                requiredStyle = "required";
+            if (UtilValidate.isEmpty(className))
+                className = requiredStyle;
+            else
+                className = requiredStyle + " " + className;
+        }
+        String visualEditorEnable = "";
+        String buttons = "";
+        if (textareaField.getVisualEditorEnable()) {
+            visualEditorEnable = "true";
+            buttons = textareaField.getVisualEditorButtons(context);
+            if (UtilValidate.isEmpty(buttons)) {
+                buttons = "maxi";
+            }
+        }
+        String readonly = "";
+        if (textareaField.isReadOnly()) {
+            readonly = "readonly";
+        }
+        Map<String, Object> userLogin = UtilGenerics.checkMap(context.get("userLogin"));
+        String language = "en";
+        if (userLogin != null) {
+            language = UtilValidate.isEmpty((String) userLogin.get("lastLocale")) ? "en" : (String) userLogin.get("lastLocale");
+        }
+        String value = modelFormField.getEntry(context, textareaField.getDefaultValue(context));
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderTextareaField ");
+        sr.append("name=\"");
+        sr.append(name);
+        sr.append("\" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" cols=\"");
+        sr.append(cols);
+        sr.append("\" rows=\"");
+        sr.append(rows);
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" readonly=\"");
+        sr.append(readonly);
+        sr.append("\" visualEditorEnable=\"");
+        sr.append(visualEditorEnable);
+        sr.append("\" language=\"");
+        sr.append(language);
+        sr.append("\" buttons=\"");
+        sr.append(buttons);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.addAsterisks(writer, context, modelFormField);
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
+        ModelFormField modelFormField = dateTimeField.getModelFormField();
+        String paramName = modelFormField.getParameterName(context);
+        String defaultDateTimeString = dateTimeField.getDefaultDateTimeString(context);
+        String className = "";
+        String alert = "false";
+        String name = "";
+        String formattedMask = "";
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        boolean useTimeDropDown = "time-dropdown".equals(dateTimeField.getInputMethod());
+        String stepString = dateTimeField.getStep();
+        int step = 1;
+        StringBuilder timeValues = new StringBuilder();
+        if (useTimeDropDown && UtilValidate.isNotEmpty(step)) {
+            try {
+                step = Integer.valueOf(stepString).intValue();
+            } catch (IllegalArgumentException e) {
+                Debug.logWarning("Inavalid value for step property for field[" + paramName + "] with input-method=\"time-dropdown\" " + " Found Value [" + stepString + "]  " + e.getMessage(), module);
+            }
+            timeValues.append("[");
+            for (int i = 0; i <= 59;) {
+                if (i != 0) {
+                    timeValues.append(", ");
+                }
+                timeValues.append(i);
+                i += step;
+            }
+            timeValues.append("]");
+        }
+        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        }
+        String localizedInputTitle = "", localizedIconTitle = "";
+        // whether the date field is short form, yyyy-mm-dd
+        boolean shortDateInput = ("date".equals(dateTimeField.getType()) || useTimeDropDown ? true : false);
+        if (useTimeDropDown) {
+            name = UtilHttp.makeCompositeParam(paramName, "date");
+        } else {
+            name = paramName;
+        }
+        // the default values for a timestamp
+        int size = 25;
+        int maxlength = 30;
+        if (shortDateInput) {
+            size = maxlength = 10;
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatDate");
+            }
+        } else if ("time".equals(dateTimeField.getType())) {
+            size = maxlength = 8;
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatTime");
+            }
+        } else {
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatDateTime");
+            }
+        }
+        /*
+         * FIXME: Using a builder here is a hack. Replace the builder with appropriate code.
+         */
+        ModelFormFieldBuilder builder = new ModelFormFieldBuilder(modelFormField);
+        boolean memEncodeOutput = modelFormField.getEncodeOutput();
+        if (useTimeDropDown)
+            // If time-dropdown deactivate encodingOutput for found hour and minutes
+            // FIXME: Encoding should be controlled by the renderer, not by the model.
+            builder.setEncodeOutput(false);
+        // FIXME: modelFormField.getEntry ignores shortDateInput when converting Date objects to Strings.
+        if (useTimeDropDown) {
+            builder.setEncodeOutput(memEncodeOutput);
+        }
+        modelFormField = builder.build();
+        String contextValue = modelFormField.getEntry(context, dateTimeField.getDefaultValue(context));
+        String value = contextValue;
+        if (UtilValidate.isNotEmpty(value)) {
+            if (value.length() > maxlength) {
+                value = value.substring(0, maxlength);
+            }
+        }
+        String id = modelFormField.getCurrentContainerId(context);
+        ModelForm modelForm = modelFormField.getModelForm();
+        String formName = FormRenderer.getCurrentFormName(modelForm, context);
+        String timeDropdown = dateTimeField.getInputMethod();
+        String timeDropdownParamName = "";
+        String classString = "";
+        boolean isTwelveHour = false;
+        String timeHourName = "";
+        int hour2 = 0, hour1 = 0, minutes = 0;
+        String timeMinutesName = "";
+        String amSelected = "", pmSelected = "", ampmName = "";
+        String compositeType = "";
+        // search for a localized label for the icon
+        if (uiLabelMap != null) {
+            localizedIconTitle = uiLabelMap.get("CommonViewCalendar");
+        }
+        if (!"time".equals(dateTimeField.getType())) {
+            String tempParamName;
+            if (useTimeDropDown) {
+                tempParamName = UtilHttp.makeCompositeParam(paramName, "date");
+            } else {
+                tempParamName = paramName;
+            }
+            timeDropdownParamName = tempParamName;
+            defaultDateTimeString = UtilHttp.encodeBlanks(modelFormField.getEntry(context, defaultDateTimeString));
+        }
+        // if we have an input method of time-dropdown, then render two
+        // dropdowns
+        if (useTimeDropDown) {
+            className = modelFormField.getWidgetStyle();
+            classString = (className != null ? className : "");
+            isTwelveHour = "12".equals(dateTimeField.getClock());
+            // set the Calendar to the default time of the form or now()
+            Calendar cal = null;
+            try {
+                Timestamp defaultTimestamp = Timestamp.valueOf(contextValue);
+                cal = Calendar.getInstance();
+                cal.setTime(defaultTimestamp);
+            } catch (IllegalArgumentException e) {
+                Debug.logWarning("Form widget field [" + paramName + "] with input-method=\"time-dropdown\" was not able to understand the default time [" + defaultDateTimeString + "]. The parsing error was: " + e.getMessage(), module);
+            }
+            timeHourName = UtilHttp.makeCompositeParam(paramName, "hour");
+            if (cal != null) {
+                int hour = cal.get(Calendar.HOUR_OF_DAY);
+                hour2 = hour;
+                if (hour == 0) {
+                    hour = 12;
+                }
+                if (hour > 12) {
+                    hour -= 12;
+                }
+                hour1 = hour;
+                minutes = cal.get(Calendar.MINUTE);
+            }
+            timeMinutesName = UtilHttp.makeCompositeParam(paramName, "minutes");
+            compositeType = UtilHttp.makeCompositeParam(paramName, "compositeType");
+            // if 12 hour clock, write the AM/PM selector
+            if (isTwelveHour) {
+                amSelected = ((cal != null && cal.get(Calendar.AM_PM) == Calendar.AM) ? "selected" : "");
+                pmSelected = ((cal != null && cal.get(Calendar.AM_PM) == Calendar.PM) ? "selected" : "");
+                ampmName = UtilHttp.makeCompositeParam(paramName, "ampm");
+            }
+        }
+        //check for required field style on single forms
+        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
+            String requiredStyle = modelFormField.getRequiredFieldStyle();
+            if (UtilValidate.isEmpty(requiredStyle))
+                requiredStyle = "required";
+            if (UtilValidate.isEmpty(className))
+                className = requiredStyle;
+            else
+                className = requiredStyle + " " + className;
+        }
+        String mask = dateTimeField.getMask();
+        if ("Y".equals(mask)) {
+            if ("date".equals(dateTimeField.getType())) {
+                formattedMask = "9999-99-99";
+            } else if ("time".equals(dateTimeField.getType())) {
+                formattedMask = "99:99:99";
+            } else if ("timestamp".equals(dateTimeField.getType())) {
+                formattedMask = "9999-99-99 99:99:99";
+            }
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderDateTimeField ");
+        sr.append("name=\"");
+        sr.append(name);
+        sr.append("\" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" title=\"");
+        sr.append(localizedInputTitle);
+        sr.append("\" size=\"");
+        sr.append(Integer.toString(size));
+        sr.append("\" maxlength=\"");
+        sr.append(Integer.toString(maxlength));
+        sr.append("\" step=\"");
+        sr.append(Integer.toString(step));
+        sr.append("\" timeValues=\"");
+        sr.append(timeValues.toString());
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" event=\"");
+        sr.append(event);
+        sr.append("\" action=\"");
+        sr.append(action);
+        sr.append("\" dateType=\"");
+        sr.append(dateTimeField.getType());
+        sr.append("\" shortDateInput=");
+        sr.append(Boolean.toString(shortDateInput));
+        sr.append(" timeDropdownParamName=\"");
+        sr.append(timeDropdownParamName);
+        sr.append("\" defaultDateTimeString=\"");
+        sr.append(defaultDateTimeString);
+        sr.append("\" localizedIconTitle=\"");
+        sr.append(localizedIconTitle);
+        sr.append("\" timeDropdown=\"");
+        sr.append(timeDropdown);
+        sr.append("\" timeHourName=\"");
+        sr.append(timeHourName);
+        sr.append("\" classString=\"");
+        sr.append(classString);
+        sr.append("\" hour1=");
+        sr.append(Integer.toString(hour1));
+        sr.append(" hour2=");
+        sr.append(Integer.toString(hour2));
+        sr.append(" timeMinutesName=\"");
+        sr.append(timeMinutesName);
+        sr.append("\" minutes=");
+        sr.append(Integer.toString(minutes));
+        sr.append(" isTwelveHour=");
+        sr.append(Boolean.toString(isTwelveHour));
+        sr.append(" ampmName=\"");
+        sr.append(ampmName);
+        sr.append("\" amSelected=\"");
+        sr.append(amSelected);
+        sr.append("\" pmSelected=\"");
+        sr.append(pmSelected);
+        sr.append("\" compositeType=\"");
+        sr.append(compositeType);
+        sr.append("\" formName=\"");
+        sr.append(formName);
+        sr.append("\" mask=\"");
+        sr.append(formattedMask);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.addAsterisks(writer, context, modelFormField);
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
+        ModelFormField modelFormField = dropDownField.getModelFormField();
+        ModelForm modelForm = modelFormField.getModelForm();
+        String currentValue = modelFormField.getEntry(context);
+        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+        ModelFormField.AutoComplete autoComplete = dropDownField.getAutoComplete();
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        Integer textSize = Integer.valueOf(0);
+        if (UtilValidate.isNotEmpty(dropDownField.getTextSize())) {
+            try {
+                textSize = Integer.parseInt(dropDownField.getTextSize());
+            } catch (NumberFormatException nfe) {
+                Debug.logError(nfe, "Error reading size of a field fieldName=" + dropDownField.getModelFormField().getFieldName() + " FormName= " + dropDownField.getModelFormField().getModelForm().getName(), module);
+            }
+            if (textSize > 0 && UtilValidate.isNotEmpty(currentValue) && currentValue.length() > textSize) {
+                currentValue = currentValue.substring(0, textSize - 8) + "..." + currentValue.substring(currentValue.length() - 5);
+            }
+        }
+        boolean ajaxEnabled = autoComplete != null && this.javaScriptEnabled;
+        String className = "";
+        String alert = "false";
+        String name = modelFormField.getParameterName(context);
+        String id = modelFormField.getCurrentContainerId(context);
+        String multiple = dropDownField.getAllowMultiple() ? "multiple" : "";
+        String otherFieldName = "";
+        String formName = modelForm.getName();
+        String size = dropDownField.getSize();
+        String dDFCurrent = dropDownField.getCurrent();
+        String firstInList = "";
+        String explicitDescription = "";
+        String allowEmpty = "";
+        StringBuilder options = new StringBuilder();
+        StringBuilder ajaxOptions = new StringBuilder();
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        //check for required field style on single forms
+        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
+            String requiredStyle = modelFormField.getRequiredFieldStyle();
+            if (UtilValidate.isEmpty(requiredStyle))
+                requiredStyle = "required";
+            if (UtilValidate.isEmpty(className))
+                className = requiredStyle;
+            else
+                className = requiredStyle + " " + className;
+        }
+        String currentDescription = null;
+        if (UtilValidate.isNotEmpty(currentValue)) {
+            for (ModelFormField.OptionValue optionValue : allOptionValues) {
+                if (optionValue.getKey().equals(currentValue)) {
+                    currentDescription = optionValue.getDescription();
+                    break;
+                }
+            }
+        }
+        int otherFieldSize = dropDownField.getOtherFieldSize();
+        if (otherFieldSize > 0) {
+            otherFieldName = dropDownField.getParameterNameOther(context);
+        }
+        // if the current value should go first, stick it in
+        if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
+            firstInList = "first-in-list";
+        }
+        explicitDescription = (currentDescription != null ? currentDescription : dropDownField.getCurrentDescription(context));
+        if (UtilValidate.isEmpty(explicitDescription)) {
+            explicitDescription = (FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues));
+        }
+        if (textSize > 0 && UtilValidate.isNotEmpty(explicitDescription) && explicitDescription.length() > textSize) {
+            explicitDescription = explicitDescription.substring(0, textSize - 8) + "..." + explicitDescription.substring(explicitDescription.length() - 5);
+        }
+        explicitDescription = encode(explicitDescription, modelFormField, context);
+        // if allow empty is true, add an empty option
+        if (dropDownField.getAllowEmpty()) {
+            allowEmpty = "Y";
+        }
+        List<String> currentValueList = null;
+        if (UtilValidate.isNotEmpty(currentValue) && dropDownField.getAllowMultiple()) {
+            // If currentValue is Array, it will start with [
+            if (currentValue.startsWith("[")) {
+                currentValueList = StringUtil.toList(currentValue);
+            } else {
+                currentValueList = UtilMisc.toList(currentValue);
+            }
+        }
+        options.append("[");
+        Iterator<ModelFormField.OptionValue> optionValueIter = allOptionValues.iterator();
+        int count = 0;
+        while (optionValueIter.hasNext()) {
+            ModelFormField.OptionValue optionValue = optionValueIter.next();
+            if (options.length() > 1) {
+                options.append(",");
+            }
+            options.append("{'key':'");
+            String key = encode(optionValue.getKey(), modelFormField, context);
+            options.append(key);
+            options.append("'");
+            options.append(",'description':'");
+            String description = optionValue.getDescription();
+            if (textSize > 0 && description.length() > textSize) {
+                description = description.substring(0, textSize - 8) + "..." + description.substring(description.length() - 5);
+            }
+            options.append(encode(description, modelFormField, context));
+
+            if (UtilValidate.isNotEmpty(currentValueList)) {
+                options.append("'");
+                options.append(",'selected':'");
+                if (currentValueList.contains(optionValue.getKey())) {
+                    options.append("selected");
+                } else {
+                    options.append("");
+                }
+            }
+
+            options.append("'}");
+            if (ajaxEnabled) {
+                count++;
+                ajaxOptions.append(optionValue.getKey()).append(": ");
+                ajaxOptions.append(" '").append(optionValue.getDescription()).append("'");
+                if (count != allOptionValues.size()) {
+                    ajaxOptions.append(", ");
+                }
+            }
+        }
+        options.append("]");
+        String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
+        String otherValue = "", fieldName = "";
+        // Adapted from work by Yucca Korpela
+        // http://www.cs.tut.fi/~jkorpela/forms/combo.html
+        if (otherFieldSize > 0) {
+            fieldName = modelFormField.getParameterName(context);
+            Map<String, ? extends Object> dataMap = modelFormField.getMap(context);
+            if (dataMap == null) {
+                dataMap = context;
+            }
+            Object otherValueObj = dataMap.get(otherFieldName);
+            otherValue = (otherValueObj == null) ? "" : otherValueObj.toString();
+        }
+        String frequency = "";
+        String minChars = "";
+        String choices = "";
+        String autoSelect = "";
+        String partialSearch = "";
+        String partialChars = "";
+        String ignoreCase = "";
+        String fullSearch = "";
+        if (ajaxEnabled) {
+            frequency = autoComplete.getFrequency();
+            minChars = autoComplete.getMinChars();
+            choices = autoComplete.getChoices();
+            autoSelect = autoComplete.getAutoSelect();
+            partialSearch = autoComplete.getPartialSearch();
+            partialChars = autoComplete.getPartialChars();
+            ignoreCase = autoComplete.getIgnoreCase();
+            fullSearch = autoComplete.getFullSearch();
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderDropDownField ");
+        sr.append("name=\"");
+        sr.append(name);
+        sr.append("\" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" multiple=\"");
+        sr.append(multiple);
+        sr.append("\" formName=\"");
+        sr.append(formName);
+        sr.append("\" otherFieldName=\"");
+        sr.append(otherFieldName);
+        sr.append("\" event=\"");
+        if (event != null) {
+            sr.append(event);
+        }
+        sr.append("\" action=\"");
+        if (action != null) {
+            sr.append(action);
+        }
+        sr.append("\" size=\"");
+        sr.append(size);
+        sr.append("\" firstInList=\"");
+        sr.append(firstInList);
+        sr.append("\" currentValue=\"");
+        sr.append(currentValue);
+        sr.append("\" explicitDescription=\"");
+        sr.append(explicitDescription);
+        sr.append("\" allowEmpty=\"");
+        sr.append(allowEmpty);
+        sr.append("\" options=");
+        sr.append(options.toString());
+        sr.append(" fieldName=\"");
+        sr.append(fieldName);
+        sr.append("\" otherFieldName=\"");
+        sr.append(otherFieldName);
+        sr.append("\" otherValue=\"");
+        sr.append(otherValue);
+        sr.append("\" otherFieldSize=");
+        sr.append(Integer.toString(otherFieldSize));
+        sr.append(" dDFCurrent=\"");
+        sr.append(dDFCurrent);
+        sr.append("\" ajaxEnabled=");
+        sr.append(Boolean.toString(ajaxEnabled));
+        sr.append(" noCurrentSelectedKey=\"");
+        sr.append(noCurrentSelectedKey);
+        sr.append("\" ajaxOptions=\"");
+        sr.append(ajaxOptions.toString());
+        sr.append("\" frequency=\"");
+        sr.append(frequency);
+        sr.append("\" minChars=\"");
+        sr.append(minChars);
+        sr.append("\" choices=\"");
+        sr.append(choices);
+        sr.append("\" autoSelect=\"");
+        sr.append(autoSelect);
+        sr.append("\" partialSearch=\"");
+        sr.append(partialSearch);
+        sr.append("\" partialChars=\"");
+        sr.append(partialChars);
+        sr.append("\" ignoreCase=\"");
+        sr.append(ignoreCase);
+        sr.append("\" fullSearch=\"");
+        sr.append(fullSearch);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        ModelFormField.SubHyperlink subHyperlink = dropDownField.getSubHyperlink();
+        if (subHyperlink != null && subHyperlink.shouldUse(context)) {
+            makeHyperlinkString(writer, subHyperlink, context);
+        }
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
+        ModelFormField modelFormField = checkField.getModelFormField();
+        modelFormField.getModelForm();
+        String currentValue = modelFormField.getEntry(context);
+        Boolean allChecked = checkField.isAllChecked(context);
+        String id = modelFormField.getCurrentContainerId(context);
+        String className = "";
+        String alert = "false";
+        String name = modelFormField.getParameterName(context);
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        StringBuilder items = new StringBuilder();
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        List<ModelFormField.OptionValue> allOptionValues = checkField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+        items.append("[");
+        for (ModelFormField.OptionValue optionValue : allOptionValues) {
+            if (items.length() > 1) {
+                items.append(",");
+            }
+            items.append("{'value':'");
+            items.append(optionValue.getKey());
+            items.append("', 'description':'" + encode(optionValue.getDescription(), modelFormField, context));
+            items.append("'}");
+        }
+        items.append("]");
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderCheckField ");
+        sr.append("items=");
+        sr.append(items.toString());
+        sr.append(" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" allChecked=");
+        sr.append((allChecked != null ? Boolean.toString(allChecked) : "\"\""));
+        sr.append(" currentValue=\"");
+        sr.append(currentValue);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" event=\"");
+        if (event != null) {
+            sr.append(event);
+        }
+        sr.append("\" action=\"");
+        if (action != null) {
+            sr.append(action);
+        }
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
+        ModelFormField modelFormField = radioField.getModelFormField();
+        modelFormField.getModelForm();
+        List<ModelFormField.OptionValue> allOptionValues = radioField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+        String currentValue = modelFormField.getEntry(context);
+        String className = "";
+        String alert = "false";
+        String name = modelFormField.getParameterName(context);
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        StringBuilder items = new StringBuilder();
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        String noCurrentSelectedKey = radioField.getNoCurrentSelectedKey(context);
+        items.append("[");
+        for (ModelFormField.OptionValue optionValue : allOptionValues) {
+            if (items.length() > 1) {
+                items.append(",");
+            }
+            items.append("{'key':'");
+            items.append(optionValue.getKey());
+            items.append("', 'description':'" + encode(optionValue.getDescription(), modelFormField, context));
+            items.append("'}");
+        }
+        items.append("]");
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderRadioField ");
+        sr.append("items=");
+        sr.append(items.toString());
+        sr.append(" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" currentValue=\"");
+        sr.append(currentValue);
+        sr.append("\" noCurrentSelectedKey=\"");
+        sr.append(noCurrentSelectedKey);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" event=\"");
+        if (event != null) {
+            sr.append(event);
+        }
+        sr.append("\" action=\"");
+        if (action != null) {
+            sr.append(action);
+        }
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
+        ModelFormField modelFormField = submitField.getModelFormField();
+        ModelForm modelForm = modelFormField.getModelForm();
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        String title = modelFormField.getTitle(context);
+        String name = modelFormField.getParameterName(context);
+        String buttonType = submitField.getButtonType();
+        String formName = FormRenderer.getCurrentFormName(modelForm, context);
+        String imgSrc = submitField.getImageLocation(context);
+        String confirmation = submitField.getConfirmation(context);
+        String className = "";
+        String alert = "false";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        String formId = FormRenderer.getCurrentContainerId(modelForm, context);
+        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnSubmitUpdateAreas();
+        // This is here for backwards compatibility. Use on-event-update-area
+        // elements instead.
+        String backgroundSubmitRefreshTarget = submitField.getBackgroundSubmitRefreshTarget(context);
+        if (UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) {
+            if (updateAreas == null) {
+                updateAreas = new LinkedList<ModelForm.UpdateArea>();
+            }
+            updateAreas.add(new ModelForm.UpdateArea("submit", formId, backgroundSubmitRefreshTarget));
+        }
+        boolean ajaxEnabled = (UtilValidate.isNotEmpty(updateAreas) || UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) && this.javaScriptEnabled;
+        String ajaxUrl = "";
+        if (ajaxEnabled) {
+            ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "", context);
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderSubmitField ");
+        sr.append("buttonType=\"");
+        sr.append(buttonType);
+        sr.append("\" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" formName=\"");
+        sr.append(formName);
+        sr.append("\" title=\"");
+        sr.append(encode(title, modelFormField, context));
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" event=\"");
+        if (event != null) {
+            sr.append(event);
+        }
+        sr.append("\" action=\"");
+        if (action != null) {
+            sr.append(action);
+        }
+        sr.append("\" imgSrc=\"");
+        sr.append(imgSrc);
+        sr.append("\" containerId=\"");
+        if (ajaxEnabled) {
+            sr.append(formId);
+        }
+        sr.append("\" confirmation =\"");
+        sr.append(confirmation);
+        sr.append("\" ajaxUrl=\"");
+        if (ajaxEnabled) {
+            sr.append(ajaxUrl);
+        }
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
+        ModelFormField modelFormField = resetField.getModelFormField();
+        String name = modelFormField.getParameterName(context);
+        String className = "";
+        String alert = "false";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        String title = modelFormField.getTitle(context);
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderResetField ");
+        sr.append(" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" title=\"");
+        sr.append(title);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
+        ModelFormField modelFormField = hiddenField.getModelFormField();
+        String value = hiddenField.getValue(context);
+        this.renderHiddenField(writer, context, modelFormField, value);
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
+        String name = modelFormField.getParameterName(context);
+        String action = modelFormField.getAction(context);
+        String event = modelFormField.getEvent();
+        String id = modelFormField.getCurrentContainerId(context);
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderHiddenField ");
+        sr.append(" name=\"");
+        sr.append(name);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" event=\"");
+        if (event != null) {
+            sr.append(event);
+        }
+        sr.append("\" action=\"");
+        if (action != null) {
+            sr.append(action);
+        }
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) {
+        // do nothing, it's an ignored field; could add a comment or something if we wanted to
+    }
+
+    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        String titleText = modelFormField.getTitle(context);
+        String style = modelFormField.getTitleStyle();
+        String id = modelFormField.getCurrentContainerId(context);
+        StringBuilder sb = new StringBuilder();
+        if (UtilValidate.isNotEmpty(titleText)) {
+            if (" ".equals(titleText)) {
+                executeMacro(writer, "<@renderFormatEmptySpace />");
+            } else {
+                titleText = UtilHttp.encodeAmpersands(titleText);
+                titleText = encode(titleText, modelFormField, context);
+                if (UtilValidate.isNotEmpty(modelFormField.getHeaderLink())) {
+                    StringBuilder targetBuffer = new StringBuilder();
+                    FlexibleStringExpander target = FlexibleStringExpander.getInstance(modelFormField.getHeaderLink());
+                    String fullTarget = target.expandString(context);
+                    targetBuffer.append(fullTarget);
+                    String targetType = CommonWidgetModels.Link.DEFAULT_URL_MODE;
+                    if (UtilValidate.isNotEmpty(targetBuffer.toString()) && targetBuffer.toString().toLowerCase().startsWith("javascript:")) {
+                        targetType = "plain";
+                    }
+                    StringWriter sr = new StringWriter();
+                    makeHyperlinkString(sr, modelFormField.getHeaderLinkStyle(), targetType, targetBuffer.toString(), null, titleText, "", modelFormField, this.request, this.response, context, "");
+                    String title = sr.toString().replace("\"", "\'");
+                    sr = new StringWriter();
+                    sr.append("<@renderHyperlinkTitle ");
+                    sr.append(" name=\"");
+                    sr.append(modelFormField.getModelForm().getName());
+                    sr.append("\" title=\"");
+                    sr.append(FreeMarkerWorker.encodeDoubleQuotes(title));
+                    sr.append("\" />");
+                    executeMacro(writer, sr.toString());
+                } else if (modelFormField.isSortField()) {
+                    renderSortField(writer, context, modelFormField, titleText);
+                } else if (modelFormField.isRowSubmit()) {
+                    StringWriter sr = new StringWriter();
+                    sr.append("<@renderHyperlinkTitle ");
+                    sr.append(" name=\"");
+                    sr.append(modelFormField.getModelForm().getName());
+                    sr.append("\" title=\"");
+                    sr.append(titleText);
+                    sr.append("\" showSelectAll=\"Y\"/>");
+                    executeMacro(writer, sr.toString());
+                } else {
+                    sb.append(titleText);
+                }
+            }
+        }
+        if (!sb.toString().isEmpty()) {
+            //check for required field style on single forms
+            if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
+                String requiredStyle = modelFormField.getRequiredFieldStyle();
+                if (UtilValidate.isNotEmpty(requiredStyle)) {
+                    style = requiredStyle;
+                }
+            }
+            StringWriter sr = new StringWriter();
+            sr.append("<@renderFieldTitle ");
+            sr.append(" style=\"");
+            sr.append(style);
+            String displayHelpText = UtilProperties.getPropertyValue("widget.properties", "widget.form.displayhelpText");
+            if ("Y".equals(displayHelpText)) {
+                Delegator delegator = WidgetWorker.getDelegator(context);
+                Locale locale = (Locale) context.get("locale");
+                String entityName = modelFormField.getEntityName();
+                String fieldName = modelFormField.getFieldName();
+                String helpText = UtilHelpText.getEntityFieldDescription(entityName, fieldName, delegator, locale);
+
+                sr.append("\" fieldHelpText=\"");
+                sr.append(FreeMarkerWorker.encodeDoubleQuotes(helpText));
+            }
+            sr.append("\" title=\"");
+            sr.append(sb.toString());
+            if (UtilValidate.isNotEmpty(id)) {
+                sr.append("\" id=\"");
+                sr.append(id);
+                sr.append("_title");
+                // Render "for"
+                sr.append("\" for=\"");
+                sr.append(id);
+            }
+            sr.append("\" />");
+            executeMacro(writer, sr.toString());
+        }
+    }
+
+    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        renderFieldTitle(writer, context, modelFormField);
+    }
+
+    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+        renderBeginningBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+        String targetType = modelForm.getTargetType();
+        String targ = modelForm.getTarget(context, targetType);
+        StringBuilder linkUrl = new StringBuilder();
+        if (UtilValidate.isNotEmpty(targ)) {
+            //this.appendOfbizUrl(writer, "/" + targ);
+            WidgetWorker.buildHyperlinkUrl(linkUrl, targ, targetType, null, null, false, false, true, request, response, context);
+        }
+        String formType = modelForm.getType();
+        String targetWindow = modelForm.getTargetWindow(context);
+        String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
+        String containerStyle = modelForm.getContainerStyle();
+        String autocomplete = "";
+        String name = FormRenderer.getCurrentFormName(modelForm, context);
+        String viewIndexField = modelForm.getMultiPaginateIndexField(context);
+        String viewSizeField = modelForm.getMultiPaginateSizeField(context);
+        int viewIndex = Paginator.getViewIndex(modelForm, context);
+        int viewSize = Paginator.getViewSize(modelForm, context);
+        boolean useRowSubmit = modelForm.getUseRowSubmit();
+        if (!modelForm.getClientAutocompleteFields()) {
+            autocomplete = "off";
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormOpen ");
+        sr.append(" linkUrl=\"");
+        sr.append(linkUrl);
+        sr.append("\" formType=\"");
+        sr.append(formType);
+        sr.append("\" targetWindow=\"");
+        sr.append(targetWindow);
+        sr.append("\" containerId=\"");
+        sr.append(containerId);
+        sr.append("\" containerStyle=\"");
+        sr.append(containerStyle);
+        sr.append("\" autocomplete=\"");
+        sr.append(autocomplete);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" viewIndexField=\"");
+        sr.append(viewIndexField);
+        sr.append("\" viewSizeField=\"");
+        sr.append(viewSizeField);
+        sr.append("\" viewIndex=\"");
+        sr.append(Integer.toString(viewIndex));
+        sr.append("\" viewSize=\"");
+        sr.append(Integer.toString(viewSize));
+        sr.append("\" useRowSubmit=");
+        sr.append(Boolean.toString(useRowSubmit));
+        sr.append(" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        String focusFieldName = FormRenderer.getFocusFieldName(modelForm, context);
+        String formName = FormRenderer.getCurrentFormName(modelForm, context);
+        String containerId = FormRenderer.getCurrentContainerId(modelForm, context);
+        String hasRequiredField = "";
+        for (ModelFormField formField : modelForm.getFieldList()) {
+            if (formField.getRequiredField()) {
+                hasRequiredField = "Y";
+                break;
+            }
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormClose ");
+        sr.append(" focusFieldName=\"");
+        sr.append(focusFieldName);
+        sr.append("\" formName=\"");
+        sr.append(formName);
+        sr.append("\" containerId=\"");
+        sr.append(containerId);
+        sr.append("\" hasRequiredField=\"");
+        sr.append(hasRequiredField);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        renderEndingBoundaryComment(writer, "Form Widget - Form Element", modelForm);
+    }
+
+    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        //FIXME copy from HtmlFormRenderer.java (except for the closing form tag itself, that is now converted)
+        Iterator<ModelFormField> submitFields = modelForm.getMultiSubmitFields().iterator();
+        while (submitFields.hasNext()) {
+            ModelFormField submitField = submitFields.next();
+            if (submitField != null && submitField.shouldUse(context)) {
+                // Threw this in that as a hack to keep the submit button from expanding the first field
+                // Needs a more rugged solution
+                // WARNING: this method (renderMultiFormClose) must be called after the
+                // table that contains the list has been closed (to avoid validation errors) so
+                // we cannot call here the methods renderFormatItemRowCell*: for this reason
+                // they are now commented.
+                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
+                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);
+                // this.renderFormatItemRowCellOpen(writer, context, modelForm, submitField);
+                submitField.renderFieldString(writer, context, this);
+                // this.renderFormatItemRowCellClose(writer, context, modelForm, submitField);
+            }
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderMultiFormClose />");
+        executeMacro(writer, sr.toString());
+        // see if there is anything that needs to be added outside of the multi-form
+        Map<String, Object> wholeFormContext = UtilGenerics.checkMap(context.get("wholeFormContext"));
+        Appendable postMultiFormWriter = wholeFormContext != null ? (Appendable) wholeFormContext.get("postMultiFormWriter") : null;
+        if (postMultiFormWriter != null) {
+            writer.append(postMultiFormWriter.toString());
+            appendWhitespace(writer);
+        }
+        renderEndingBoundaryComment(writer, "Form Widget - Form Element (Multi)", modelForm);
+    }
+
+    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        Map<String, Object> inputFields = UtilGenerics.checkMap(context.get("requestParameters"));
+        Map<String, Object> queryStringMap = UtilGenerics.toMap(context.get("queryStringMap"));
+        if (UtilValidate.isNotEmpty(queryStringMap)) {
+            inputFields.putAll(queryStringMap);
+        }
+        if (modelForm.getType().equals("multi")) {
+            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
+        }
+        String queryString = UtilHttp.urlEncodeArgs(inputFields);
+        context.put("_QBESTRING_", queryString);
+        renderBeginningBoundaryComment(writer, "Form Widget", modelForm);
+        if (this.renderPagination) {
+            this.renderNextPrev(writer, context, modelForm);
+        }
+        List<ModelFormField> childFieldList = modelForm.getFieldList();
+        List<String> columnStyleList = new LinkedList<String>();
+        List<String> fieldNameList = new LinkedList<String>();
+        for (ModelFormField childField : childFieldList) {
+            int childFieldType = childField.getFieldInfo().getFieldType();
+            if (childFieldType == FieldInfo.HIDDEN || childFieldType == FieldInfo.IGNORED) {
+                continue;
+            }
+            String areaStyle = childField.getTitleAreaStyle();
+            if (UtilValidate.isEmpty(areaStyle)) {
+                areaStyle = "";
+            }
+            if (fieldNameList.contains(childField.getName())) {
+                if (UtilValidate.isNotEmpty(areaStyle)) {
+                    columnStyleList.set(fieldNameList.indexOf(childField.getName()), areaStyle);
+                }
+            } else {
+                columnStyleList.add(areaStyle);
+                fieldNameList.add(childField.getName());
+            }
+        }
+        columnStyleList = StringUtil.quoteStrList(columnStyleList);
+        String columnStyleListString = StringUtil.join(columnStyleList, ", ");
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatListWrapperOpen ");
+        sr.append(" formName=\"");
+        sr.append(modelForm.getName());
+        sr.append("\" style=\"");
+        sr.append(FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context));
+        sr.append("\" columnStyles=[");
+        if (UtilValidate.isNotEmpty(columnStyleListString)) {
+            // this is a fix for forms with no fields
+            sr.append(columnStyleListString);
+        }
+        sr.append("] />");
+        executeMacro(writer, sr.toString());
+
+    }
+
+    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatListWrapperClose");
+        sr.append(" formName=\"");
+        sr.append(modelForm.getName());
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        if (this.renderPagination) {
+            this.renderNextPrev(writer, context, modelForm);
+        }
+        renderEndingBoundaryComment(writer, "Form Widget - Formal List Wrapper", modelForm);
+    }
+
+    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        String headerStyle = FlexibleStringExpander.expandString(modelForm.getHeaderRowStyle(), context);
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatHeaderRowOpen ");
+        sr.append(" style=\"");
+        sr.append(headerStyle);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatHeaderRowClose />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
+        String areaStyle = modelFormField.getTitleAreaStyle();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatHeaderRowCellOpen ");
+        sr.append(" style=\"");
+        sr.append(areaStyle);
+        sr.append("\" positionSpan=");
+        sr.append(Integer.toString(positionSpan));
+        sr.append(" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatHeaderRowCellClose />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        String areaStyle = modelForm.getFormTitleAreaStyle();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatHeaderRowFormCellOpen ");
+        sr.append(" style=\"");
+        sr.append(areaStyle);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatHeaderRowFormCellClose />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {
+        String titleStyle = modelFormField.getTitleStyle();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatHeaderRowFormCellTitleSeparator ");
+        sr.append(" style=\"");
+        sr.append(titleStyle);
+        sr.append("\" isLast=");
+        sr.append(Boolean.toString(isLast));
+        sr.append(" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        Integer itemIndex = (Integer) context.get("itemIndex");
+        String altRowStyles = "";
+        String evenRowStyle = "";
+        String oddRowStyle = "";
+        if (itemIndex != null) {
+            altRowStyles = modelForm.getStyleAltRowStyle(context);
+            if (itemIndex.intValue() % 2 == 0) {
+                evenRowStyle = modelForm.getEvenRowStyle();
+            } else {
+                oddRowStyle = FlexibleStringExpander.expandString(modelForm.getOddRowStyle(), context);
+            }
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatItemRowOpen ");
+        sr.append(" formName=\"");
+        sr.append(modelForm.getName());
+        sr.append("\" itemIndex=");
+        sr.append(Integer.toString(itemIndex));
+        sr.append(" altRowStyles=\"");
+        sr.append(altRowStyles);
+        sr.append("\" evenRowStyle=\"");
+        sr.append(evenRowStyle);
+        sr.append("\" oddRowStyle=\"");
+        sr.append(oddRowStyle);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatItemRowClose ");
+        sr.append(" formName=\"");
+        sr.append(modelForm.getName());
+        sr.append("\"/>");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
+        String areaStyle = modelFormField.getWidgetAreaStyle();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatItemRowCellOpen ");
+        sr.append(" fieldName=\"");
+        sr.append(modelFormField.getName());
+        sr.append("\" style=\"");
+        sr.append(areaStyle);
+        sr.append("\" positionSpan=");
+        sr.append(Integer.toString(positionSpan));
+        sr.append(" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatItemRowCellClose");
+        sr.append(" fieldName=\"");
+        sr.append(modelFormField.getName());
+        sr.append("\"/>");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        String areaStyle = modelForm.getFormTitleAreaStyle();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatItemRowFormCellOpen ");
+        sr.append(" style=\"");
+        sr.append(areaStyle);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatItemRowFormCellClose />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        String style = FlexibleStringExpander.expandString(modelForm.getDefaultTableStyle(), context);
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatSingleWrapperOpen ");
+        sr.append(" formName=\"");
+        sr.append(modelForm.getName());
+        sr.append("\" style=\"");
+        sr.append(style);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatSingleWrapperClose");
+        sr.append(" formName=\"");
+        sr.append(modelForm.getName());
+        sr.append("\"/>");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatFieldRowOpen />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatFieldRowClose />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        String style = modelFormField.getTitleAreaStyle();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatFieldRowTitleCellOpen ");
+        sr.append(" style=\"");
+        sr.append(style);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatFieldRowTitleCellClose />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+    }
+
+    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
+        String areaStyle = modelFormField.getWidgetAreaStyle();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatFieldRowWidgetCellOpen ");
+        sr.append(" positionSpan=");
+        sr.append(Integer.toString(positionSpan));
+        sr.append(" style=\"");
+        sr.append(areaStyle);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatFieldRowWidgetCellClose />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFormatEmptySpace />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
+        ModelFormField modelFormField = textFindField.getModelFormField();
+        String defaultOption = textFindField.getDefaultOption();
+        String className = "";
+        String alert = "false";
+        String opEquals = "";
+        String opBeginsWith = "";
+        String opContains = "";
+        String opIsEmpty = "";
+        String opNotEqual = "";
+        String name = modelFormField.getParameterName(context);
+        String size = Integer.toString(textFindField.getSize());
+        String maxlength = "";
+        String autocomplete = "";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        Locale locale = (Locale) context.get("locale");
+        if (!textFindField.getHideOptions()) {
+            opEquals = UtilProperties.getMessage("conditional", "equals", locale);
+            opBeginsWith = UtilProperties.getMessage("conditional", "begins_with", locale);
+            opContains = UtilProperties.getMessage("conditional", "contains", locale);
+            opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
+            opNotEqual = UtilProperties.getMessage("conditional", "not_equal", locale);
+        }
+        String value = modelFormField.getEntry(context, textFindField.getDefaultValue(context));
+        if (value == null) {
+            value = "";
+        }
+        if (textFindField.getMaxlength() != null) {
+            maxlength = textFindField.getMaxlength().toString();
+        }
+        if (!textFindField.getClientAutocompleteField()) {
+            autocomplete = "off";
+        }
+        String titleStyle = "";
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            titleStyle = modelFormField.getTitleStyle();
+        }
+        String ignoreCase = UtilProperties.getMessage("conditional", "ignore_case", locale);
+        boolean ignCase = textFindField.getIgnoreCase();
+        boolean hideIgnoreCase = textFindField.getHideIgnoreCase();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderTextFindField ");
+        sr.append(" name=\"");
+        sr.append(name);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" defaultOption=\"");
+        sr.append(defaultOption);
+        sr.append("\" opEquals=\"");
+        sr.append(opEquals);
+        sr.append("\" opBeginsWith=\"");
+        sr.append(opBeginsWith);
+        sr.append("\" opContains=\"");
+        sr.append(opContains);
+        sr.append("\" opIsEmpty=\"");
+        sr.append(opIsEmpty);
+        sr.append("\" opNotEqual=\"");
+        sr.append(opNotEqual);
+        sr.append("\" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" size=\"");
+        sr.append(size);
+        sr.append("\" maxlength=\"");
+        sr.append(maxlength);
+        sr.append("\" autocomplete=\"");
+        sr.append(autocomplete);
+        sr.append("\" titleStyle=\"");
+        sr.append(titleStyle);
+        sr.append("\" hideIgnoreCase=");
+        sr.append(Boolean.toString(hideIgnoreCase));
+        sr.append(" ignCase=");
+        sr.append(Boolean.toString(ignCase));
+        sr.append(" ignoreCase=\"");
+        sr.append(ignoreCase);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
+        ModelFormField modelFormField = rangeFindField.getModelFormField();
+        Locale locale = (Locale) context.get("locale");
+        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
+        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
+        String opGreaterThanEquals = UtilProperties.getMessage("conditional", "greater_than_equals", locale);
+        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
+        String opLessThanEquals = UtilProperties.getMessage("conditional", "less_than_equals", locale);
+        //String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
+        String className = "";
+        String alert = "false";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        String name = modelFormField.getParameterName(context);
+        String size = Integer.toString(rangeFindField.getSize());
+        String value = modelFormField.getEntry(context, rangeFindField.getDefaultValue(context));
+        if (value == null) {
+            value = "";
+        }
+        Integer maxlength = rangeFindField.getMaxlength();
+        String autocomplete = "";
+
+        if (!rangeFindField.getClientAutocompleteField()) {
+            autocomplete = "off";
+        }
+        String titleStyle = modelFormField.getTitleStyle();
+
+        if (titleStyle == null) {
+            titleStyle = "";
+        }
+        String defaultOptionFrom = rangeFindField.getDefaultOptionFrom();
+        String value2 = modelFormField.getEntry(context);
+        if (value2 == null) {
+            value2 = "";
+        }
+        String defaultOptionThru = rangeFindField.getDefaultOptionThru();
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderRangeFindField ");
+        sr.append(" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" size=\"");
+        sr.append(size);
+        sr.append("\" maxlength=\"");
+        if (maxlength != null) {
+            sr.append(Integer.toString(maxlength));
+        }
+        sr.append("\" autocomplete=\"");
+        sr.append(autocomplete);
+        sr.append("\" titleStyle=\"");
+        sr.append(titleStyle);
+        sr.append("\" defaultOptionFrom=\"");
+        sr.append(defaultOptionFrom);
+        sr.append("\" opEquals=\"");
+        sr.append(opEquals);
+        sr.append("\" opGreaterThan=\"");
+        sr.append(opGreaterThan);
+        sr.append("\" opGreaterThanEquals=\"");
+        sr.append(opGreaterThanEquals);
+        sr.append("\" opLessThan=\"");
+        sr.append(opLessThan);
+        sr.append("\" opLessThanEquals=\"");
+        sr.append(opLessThanEquals);
+        sr.append("\" value2=\"");
+        sr.append(value2);
+        sr.append("\" defaultOptionThru=\"");
+        sr.append(defaultOptionThru);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
+        ModelFormField modelFormField = dateFindField.getModelFormField();
+        Locale locale = (Locale) context.get("locale");
+        String opEquals = UtilProperties.getMessage("conditional", "equals", locale);
+        String opGreaterThan = UtilProperties.getMessage("conditional", "greater_than", locale);
+        String opSameDay = UtilProperties.getMessage("conditional", "same_day", locale);
+        String opGreaterThanFromDayStart = UtilProperties.getMessage("conditional", "greater_than_from_day_start", locale);
+        String opLessThan = UtilProperties.getMessage("conditional", "less_than", locale);
+        String opUpToDay = UtilProperties.getMessage("conditional", "up_to_day", locale);
+        String opUpThruDay = UtilProperties.getMessage("conditional", "up_thru_day", locale);
+        String opIsEmpty = UtilProperties.getMessage("conditional", "is_empty", locale);
+        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        }
+        String localizedInputTitle = "", localizedIconTitle = "";
+        String className = "";
+        String alert = "false";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        String name = modelFormField.getParameterName(context);
+        // the default values for a timestamp
+        int size = 25;
+        int maxlength = 30;
+        String dateType = dateFindField.getType();
+        if ("date".equals(dateType)) {
+            size = maxlength = 10;
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatDate");
+            }
+        } else if ("time".equals(dateFindField.getType())) {
+            size = maxlength = 8;
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatTime");
+            }
+        } else {
+            if (uiLabelMap != null) {
+                localizedInputTitle = uiLabelMap.get("CommonFormatDateTime");
+            }
+        }
+        String value = modelFormField.getEntry(context, dateFindField.getDefaultValue(context));
+        if (value == null) {
+            value = "";
+        }
+        // search for a localized label for the icon
+        if (uiLabelMap != null) {
+            localizedIconTitle = uiLabelMap.get("CommonViewCalendar");
+        }
+        String formName = "";
+        String defaultDateTimeString = "";
+        StringBuilder imgSrc = new StringBuilder();
+        // add calendar pop-up button and seed data IF this is not a "time" type date-find
+        if (!"time".equals(dateFindField.getType())) {
+            ModelForm modelForm = modelFormField.getModelForm();
+            formName = FormRenderer.getCurrentFormName(modelForm, context);
+            defaultDateTimeString = UtilHttp.encodeBlanks(modelFormField.getEntry(context, dateFindField.getDefaultDateTimeString(context)));
+            this.appendContentUrl(imgSrc, "/images/cal.gif");
+        }
+        String defaultOptionFrom = dateFindField.getDefaultOptionFrom();
+        String defaultOptionThru = dateFindField.getDefaultOptionThru();
+        String value2 = modelFormField.getEntry(context);
+        if (value2 == null) {
+            value2 = "";
+        }
+        String titleStyle = "";
+        if (UtilValidate.isNotEmpty(modelFormField.getTitleStyle())) {
+            titleStyle = modelFormField.getTitleStyle();
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderDateFindField ");
+        sr.append(" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" localizedInputTitle=\"");
+        sr.append(localizedInputTitle);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" size=\"");
+        sr.append(Integer.toString(size));
+        sr.append("\" maxlength=\"");
+        sr.append(Integer.toString(maxlength));
+        sr.append("\" dateType=\"");
+        sr.append(dateType);
+        sr.append("\" formName=\"");
+        sr.append(formName);
+        sr.append("\" defaultDateTimeString=\"");
+        sr.append(defaultDateTimeString);
+        sr.append("\" imgSrc=\"");
+        sr.append(imgSrc.toString());
+        sr.append("\" localizedIconTitle=\"");
+        sr.append(localizedIconTitle);
+        sr.append("\" titleStyle=\"");
+        sr.append(titleStyle);
+        sr.append("\" defaultOptionFrom=\"");
+        sr.append(defaultOptionFrom);
+        sr.append("\" defaultOptionThru=\"");
+        sr.append(defaultOptionThru);
+        sr.append("\" opEquals=\"");
+        sr.append(opEquals);
+        sr.append("\" opSameDay=\"");
+        sr.append(opSameDay);
+        sr.append("\" opGreaterThanFromDayStart=\"");
+        sr.append(opGreaterThanFromDayStart);
+        sr.append("\" opGreaterThan=\"");
+        sr.append(opGreaterThan);
+        sr.append("\" opGreaterThan=\"");
+        sr.append(opGreaterThan);
+        sr.append("\" opLessThan=\"");
+        sr.append(opLessThan);
+        sr.append("\" opUpToDay=\"");
+        sr.append(opUpToDay);
+        sr.append("\" opUpThruDay=\"");
+        sr.append(opUpThruDay);
+        sr.append("\" opIsEmpty=\"");
+        sr.append(opIsEmpty);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
+        ModelFormField modelFormField = lookupField.getModelFormField();
+        String lookupFieldFormName = lookupField.getFormName(context);
+        String className = "";
+        String alert = "false";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        //check for required field style on single forms
+        if ("single".equals(modelFormField.getModelForm().getType()) && modelFormField.getRequiredField()) {
+            String requiredStyle = modelFormField.getRequiredFieldStyle();
+            if (UtilValidate.isEmpty(requiredStyle))
+                requiredStyle = "required";
+            if (UtilValidate.isEmpty(className))
+                className = requiredStyle;
+            else
+                className = requiredStyle + " " + className;
+        }
+        String name = modelFormField.getParameterName(context);
+        String value = modelFormField.getEntry(context, lookupField.getDefaultValue(context));
+        if (value == null) {
+            value = "";
+        }
+        String size = Integer.toString(lookupField.getSize());
+        Integer maxlength = lookupField.getMaxlength();
+        String id = modelFormField.getCurrentContainerId(context);
+        List<ModelForm.UpdateArea> updateAreas = modelFormField.getOnChangeUpdateAreas();
+        //add default ajax auto completer to all lookup fields
+        if (UtilValidate.isEmpty(updateAreas) && UtilValidate.isNotEmpty(lookupFieldFormName)) {
+            String autoCompleterTarget = null;
+            if (lookupFieldFormName.indexOf('?') == -1) {
+                autoCompleterTarget = lookupFieldFormName + "?";
+            } else {
+                autoCompleterTarget = lookupFieldFormName + "&amp;amp;";
+            }
+            autoCompleterTarget = autoCompleterTarget + "ajaxLookup=Y";
+            updateAreas = new LinkedList<ModelForm.UpdateArea>();
+            updateAreas.add(new ModelForm.UpdateArea("change", id, autoCompleterTarget));
+        }
+        boolean ajaxEnabled = UtilValidate.isNotEmpty(updateAreas) && this.javaScriptEnabled;
+        String autocomplete = "";
+        if (!lookupField.getClientAutocompleteField() || !ajaxEnabled) {
+            autocomplete = "off";
+        }
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        boolean readonly = lookupField.getReadonly();
+        // add lookup pop-up button
+        String descriptionFieldName = lookupField.getDescriptionFieldName();
+        ModelForm modelForm = modelFormField.getModelForm();
+        String formName = FormRenderer.getCurrentFormName(modelForm, context);
+        StringBuilder targetParameterIter = new StringBuilder();
+        StringBuilder imgSrc = new StringBuilder();
+        // FIXME: refactor using the StringUtils methods
+        List<String> targetParameterList = lookupField.getTargetParameterList();
+        targetParameterIter.append("[");
+        for (String targetParameter : targetParameterList) {
+            if (targetParameterIter.length() > 1) {
+                targetParameterIter.append(",");
+            }
+            targetParameterIter.append("'");
+            targetParameterIter.append(targetParameter);
+            targetParameterIter.append("'");
+        }
+        targetParameterIter.append("]");
+        this.appendContentUrl(imgSrc, "/images/fieldlookup.gif");
+        String ajaxUrl = "";
+        if (ajaxEnabled) {
+            ajaxUrl = createAjaxParamsFromUpdateAreas(updateAreas, "", context);
+        }
+        String lookupPresentation = lookupField.getLookupPresentation();
+        if (UtilValidate.isEmpty(lookupPresentation)) {
+            lookupPresentation = "";
+        }
+        String lookupHeight = lookupField.getLookupHeight();
+        if (UtilValidate.isEmpty(lookupHeight)) {
+            lookupHeight = "";
+        }
+        String lookupWidth = lookupField.getLookupWidth();
+        if (UtilValidate.isEmpty(lookupWidth)) {
+            lookupWidth = "";
+        }
+        String lookupPosition = lookupField.getLookupPosition();
+        if (UtilValidate.isEmpty(lookupPosition)) {
+            lookupPosition = "";
+        }
+        String fadeBackground = lookupField.getFadeBackground();
+        if (UtilValidate.isEmpty(fadeBackground)) {
+            fadeBackground = "false";
+        }
+        Boolean isInitiallyCollapsed = lookupField.getInitiallyCollapsed();
+        String clearText = "";
+        Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+        if (uiLabelMap != null) {
+            clearText = (String) uiLabelMap.get("CommonClear");
+        } else {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        }
+        Boolean showDescription = lookupField.getShowDescription();
+        if (showDescription == null) {
+            showDescription = "Y".equals(UtilProperties.getPropertyValue("widget", "widget.lookup.showDescription", "Y"));
+        }
+        // lastViewName, used by lookup to remember the real last view name
+        String lastViewName = request.getParameter("_LAST_VIEW_NAME_"); // Try to get it from parameters firstly
+        if (UtilValidate.isEmpty(lastViewName)) { // get from session
+            lastViewName = (String) request.getSession().getAttribute("_LAST_VIEW_NAME_");
+        }
+        if (UtilValidate.isEmpty(lastViewName)) {
+            lastViewName = "";
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderLookupField ");
+        sr.append(" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" size=\"");
+        sr.append(size);
+        sr.append("\" maxlength=\"");
+        sr.append((maxlength != null ? Integer.toString(maxlength) : ""));
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" event=\"");
+        if (event != null) {
+            sr.append(event);
+        }
+        sr.append("\" action=\"");
+        if (action != null) {
+            sr.append(action);
+        }
+        sr.append("\" readonly=");
+        sr.append(Boolean.toString(readonly));
+        sr.append(" autocomplete=\"");
+        sr.append(autocomplete);
+        sr.append("\" descriptionFieldName=\"");
+        sr.append(descriptionFieldName);
+        sr.append("\" formName=\"");
+        sr.append(formName);
+        sr.append("\" fieldFormName=\"");
+        sr.append(lookupFieldFormName);
+        sr.append("\" targetParameterIter=");
+        sr.append(targetParameterIter.toString());
+        sr.append(" imgSrc=\"");
+        sr.append(imgSrc.toString());
+        sr.append("\" ajaxUrl=\"");
+        sr.append(ajaxUrl);
+        sr.append("\" ajaxEnabled=");
+        sr.append(Boolean.toString(ajaxEnabled));
+        sr.append(" presentation=\"");
+        sr.append(lookupPresentation);
+        sr.append("\" height=\"");
+        sr.append(lookupHeight);
+        sr.append("\" width=\"");
+        sr.append(lookupWidth);
+        sr.append("\" position=\"");
+        sr.append(lookupPosition);
+        sr.append("\" fadeBackground=\"");
+        sr.append(fadeBackground);
+        sr.append("\" clearText=\"");
+        sr.append(clearText);
+        sr.append("\" showDescription=\"");
+        sr.append(Boolean.toString(showDescription));
+        sr.append("\" initiallyCollapsed=\"");
+        sr.append(Boolean.toString(isInitiallyCollapsed));
+        sr.append("\" lastViewName=\"");
+        sr.append(lastViewName);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.addAsterisks(writer, context, modelFormField);
+        this.makeHyperlinkString(writer, lookupField.getSubHyperlink(), context);
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    protected String appendExternalLoginKey(String target) {
+        String result = target;
+        String sessionId = ";jsessionid=" + request.getSession().getId();
+        int questionIndex = target.indexOf("?");
+        if (questionIndex == -1) {
+            result += sessionId;
+        } else {
+            result = result.replace("?", sessionId + "?");
+        }
+        return result;
+    }
+
+    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        boolean ajaxEnabled = false;
+        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnPaginateUpdateAreas();
+        String targetService = modelForm.getPaginateTarget(context);
+        if (this.javaScriptEnabled) {
+            if (UtilValidate.isNotEmpty(updateAreas)) {
+                ajaxEnabled = true;
+            }
+        }
+        if (targetService == null) {
+            targetService = "${targetService}";
+        }
+        if (UtilValidate.isEmpty(targetService) && updateAreas == null) {
+            Debug.logWarning("Cannot paginate because TargetService is empty for the form: " + modelForm.getName(), module);
+            return;
+        }
+        // get the parameterized pagination index and size fields
+        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
+        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
+        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
+        int viewIndex = Paginator.getViewIndex(modelForm, context);
+        int viewSize = Paginator.getViewSize(modelForm, context);
+        int listSize = Paginator.getListSize(context);
+        int lowIndex = Paginator.getLowIndex(context);
+        int highIndex = Paginator.getHighIndex(context);
+        int actualPageSize = Paginator.getActualPageSize(context);
+        // needed for the "Page" and "rows" labels
+        Map<String, String> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+        String pageLabel = "";
+        String commonDisplaying = "";
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        } else {
+            pageLabel = uiLabelMap.get("CommonPage");
+            Map<String, Integer> messageMap = UtilMisc.toMap("lowCount", Integer.valueOf(lowIndex + 1), "highCount", Integer.valueOf(lowIndex + actualPageSize), "total", Integer.valueOf(listSize));
+            commonDisplaying = UtilProperties.getMessage("CommonUiLabels", "CommonDisplaying", messageMap, (Locale) context.get("locale"));
+        }
+        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
+        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber))
+            viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
+        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber))
+            viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;
+        String str = (String) context.get("_QBESTRING_");
+        // strip legacy viewIndex/viewSize params from the query string
+        String queryString = UtilHttp.stripViewParamsFromQueryString(str, "" + paginatorNumber);
+        // strip parameterized index/size params from the query string
+        HashSet<String> paramNames = new HashSet<String>();
+        paramNames.add(viewIndexParam);
+        paramNames.add(viewSizeParam);
+        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);
+        String anchor = "";
+        String paginateAnchor = modelForm.getPaginateTargetAnchor();
+        if (UtilValidate.isNotEmpty(paginateAnchor))
+            anchor = "#" + paginateAnchor;
+        // Create separate url path String and request parameters String,
+        // add viewIndex/viewSize parameters to request parameter String
+        String urlPath = UtilHttp.removeQueryStringFromTarget(targetService);
+        String prepLinkText = UtilHttp.getQueryStringFromTarget(targetService);
+        String prepLinkSizeText;
+        if (UtilValidate.isNotEmpty(queryString)) {
+            queryString = UtilHttp.encodeAmpersands(queryString);
+        }
+        if (prepLinkText == null) {
+            prepLinkText = "";
+        }
+        if (prepLinkText.indexOf("?") < 0) {
+            prepLinkText += "?";
+        } else if (!prepLinkText.endsWith("?")) {
+            prepLinkText += "&amp;";
+        }
+        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
+            prepLinkText += queryString + "&amp;";
+        }
+        prepLinkSizeText = prepLinkText + viewSizeParam + "='+this.value+'" + "&amp;" + viewIndexParam + "=0";
+        prepLinkText += viewSizeParam + "=" + viewSize + "&amp;" + viewIndexParam + "=";
+        if (ajaxEnabled) {
+            // Prepare params for prototype.js
+            prepLinkText = prepLinkText.replace("?", "");
+            prepLinkText = prepLinkText.replace("&amp;", "&");
+        }
+        String linkText;
+        String paginateStyle = modelForm.getPaginateStyle();
+        String paginateFirstStyle = modelForm.getPaginateFirstStyle();
+        String paginateFirstLabel = modelForm.getPaginateFirstLabel(context);
+        String firstUrl = "";
+        String ajaxFirstUrl = "";
+        String paginatePreviousStyle = modelForm.getPaginatePreviousStyle();
+        String paginatePreviousLabel = modelForm.getPaginatePreviousLabel(context);
+        String previousUrl = "";
+        String ajaxPreviousUrl = "";
+        String selectUrl = "";
+        String ajaxSelectUrl = "";
+        String paginateViewSizeLabel = modelForm.getPaginateViewSizeLabel(context);
+        String selectSizeUrl = "";
+        String ajaxSelectSizeUrl = "";
+        String paginateNextStyle = modelForm.getPaginateNextStyle();
+        String paginateNextLabel = modelForm.getPaginateNextLabel(context);
+        String nextUrl = "";
+        String ajaxNextUrl = "";
+        String paginateLastStyle = modelForm.getPaginateLastStyle();
+        String paginateLastLabel = modelForm.getPaginateLastLabel(context);
+        String lastUrl = "";
+        String ajaxLastUrl = "";
+        if (viewIndex > 0) {
+            if (ajaxEnabled) {
+                ajaxFirstUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + 0 + anchor, context);
+            } else {
+                linkText = prepLinkText + 0 + anchor;
+                firstUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
+            }
+        }
+        if (viewIndex > 0) {
+            if (ajaxEnabled) {
+                ajaxPreviousUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex - 1) + anchor, context);
+            } else {
+                linkText = prepLinkText + (viewIndex - 1) + anchor;
+                previousUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
+            }
+        }
+        // Page select dropdown
+        if (listSize > 0 && this.javaScriptEnabled) {
+            if (ajaxEnabled) {
+                ajaxSelectUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + "' + this.value + '", context);
+            } else {
+                linkText = prepLinkText;
+                if (linkText.startsWith("/")) {
+                    linkText = linkText.substring(1);
+                }
+                selectUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
+            }
+        }
+        // Next button
+        if (highIndex < listSize) {
+            if (ajaxEnabled) {
+                ajaxNextUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + (viewIndex + 1) + anchor, context);
+            } else {
+                linkText = prepLinkText + (viewIndex + 1) + anchor;
+                nextUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
+            }
+        }
+        // Last button
+        if (highIndex < listSize) {
+            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
+            if (ajaxEnabled) {
+                ajaxLastUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkText + lastIndex + anchor, context);
+            } else {
+                linkText = prepLinkText + lastIndex + anchor;
+                lastUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
+            }
+        }
+        // Page size select dropdown
+        if (listSize > 0 && this.javaScriptEnabled) {
+            if (ajaxEnabled) {
+                ajaxSelectSizeUrl = createAjaxParamsFromUpdateAreas(updateAreas, prepLinkSizeText + anchor, context);
+            } else {
+                linkText = prepLinkSizeText;
+                if (linkText.startsWith("/")) {
+                    linkText = linkText.substring(1);
+                }
+                selectSizeUrl = rh.makeLink(this.request, this.response, urlPath + linkText);
+            }
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderNextPrev ");
+        sr.append(" paginateStyle=\"");
+        sr.append(paginateStyle);
+        sr.append("\" paginateFirstStyle=\"");
+        sr.append(paginateFirstStyle);
+        sr.append("\" viewIndex=");
+        sr.append(Integer.toString(viewIndex));
+        sr.append(" highIndex=");
+        sr.append(Integer.toString(highIndex));
+        sr.append(" listSize=");
+        sr.append(Integer.toString(listSize));
+        sr.append(" viewSize=");
+        sr.append(Integer.toString(viewSize));
+        sr.append(" ajaxEnabled=");
+        sr.append(Boolean.toString(ajaxEnabled));
+        sr.append(" javaScriptEnabled=");
+        sr.append(Boolean.toString(javaScriptEnabled));
+        sr.append(" ajaxFirstUrl=\"");
+        sr.append(ajaxFirstUrl);
+        sr.append("\" ajaxFirstUrl=\"");
+        sr.append(ajaxFirstUrl);
+        sr.append("\" ajaxFirstUrl=\"");
+        sr.append(ajaxFirstUrl);
+        sr.append("\" firstUrl=\"");
+        sr.append(firstUrl);
+        sr.append("\" paginateFirstLabel=\"");
+        sr.append(paginateFirstLabel);
+        sr.append("\" paginatePreviousStyle=\"");
+        sr.append(paginatePreviousStyle);
+        sr.append("\" ajaxPreviousUrl=\"");
+        sr.append(ajaxPreviousUrl);
+        sr.append("\" previousUrl=\"");
+        sr.append(previousUrl);
+        sr.append("\" paginatePreviousLabel=\"");
+        sr.append(paginatePreviousLabel);
+        sr.append("\" pageLabel=\"");
+        sr.append(pageLabel);
+        sr.append("\" ajaxSelectUrl=\"");
+        sr.append(ajaxSelectUrl);
+        sr.append("\" selectUrl=\"");
+        sr.append(selectUrl);
+        sr.append("\" ajaxSelectSizeUrl=\"");
+        sr.append(ajaxSelectSizeUrl);
+        sr.append("\" selectSizeUrl=\"");
+        sr.append(selectSizeUrl);
+        sr.append("\" commonDisplaying=\"");
+        sr.append(commonDisplaying);
+        sr.append("\" paginateNextStyle=\"");
+        sr.append(paginateNextStyle);
+        sr.append("\" ajaxNextUrl=\"");
+        sr.append(ajaxNextUrl);
+        sr.append("\" nextUrl=\"");
+        sr.append(nextUrl);
+        sr.append("\" paginateNextLabel=\"");
+        sr.append(paginateNextLabel);
+        sr.append("\" paginateLastStyle=\"");
+        sr.append(paginateLastStyle);
+        sr.append("\" ajaxLastUrl=\"");
+        sr.append(ajaxLastUrl);
+        sr.append("\" lastUrl=\"");
+        sr.append(lastUrl);
+        sr.append("\" paginateLastLabel=\"");
+        sr.append(paginateLastLabel);
+        sr.append("\" paginateViewSizeLabel=\"");
+        sr.append(paginateViewSizeLabel);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+        String className = "";
+        String alert = "false";
+        String name = modelFormField.getParameterName(context);
+        String value = modelFormField.getEntry(context, textField.getDefaultValue(context));
+        String size = Integer.toString(textField.getSize());
+        String maxlength = "";
+        String autocomplete = "";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        if (UtilValidate.isEmpty(value)) {
+            value = "";
+        }
+        if (textField.getMaxlength() != null) {
+            maxlength = textField.getMaxlength().toString();
+        }
+        if (!textField.getClientAutocompleteField()) {
+            autocomplete = "off";
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFileField ");
+        sr.append(" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" size=\"");
+        sr.append(size);
+        sr.append("\" maxlength=\"");
+        sr.append(maxlength);
+        sr.append("\" autocomplete=\"");
+        sr.append(autocomplete);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.makeHyperlinkString(writer, textField.getSubHyperlink(), context);
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
+        ModelFormField modelFormField = passwordField.getModelFormField();
+        String className = "";
+        String alert = "false";
+        String name = modelFormField.getParameterName(context);
+        String size = Integer.toString(passwordField.getSize());
+        String maxlength = "";
+        String id = modelFormField.getCurrentContainerId(context);
+        String autocomplete = "";
+        if (UtilValidate.isNotEmpty(modelFormField.getWidgetStyle())) {
+            className = modelFormField.getWidgetStyle();
+            if (modelFormField.shouldBeRed(context)) {
+                alert = "true";
+            }
+        }
+        String value = modelFormField.getEntry(context, passwordField.getDefaultValue(context));
+        if (value == null) {
+            value = "";
+        }
+        if (passwordField.getMaxlength() != null) {
+            maxlength = passwordField.getMaxlength().toString();
+        }
+        if (id == null) {
+            id = "";
+        }
+        if (!passwordField.getClientAutocompleteField()) {
+            autocomplete = "off";
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderPasswordField ");
+        sr.append(" className=\"");
+        sr.append(className);
+        sr.append("\" alert=\"");
+        sr.append(alert);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" value=\"");
+        sr.append(value);
+        sr.append("\" size=\"");
+        sr.append(size);
+        sr.append("\" maxlength=\"");
+        sr.append(maxlength);
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" autocomplete=\"");
+        sr.append(autocomplete);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.addAsterisks(writer, context, modelFormField);
+        this.makeHyperlinkString(writer, passwordField.getSubHyperlink(), context);
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
+        ModelFormField modelFormField = imageField.getModelFormField();
+        String value = modelFormField.getEntry(context, imageField.getValue(context));
+        String description = imageField.getDescription(context);
+        String alternate = imageField.getAlternate(context);
+        String style = imageField.getStyle(context);
+        if (UtilValidate.isEmpty(description)) {
+            description = imageField.getModelFormField().getTitle(context);
+        }
+        if (UtilValidate.isEmpty(alternate)) {
+            alternate = description;
+        }
+        if (UtilValidate.isNotEmpty(value)) {
+            if (!value.startsWith("http")) {
+                StringBuilder buffer = new StringBuilder();
+                ContentUrlTag.appendContentPrefix(request, buffer);
+                buffer.append(value);
+                value = buffer.toString();
+            }
+        } else if (value == null) {
+            value = "";
+        }
+        String event = modelFormField.getEvent();
+        String action = modelFormField.getAction(context);
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderImageField ");
+        sr.append(" value=\"");
+        sr.append(value);
+        sr.append("\" description=\"");
+        sr.append(encode(description, modelFormField, context));
+        sr.append("\" alternate=\"");
+        sr.append(encode(alternate, modelFormField, context));
+        sr.append("\" style=\"");
+        sr.append(style);
+        sr.append("\" event=\"");
+        sr.append(event == null ? "" : event);
+        sr.append("\" action=\"");
+        sr.append(action == null ? "" : action);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+        this.makeHyperlinkString(writer, imageField.getSubHyperlink(), context);
+        this.appendTooltip(writer, context, modelFormField);
+    }
+
+    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
+        String style = fieldGroup.getStyle();
+        String id = fieldGroup.getId();
+        FlexibleStringExpander titleNotExpanded = FlexibleStringExpander.getInstance(fieldGroup.getTitle());
+        String title = titleNotExpanded.expandString(context);
+        Boolean collapsed = fieldGroup.initiallyCollapsed();
+        String collapsibleAreaId = fieldGroup.getId() + "_body";
+        Boolean collapsible = fieldGroup.collapsible();
+        String expandToolTip = "";
+        String collapseToolTip = "";
+        if (UtilValidate.isNotEmpty(style) || UtilValidate.isNotEmpty(id) || UtilValidate.isNotEmpty(title)) {
+            if (fieldGroup.collapsible()) {
+                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+                //Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
+                if (uiLabelMap != null) {
+                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
+                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
+                }
+            }
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFieldGroupOpen ");
+        sr.append(" style=\"");
+        if (style != null) {
+            sr.append(style);
+        }
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" title=\"");
+        sr.append(title);
+        sr.append("\" collapsed=");
+        sr.append(Boolean.toString(collapsed));
+        sr.append(" collapsibleAreaId=\"");
+        sr.append(collapsibleAreaId);
+        sr.append("\" collapsible=");
+        sr.append(Boolean.toString(collapsible));
+        sr.append(" expandToolTip=\"");
+        sr.append(expandToolTip);
+        sr.append("\" collapseToolTip=\"");
+        sr.append(collapseToolTip);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
+        String style = fieldGroup.getStyle();
+        String id = fieldGroup.getId();
+        FlexibleStringExpander titleNotExpanded = FlexibleStringExpander.getInstance(fieldGroup.getTitle());
+        String title = titleNotExpanded.expandString(context);
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderFieldGroupClose ");
+        sr.append(" style=\"");
+        if (style != null) {
+            sr.append(style);
+        }
+        sr.append("\" id=\"");
+        if (id != null) {
+            sr.append(id);
+        }
+        sr.append("\" title=\"");
+        if (title != null) {
+            sr.append(title);
+        }
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
+        String style = banner.getStyle(context);
+        String leftStyle = banner.getLeftTextStyle(context);
+        if (UtilValidate.isEmpty(leftStyle))
+            leftStyle = style;
+        String rightStyle = banner.getRightTextStyle(context);
+        if (UtilValidate.isEmpty(rightStyle))
+            rightStyle = style;
+        String leftText = banner.getLeftText(context);
+        if (leftText == null) {
+            leftText = "";
+        }
+        String text = banner.getText(context);
+        if (text == null) {
+            text = "";
+        }
+        String rightText = banner.getRightText(context);
+        if (rightText == null) {
+            rightText = "";
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderBanner ");
+        sr.append(" style=\"");
+        sr.append(style);
+        sr.append("\" leftStyle=\"");
+        sr.append(leftStyle);
+        sr.append("\" rightStyle=\"");
+        sr.append(rightStyle);
+        sr.append("\" leftText=\"");
+        sr.append(leftText);
+        sr.append("\" text=\"");
+        sr.append(text);
+        sr.append("\" rightText=\"");
+        sr.append(rightText);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    /**
+     * Renders the beginning boundary comment string.
+     * @param writer The writer to write to
+     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
+     * @param modelWidget The widget
+     */
+    public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
+        if (this.widgetCommentsEnabled) {
+            StringWriter sr = new StringWriter();
+            sr.append("<@formatBoundaryComment ");
+            sr.append(" boundaryType=\"");
+            sr.append("Begin");
+            sr.append("\" widgetType=\"");
+            sr.append(widgetType);
+            sr.append("\" widgetName=\"");
+            sr.append(modelWidget.getBoundaryCommentName());
+            sr.append("\" />");
+            executeMacro(writer, sr.toString());
+        }
+    }
+
+    /**
+     * Renders the ending boundary comment string.
+     * @param writer The writer to write to
+     * @param widgetType The widget type: "Screen Widget", "Form Widget", etc.
+     * @param modelWidget The widget
+     */
+    public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
+        if (this.widgetCommentsEnabled) {
+            StringWriter sr = new StringWriter();
+            sr.append("<@formatBoundaryComment ");
+            sr.append(" boundaryType=\"");
+            sr.append("End");
+            sr.append("\" widgetType=\"");
+            sr.append(widgetType);
+            sr.append("\" widgetName=\"");
+            sr.append(modelWidget.getBoundaryCommentName());
+            sr.append("\" />");
+            executeMacro(writer, sr.toString());
+        }
+    }
+
+    public void renderSortField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
+        boolean ajaxEnabled = false;
+        ModelForm modelForm = modelFormField.getModelForm();
+        List<ModelForm.UpdateArea> updateAreas = modelForm.getOnSortColumnUpdateAreas();
+        if (updateAreas == null) {
+            // For backward compatibility.
+            updateAreas = modelForm.getOnPaginateUpdateAreas();
+        }
+        if (this.javaScriptEnabled) {
+            if (UtilValidate.isNotEmpty(updateAreas)) {
+                ajaxEnabled = true;
+            }
+        }
+        String paginateTarget = modelForm.getPaginateTarget(context);
+        if (paginateTarget.isEmpty() && updateAreas == null) {
+            Debug.logWarning("Cannot sort because the paginate target URL is empty for the form: " + modelForm.getName(), module);
+            return;
+        }
+        String oldSortField = modelForm.getSortField(context);
+        String sortFieldStyle = modelFormField.getSortFieldStyle();
+        // if the entry-name is defined use this instead of field name
+        String columnField = modelFormField.getEntryName();
+        if (UtilValidate.isEmpty(columnField)) {
+            columnField = modelFormField.getFieldName();
+        }
+        // switch between asc/desc order
+        String newSortField = columnField;
+        if (UtilValidate.isNotEmpty(oldSortField)) {
+            if (oldSortField.equals(columnField)) {
+                newSortField = "-" + columnField;
+                sortFieldStyle = modelFormField.getSortFieldStyleDesc();
+            } else if (oldSortField.equals("-" + columnField)) {
+                newSortField = columnField;
+                sortFieldStyle = modelFormField.getSortFieldStyleAsc();
+            }
+        }
+        String queryString = UtilHttp.getQueryStringFromTarget(paginateTarget).replace("?", "");
+        Map<String, Object> paramMap = UtilHttp.getQueryStringOnlyParameterMap(queryString);
+        String qbeString = (String) context.get("_QBESTRING_");
+        if (qbeString != null) {
+            qbeString = qbeString.replaceAll("&amp;", "&");
+            paramMap.putAll(UtilHttp.getQueryStringOnlyParameterMap(qbeString));
+        }
+        paramMap.put(modelForm.getSortFieldParameterName(), newSortField);
+        UtilHttp.canonicalizeParameterMap(paramMap);
+        String linkUrl = null;
+        if (ajaxEnabled) {
+            linkUrl = createAjaxParamsFromUpdateAreas(updateAreas, paramMap, null, context);
+        } else {
+            StringBuilder sb = new StringBuilder("?");
+            Iterator<Map.Entry<String, Object>> iter = paramMap.entrySet().iterator();
+            while (iter.hasNext()) {
+                Map.Entry<String, Object> entry = iter.next();
+                sb.append(entry.getKey()).append("=").append(entry.getValue());
+                if (iter.hasNext()) {
+                    sb.append("&amp;");
+                }
+            }
+            String newQueryString = sb.toString();
+            String urlPath = UtilHttp.removeQueryStringFromTarget(paginateTarget);
+            linkUrl = rh.makeLink(this.request, this.response, urlPath.concat(newQueryString));
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderSortField ");
+        sr.append(" style=\"");
+        sr.append(sortFieldStyle);
+        sr.append("\" title=\"");
+        sr.append(titleText);
+        sr.append("\" linkUrl=\"");
+        sr.append(linkUrl);
+        sr.append("\" ajaxEnabled=");
+        sr.append(Boolean.toString(ajaxEnabled));
+        String tooltip = modelFormField.getSortFieldHelpText(context);
+        if (!tooltip.isEmpty()) {
+            sr.append(" tooltip=\"").append(tooltip).append("\"");
+        }
+        sr.append(" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea objects. See
+     * <code>selectall.js</code>.
+     * @param updateAreas
+     * @param extraParams Renderer-supplied additional target parameters
+     * @param context
+     * @return Parameter string or empty string if no UpdateArea objects were found
+     */
+    private String createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas, Map<String, Object> extraParams, String anchor, Map<String, ? extends Object> context) {
+        StringBuilder sb = new StringBuilder();
+        Iterator<ModelForm.UpdateArea> updateAreaIter = updateAreas.iterator();
+        while (updateAreaIter.hasNext()) {
+            ModelForm.UpdateArea updateArea = updateAreaIter.next();
+            sb.append(updateArea.getAreaId()).append(",");
+            String ajaxTarget = updateArea.getAreaTarget(context);
+            String urlPath = UtilHttp.removeQueryStringFromTarget(ajaxTarget);
+            sb.append(this.rh.makeLink(this.request, this.response,urlPath)).append(",");
+            String queryString = UtilHttp.getQueryStringFromTarget(ajaxTarget).replace("?", "");
+            Map<String, Object> parameters = UtilHttp.getQueryStringOnlyParameterMap(queryString);
+            Map<String, Object> ctx = UtilGenerics.checkMap(context);
+            Map<String, Object> updateParams = UtilGenerics.checkMap(updateArea.getParameterMap(ctx));
+            parameters.putAll(updateParams);
+            UtilHttp.canonicalizeParameterMap(parameters);
+            parameters.putAll(extraParams);
+            Iterator<Map.Entry<String, Object>> paramIter = parameters.entrySet().iterator();
+            while (paramIter.hasNext()) {
+                Map.Entry<String, Object> entry = paramIter.next();
+                sb.append(entry.getKey()).append("=").append(entry.getValue());
+                if (paramIter.hasNext()) {
+                    sb.append("&");
+                }
+            }
+            if (anchor != null) {
+                sb.append("#").append(anchor);
+            }
+            if (updateAreaIter.hasNext()) {
+                sb.append(",");
+            }
+        }
+        Locale locale = UtilMisc.ensureLocale(context.get("locale"));
+        return FlexibleStringExpander.expandString(sb.toString(), context, locale);
+    }
+
+    /** Create an ajaxXxxx JavaScript CSV string from a list of UpdateArea objects. See
+     * <code>selectall.js</code>.
+     * @param updateAreas
+     * @param extraParams Renderer-supplied additional target parameters
+     * @param context
+     * @return Parameter string or empty string if no UpdateArea objects were found
+     */
+    public String createAjaxParamsFromUpdateAreas(List<ModelForm.UpdateArea> updateAreas, String extraParams, Map<String, ? extends Object> context) {
+        //FIXME copy from HtmlFormRenderer.java
+        if (updateAreas == null) {
+            return "";
+        }
+        String ajaxUrl = "";
+        boolean firstLoop = true;
+        for (ModelForm.UpdateArea updateArea : updateAreas) {
+            if (firstLoop) {
+                firstLoop = false;
+            } else {
+                ajaxUrl += ",";
+            }
+            Map<String, Object> ctx = UtilGenerics.checkMap(context);
+            Map<String, String> parameters = updateArea.getParameterMap(ctx);
+            String targetUrl = updateArea.getAreaTarget(context);
+            String ajaxParams = getAjaxParamsFromTarget(targetUrl);
+            //add first parameters from updateArea parameters
+            if (UtilValidate.isNotEmpty(parameters)) {
+                if (UtilValidate.isEmpty(ajaxParams)) {
+                    ajaxParams = "";
+                }
+                for (Map.Entry<String, String> entry : parameters.entrySet()) {
+                    String key = entry.getKey();
+                    String value = entry.getValue();
+                    //test if ajax parameters are not already into extraParams, if so do not add it
+                    if (UtilValidate.isNotEmpty(extraParams) && extraParams.contains(value)) {
+                        continue;
+                    }
+                    if (ajaxParams.length() > 0 && ajaxParams.indexOf(key) < 0) {
+                        ajaxParams += "&";
+                    }
+                    if (ajaxParams.indexOf(key) < 0) {
+                        ajaxParams += key + "=" + value;
+                    }
+                }
+            }
+            //then add parameters from request. Those parameters could end with an anchor so we must set ajax parameters first
+            if (UtilValidate.isNotEmpty(extraParams)) {
+                if (ajaxParams.length() > 0 && !extraParams.startsWith("&")) {
+                    ajaxParams += "&";
+                }
+                ajaxParams += extraParams;
+            }
+            ajaxUrl += updateArea.getAreaId() + ",";
+            ajaxUrl += this.rh.makeLink(this.request, this.response, UtilHttp.removeQueryStringFromTarget(targetUrl));
+            ajaxUrl += "," + ajaxParams;
+        }
+        Locale locale = UtilMisc.ensureLocale(context.get("locale"));
+        return FlexibleStringExpander.expandString(ajaxUrl, context, locale);
+    }
+
+    /** Extracts parameters from a target URL string, prepares them for an Ajax
+     * JavaScript call. This method is currently set to return a parameter string
+     * suitable for the Prototype.js library.
+     * @param target Target URL string
+     * @return Parameter string
+     */
+    public static String getAjaxParamsFromTarget(String target) {
+        String targetParams = UtilHttp.getQueryStringFromTarget(target);
+        targetParams = targetParams.replace("?", "");
+        targetParams = targetParams.replace("&amp;", "&");
+        return targetParams;
+    }
+
+    public void appendTooltip(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        // render the tooltip, in other methods too
+        String tooltip = modelFormField.getTooltip(context);
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderTooltip ");
+        sr.append("tooltip=\"");
+        sr.append(FreeMarkerWorker.encodeDoubleQuotes(tooltip));
+        sr.append("\" tooltipStyle=\"");
+        sr.append(modelFormField.getTooltipStyle());
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void makeHyperlinkString(Appendable writer, ModelFormField.SubHyperlink subHyperlink, Map<String, Object> context) throws IOException {
+        if (subHyperlink == null) {
+            return;
+        }
+        if (subHyperlink.shouldUse(context)) {
+            writer.append(' ');
+            makeHyperlinkByType(writer, subHyperlink.getLinkType(), subHyperlink.getStyle(context), subHyperlink.getUrlMode(),
+                    subHyperlink.getTarget(context), subHyperlink.getParameterMap(context), subHyperlink.getDescription(context),
+                    subHyperlink.getTargetWindow(context), null, subHyperlink.getModelFormField(), this.request, this.response,
+                    context);
+        }
+    }
+
+    public void addAsterisks(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        String requiredField = "false";
+        String requiredStyle = "";
+        if (modelFormField.getRequiredField()) {
+            requiredField = "true";
+            requiredStyle = modelFormField.getRequiredFieldStyle();
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderAsterisks ");
+        sr.append("requiredField=\"");
+        sr.append(requiredField);
+        sr.append("\" requiredStyle=\"");
+        sr.append(requiredStyle);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void appendContentUrl(Appendable writer, String location) throws IOException {
+        StringBuilder buffer = new StringBuilder();
+        ContentUrlTag.appendContentPrefix(this.request, buffer);
+        writer.append(buffer.toString());
+        writer.append(location);
+    }
+
+    public void makeHyperlinkByType(Appendable writer, String linkType, String linkStyle, String targetType, String target, Map<String, String> parameterMap, String description, String targetWindow, String confirmation, ModelFormField modelFormField, HttpServletRequest request,
+            HttpServletResponse response, Map<String, Object> context) throws IOException {
+        String realLinkType = WidgetWorker.determineAutoLinkType(linkType, target, targetType, request);
+        String encodedDescription = encode(description, modelFormField, context);
+        // get the parameterized pagination index and size fields
+        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
+        ModelForm modelForm = modelFormField.getModelForm();
+        String viewIndexField = modelForm.getMultiPaginateIndexField(context);
+        String viewSizeField = modelForm.getMultiPaginateSizeField(context);
+        int viewIndex = Paginator.getViewIndex(modelForm, context);
+        int viewSize = Paginator.getViewSize(modelForm, context);
+        if (viewIndexField.equals("viewIndex" + "_" + paginatorNumber)) {
+            viewIndexField = "VIEW_INDEX" + "_" + paginatorNumber;
+        }
+        if (viewSizeField.equals("viewSize" + "_" + paginatorNumber)) {
+            viewSizeField = "VIEW_SIZE" + "_" + paginatorNumber;
+        }
+        if ("hidden-form".equals(realLinkType)) {
+            parameterMap.put(viewIndexField, Integer.toString(viewIndex));
+            parameterMap.put(viewSizeField, Integer.toString(viewSize));
+            if (modelFormField != null && "multi".equals(modelForm.getType())) {
+                WidgetWorker.makeHiddenFormLinkAnchor(writer, linkStyle, encodedDescription, confirmation, modelFormField, request, response, context);
+                // this is a bit trickier, since we can't do a nested form we'll have to put the link to submit the form in place, but put the actual form def elsewhere, ie after the big form is closed
+                Map<String, Object> wholeFormContext = UtilGenerics.checkMap(context.get("wholeFormContext"));
+                Appendable postMultiFormWriter = wholeFormContext != null ? (Appendable) wholeFormContext.get("postMultiFormWriter") : null;
+                if (postMultiFormWriter == null) {
+                    postMultiFormWriter = new StringWriter();
+                    wholeFormContext.put("postMultiFormWriter", postMultiFormWriter);
+                }
+                WidgetWorker.makeHiddenFormLinkForm(postMultiFormWriter, target, targetType, targetWindow, parameterMap, modelFormField, request, response, context);
+            } else {
+                WidgetWorker.makeHiddenFormLinkForm(writer, target, targetType, targetWindow, parameterMap, modelFormField, request, response, context);
+                WidgetWorker.makeHiddenFormLinkAnchor(writer, linkStyle, encodedDescription, confirmation, modelFormField, request, response, context);
+            }
+        } else {
+            makeHyperlinkString(writer, linkStyle, targetType, target, parameterMap, encodedDescription, confirmation, modelFormField, request, response, context, targetWindow);
+        }
+
+    }
+
+    public void makeHyperlinkString(Appendable writer, String linkStyle, String targetType, String target, Map<String, String> parameterMap, String description, String confirmation, ModelFormField modelFormField, HttpServletRequest request, HttpServletResponse response, Map<String, Object> context,
+            String targetWindow) throws IOException {
+        if (UtilValidate.isNotEmpty(description) || UtilValidate.isNotEmpty(request.getAttribute("image"))) {
+            StringBuilder linkUrl = new StringBuilder();
+            WidgetWorker.buildHyperlinkUrl(linkUrl, target, targetType, parameterMap, null, false, false, true, request, response, context);
+            String event = "";
+            String action = "";
+            String imgSrc = "";
+            String alt = "";
+            String imgTitle = "";
+            String hiddenFormName = WidgetWorker.makeLinkHiddenFormName(context, modelFormField);
+            if (UtilValidate.isNotEmpty(modelFormField.getEvent()) && UtilValidate.isNotEmpty(modelFormField.getAction(context))) {
+                event = modelFormField.getEvent();
+                action = modelFormField.getAction(context);
+            }
+            if (UtilValidate.isNotEmpty(request.getAttribute("image"))) {
+                imgSrc = request.getAttribute("image").toString();
+            }
+            if (UtilValidate.isNotEmpty(request.getAttribute("alternate"))) {
+                alt = request.getAttribute("alternate").toString();
+            }
+            if (UtilValidate.isNotEmpty(request.getAttribute("imageTitle"))) {
+                imgTitle = request.getAttribute("imageTitle").toString();
+            }
+            Integer size = Integer.valueOf("0");
+            if (UtilValidate.isNotEmpty(request.getAttribute("descriptionSize"))) {
+                size = Integer.valueOf(request.getAttribute("descriptionSize").toString());
+            }
+            if (UtilValidate.isNotEmpty(description) && size > 0 && description.length() > size) {
+                imgTitle = description;
+                description = description.substring(0, size - 8) + "..." + description.substring(description.length() - 5);
+            }
+            if (UtilValidate.isEmpty(imgTitle)) {
+                imgTitle = modelFormField.getTitle(context);
+            }
+            StringWriter sr = new StringWriter();
+            sr.append("<@makeHyperlinkString ");
+            sr.append("linkStyle=\"");
+            sr.append(linkStyle == null ? "" : linkStyle);
+            sr.append("\" hiddenFormName=\"");
+            sr.append(hiddenFormName == null ? "" : hiddenFormName);
+            sr.append("\" event=\"");
+            sr.append(event);
+            sr.append("\" action=\"");
+            sr.append(action);
+            sr.append("\" imgSrc=\"");
+            sr.append(imgSrc);
+            sr.append("\" title=\"");
+            sr.append(imgTitle);
+            sr.append("\" alternate=\"");
+            sr.append(alt);
+            sr.append("\" linkUrl=\"");
+            sr.append(linkUrl.toString());
+            sr.append("\" targetWindow=\"");
+            sr.append(targetWindow);
+            sr.append("\" description=\"");
+            sr.append(description);
+            sr.append("\" confirmation =\"");
+            sr.append(confirmation);
+            sr.append("\" />");
+            executeMacro(writer, sr.toString());
+        }
+    }
+
+    public void makeHiddenFormLinkAnchor(Appendable writer, String linkStyle, String description, String confirmation, ModelFormField modelFormField, HttpServletRequest request, HttpServletResponse response, Map<String, Object> context) throws IOException {
+        if (UtilValidate.isNotEmpty(description) || UtilValidate.isNotEmpty(request.getAttribute("image"))) {
+            String hiddenFormName = WidgetWorker.makeLinkHiddenFormName(context, modelFormField);
+            String event = "";
+            String action = "";
+            String imgSrc = "";
+            if (UtilValidate.isNotEmpty(modelFormField.getEvent()) && UtilValidate.isNotEmpty(modelFormField.getAction(context))) {
+                event = modelFormField.getEvent();
+                action = modelFormField.getAction(context);
+            }
+            if (UtilValidate.isNotEmpty(request.getAttribute("image"))) {
+                imgSrc = request.getAttribute("image").toString();
+            }
+            StringWriter sr = new StringWriter();
+            sr.append("<@makeHiddenFormLinkAnchor ");
+            sr.append("linkStyle=\"");
+            sr.append(linkStyle == null ? "" : linkStyle);
+            sr.append("\" hiddenFormName=\"");
+            sr.append(hiddenFormName == null ? "" : hiddenFormName);
+            sr.append("\" event=\"");
+            sr.append(event);
+            sr.append("\" action=\"");
+            sr.append(action);
+            sr.append("\" imgSrc=\"");
+            sr.append(imgSrc);
+            sr.append("\" description=\"");
+            sr.append(description);
+            sr.append("\" confirmation =\"");
+            sr.append(confirmation);
+            sr.append("\" />");
+            executeMacro(writer, sr.toString());
+        }
+    }
+
+    public void makeHiddenFormLinkForm(Appendable writer, String target, String targetType, String targetWindow, List<CommonWidgetModels.Parameter> parameterList, ModelFormField modelFormField, HttpServletRequest request, HttpServletResponse response, Map<String, Object> context) throws IOException {
+        StringBuilder actionUrl = new StringBuilder();
+        WidgetWorker.buildHyperlinkUrl(actionUrl, target, targetType, null, null, false, false, true, request, response, context);
+        String name = WidgetWorker.makeLinkHiddenFormName(context, modelFormField);
+        StringBuilder parameters = new StringBuilder();
+        parameters.append("[");
+        for (CommonWidgetModels.Parameter parameter : parameterList) {
+            if (parameters.length() > 1) {
+                parameters.append(",");
+            }
+            parameters.append("{'name':'");
+            parameters.append(parameter.getName());
+            parameters.append("'");
+            parameters.append(",'value':'");
+            parameters.append(UtilCodec.getEncoder("html").encode(parameter.getValue(context)));
+            parameters.append("'}");
+        }
+        parameters.append("]");
+        StringWriter sr = new StringWriter();
+        sr.append("<@makeHiddenFormLinkForm ");
+        sr.append("actionUrl=\"");
+        sr.append(actionUrl.toString());
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" parameters=");
+        sr.append(parameters.toString());
+        sr.append(" targetWindow=\"");
+        sr.append(targetWindow);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
+        String id = containerField.getModelFormField().getIdName();
+        String className = UtilFormatOut.checkNull(containerField.getModelFormField().getWidgetStyle());
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderContainerField ");
+        sr.append("id=\"");
+        sr.append(id);
+        sr.append("\" className=\"");
+        sr.append(className);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
index fc99336..bcac580 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/MacroMenuRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  *******************************************************************************/
-package org.ofbiz.widget.menu;
+package org.ofbiz.widget.renderer.macro;
 
 import java.io.IOException;
 import java.io.Reader;
@@ -39,10 +39,13 @@
 import org.ofbiz.base.util.template.FreeMarkerWorker;
 import org.ofbiz.webapp.control.RequestHandler;
 import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.CommonWidgetModels.Image;
-import org.ofbiz.widget.ModelWidget;
 import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.menu.ModelMenuItem.MenuLink;
+import org.ofbiz.widget.model.CommonWidgetModels.Image;
+import org.ofbiz.widget.model.ModelMenu;
+import org.ofbiz.widget.model.ModelMenuItem;
+import org.ofbiz.widget.model.ModelMenuItem.MenuLink;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
 
 import freemarker.core.Environment;
 import freemarker.template.Template;
diff --git a/framework/widget/src/org/ofbiz/widget/screen/MacroScreenRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroScreenRenderer.java
similarity index 98%
rename from framework/widget/src/org/ofbiz/widget/screen/MacroScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/macro/MacroScreenRenderer.java
index 3bb08d0..66c7f23 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/MacroScreenRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroScreenRenderer.java
@@ -1,1045 +1,1048 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilFormatOut;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilHttp;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.template.FreeMarkerWorker;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.WidgetContentWorker;
-import org.ofbiz.widget.WidgetDataResourceWorker;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.MacroFormRenderer;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.Paginator;
-import org.ofbiz.widget.html.HtmlScreenRenderer.ScreenletMenuRenderer;
-import org.ofbiz.widget.menu.MenuStringRenderer;
-import org.ofbiz.widget.screen.ModelScreenWidget.Column;
-import org.ofbiz.widget.screen.ModelScreenWidget.ColumnContainer;
-import org.xml.sax.SAXException;
-
-import freemarker.core.Environment;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-
-public class MacroScreenRenderer implements ScreenStringRenderer {
-
-    public static final String module = MacroScreenRenderer.class.getName();
-    private Template macroLibrary;
-    private WeakHashMap<Appendable, Environment> environments = new WeakHashMap<Appendable, Environment>();
-    private String rendererName;
-    private int elementId = 999;
-    protected boolean widgetCommentsEnabled = false;
-    private static final String formrenderer = UtilProperties.getPropertyValue("widget", "screen.formrenderer");
-    private int screenLetsIdCounter = 1;
-
-    public MacroScreenRenderer(String name, String macroLibraryPath) throws TemplateException, IOException {
-        macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
-        rendererName = name;
-    }
-
-    @Deprecated
-    public MacroScreenRenderer(String name, String macroLibraryPath, Appendable writer) throws TemplateException, IOException {
-        this(name, macroLibraryPath);
-    }
-
-    private String getNextElementId() {
-        elementId++;
-        return "hsr" + elementId;
-    }
-
-    private void executeMacro(Appendable writer, String macro) throws IOException {
-        try {
-            Environment environment = getEnvironment(writer);
-            Reader templateReader = new StringReader(macro);
-            // FIXME: I am using a Date as an hack to provide a unique name for the template...
-            Template template = new Template((new java.util.Date()).toString(), templateReader, FreeMarkerWorker.getDefaultOfbizConfig());
-            templateReader.close();
-            environment.include(template);
-        } catch (TemplateException e) {
-            Debug.logError(e, "Error rendering screen macro [" + macro + "] thru ftl", module);
-        } catch (IOException e) {
-            Debug.logError(e, "Error rendering screen macro [" + macro + "] thru ftl", module);
-        }
-    }
-
-    private void executeMacro(Appendable writer, String macroName, Map<String, Object> parameters) throws IOException {
-        StringBuilder sb = new StringBuilder("<@");
-        sb.append(macroName);
-        if (parameters != null) {
-            for (Map.Entry<String, Object> parameter : parameters.entrySet()) {
-                sb.append(' ');
-                sb.append(parameter.getKey());
-                sb.append("=");
-                Object value = parameter.getValue();
-                if (value instanceof String) {
-                    sb.append('"');
-                    sb.append(((String) value).replaceAll("\"", "\\\\\""));
-                    sb.append('"');
-                } else {
-                    sb.append(value);
-                }
-            }
-        }
-        sb.append(" />");
-        executeMacro(writer, sb.toString());
-    }
-
-    private Environment getEnvironment(Appendable writer) throws TemplateException, IOException {
-        Environment environment = environments.get(writer);
-        if (environment == null) {
-            Map<String, Object> input = UtilMisc.toMap("key", null);
-            environment = FreeMarkerWorker.renderTemplate(macroLibrary, input, writer);
-            environments.put(writer, environment);
-        }
-        return environment;
-    }
-
-    public String getRendererName() {
-        return rendererName;
-    }
-
-    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException {
-        executeMacro(writer, "renderScreenBegin", null);
-    }
-
-    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException {
-        executeMacro(writer, "renderScreenEnd", null);
-    }
-
-    public void renderSectionBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
-        if (section.isMainSection()) {
-            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
-        }
-        if (this.widgetCommentsEnabled) {
-            Map<String, Object> parameters = new HashMap<String, Object>();
-            StringBuilder sb = new StringBuilder("Begin ");
-            sb.append(section.isMainSection() ? "Screen " : "Section Widget ");
-            sb.append(section.getBoundaryCommentName());
-            parameters.put("boundaryComment", sb.toString());
-            executeMacro(writer, "renderSectionBegin", parameters);
-        }
-    }
-    public void renderSectionEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
-        if (this.widgetCommentsEnabled) {
-            Map<String, Object> parameters = new HashMap<String, Object>();
-            StringBuilder sb = new StringBuilder();
-            sb.append("End ");
-            sb.append(section.isMainSection() ? "Screen " : "Section Widget ");
-            sb.append(section.getBoundaryCommentName());
-            parameters.put("boundaryComment", sb.toString());
-            executeMacro(writer, "renderSectionEnd", parameters);
-        }
-    }
-
-    public void renderContainerBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
-        String containerId = container.getId(context);
-        String autoUpdateTarget = container.getAutoUpdateTargetExdr(context);
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        String autoUpdateLink = "";
-        if (UtilValidate.isNotEmpty(autoUpdateTarget) && UtilHttp.isJavaScriptEnabled(request)) {
-            if (UtilValidate.isEmpty(containerId)) {
-                containerId = getNextElementId();
-            }
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-            RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-            autoUpdateLink = rh.makeLink(request, response, autoUpdateTarget);
-        }
-        Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put("id", containerId);
-        parameters.put("style", container.getStyle(context));
-        parameters.put("autoUpdateLink", autoUpdateLink);
-        parameters.put("autoUpdateInterval", container.getAutoUpdateInterval(context));
-        executeMacro(writer, "renderContainerBegin", parameters);
-    }
-
-    public void renderContainerEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
-        executeMacro(writer, "renderContainerEnd", null);
-    }
-
-    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException {
-        Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put("text", label.getText(context));
-        parameters.put("id", label.getId(context));
-        parameters.put("style", label.getStyle(context));
-        executeMacro(writer, "renderLabel", parameters);
-    }
-
-    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.HorizontalSeparator separator) throws IOException {
-        Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put("id", separator.getId(context));
-        parameters.put("style", separator.getStyle(context));
-        executeMacro(writer, "renderHorizontalSeparator", parameters);
-    }
-
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenLink link) throws IOException {
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-
-        String targetWindow = link.getTargetWindow(context);
-        String target = link.getTarget(context);
-
-        String uniqueItemName = link.getModelScreen().getName() + "_LF_" + UtilMisc.<String>addToBigDecimalInMap(context, "screenUniqueItemIndex", BigDecimal.ONE);
-
-        String linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request);
-        String linkUrl = "";
-        String actionUrl = "";
-        StringBuilder parameters=new StringBuilder();
-        String width = link.getWidth();
-        if (UtilValidate.isEmpty(width)) {
-            width = "300";
-        }
-        String height = link.getHeight();
-        if (UtilValidate.isEmpty(height)) {
-            height = "200";
-        }
-        if ("hidden-form".equals(linkType) || "ajax-window".equals(linkType)) {
-            StringBuilder sb = new StringBuilder();
-            WidgetWorker.buildHyperlinkUrl(sb, target, link.getUrlMode(), null, link.getPrefix(context),
-                    link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
-            actionUrl = sb.toString();
-            parameters.append("[");
-            for (Map.Entry<String, String> parameter: link.getParameterMap(context).entrySet()) {
-                if (parameters.length() >1) {
-                    parameters.append(",");
-                }
-                parameters.append("{'name':'");
-                parameters.append(parameter.getKey());
-                parameters.append("'");
-                parameters.append(",'value':'");
-                parameters.append(parameter.getValue());
-                parameters.append("'}");
-            }
-            parameters.append("]");
-
-        }
-        String id = link.getId(context);
-        String style = link.getStyle(context);
-        String name = link.getName(context);
-        String text = link.getText(context);
-        if (UtilValidate.isNotEmpty(target)) {
-            if (!"hidden-form".equals(linkType)) {
-                StringBuilder sb = new StringBuilder();
-                WidgetWorker.buildHyperlinkUrl(sb, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
-                        link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
-                linkUrl = sb.toString();
-            }
-        }
-        String imgStr = "";
-        ModelScreenWidget.ScreenImage img = link.getImage();
-        if (img != null) {
-            StringWriter sw = new StringWriter();
-            renderImage(sw, context, img);
-            imgStr = sw.toString();
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderLink ");
-        sr.append("parameterList=");
-        sr.append(parameters.length()==0?"\"\"":parameters.toString());
-        sr.append(" targetWindow=\"");
-        sr.append(targetWindow);
-        sr.append("\" target=\"");
-        sr.append(target);
-        sr.append("\" uniqueItemName=\"");
-        sr.append(uniqueItemName);
-        sr.append("\" linkType=\"");
-        sr.append(linkType);
-        sr.append("\" actionUrl=\"");
-        sr.append(actionUrl);
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" style=\"");
-        sr.append(style);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" width=\"");
-        sr.append(width);
-        sr.append("\" height=\"");
-        sr.append(height);
-        sr.append("\" linkUrl=\"");
-        sr.append(linkUrl);
-        sr.append("\" text=\"");
-        sr.append(text);
-        sr.append("\" imgStr=\"");
-        sr.append(imgStr.replaceAll("\"", "\\\\\""));
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenImage image) throws IOException {
-        if (image == null)
-            return ;
-        String src = image.getSrc(context);
-
-        String urlMode = image.getUrlMode();
-        boolean fullPath = false;
-        boolean secure = false;
-        boolean encode = false;
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        String urlString = "";
-        if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
-            if (request != null && response != null) {
-                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
-            } else {
-                urlString = src;
-            }
-        } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
-            if (request != null && response != null) {
-                StringBuilder newURL = new StringBuilder();
-                ContentUrlTag.appendContentPrefix(request, newURL);
-                newURL.append(src);
-                urlString = newURL.toString();
-            }
-        } else {
-            urlString = src;
-        }
-        Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put("src", src);
-        parameters.put("id", image.getId(context));
-        parameters.put("style", image.getStyle(context));
-        parameters.put("wid", image.getWidth(context));
-        parameters.put("hgt", image.getHeight(context));
-        parameters.put("border", image.getBorder(context));
-        parameters.put("alt", image.getAlt(context));
-        parameters.put("urlString", urlString);
-        executeMacro(writer, "renderImage", parameters);
-    }
-
-    public void renderContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-         String editRequest = content.getEditRequest(context);
-         String enableEditName = content.getEnableEditName(context);
-         String enableEditValue = (String)context.get(enableEditName);
-
-         if (Debug.verboseOn()) Debug.logVerbose("directEditRequest:" + editRequest, module);
-
-         Map<String, Object> parameters = new HashMap<String, Object>();
-         parameters.put("editRequest", editRequest);
-         parameters.put("enableEditValue", enableEditValue == null ? "" : enableEditValue);
-         parameters.put("editContainerStyle", content.getEditContainerStyle(context));
-         executeMacro(writer, "renderContentBegin", parameters);
-    }
-
-    public void renderContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        Locale locale = UtilMisc.ensureLocale(context.get("locale"));
-        //Boolean nullThruDatesOnly = Boolean.valueOf(false);
-        String mimeTypeId = "text/html";
-        String expandedContentId = content.getContentId(context);
-        String expandedDataResourceId = content.getDataResourceId(context);
-        String renderedContent = null;
-        LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
-        Delegator delegator = (Delegator) context.get("delegator");
-
-        // make a new map for content rendering; so our current map does not get clobbered
-        Map<String, Object> contentContext = new HashMap<String, Object>();
-        contentContext.putAll(context);
-        String dataResourceId = (String)contentContext.get("dataResourceId");
-        if (Debug.verboseOn()) Debug.logVerbose("expandedContentId:" + expandedContentId, module);
-
-        try {
-            if (UtilValidate.isNotEmpty(dataResourceId)) {
-                if (WidgetDataResourceWorker.dataresourceWorker != null) {
-                    renderedContent = WidgetDataResourceWorker.dataresourceWorker.renderDataResourceAsTextExt(delegator, dataResourceId, contentContext, locale, mimeTypeId, false);
-                } else {
-                    Debug.logError("Not rendering content, WidgetDataResourceWorker.dataresourceWorker not found.", module);
-                }
-            } else if (UtilValidate.isNotEmpty(expandedContentId)) {
-                if (WidgetContentWorker.contentWorker != null) {
-                    renderedContent = WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, expandedContentId, contentContext, locale, mimeTypeId, true);
-                } else {
-                    Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
-                }
-            } else if (UtilValidate.isNotEmpty(expandedDataResourceId)) {
-                if (WidgetDataResourceWorker.dataresourceWorker != null) {
-                    renderedContent = WidgetDataResourceWorker.dataresourceWorker.renderDataResourceAsTextExt(delegator, expandedDataResourceId, contentContext, locale, mimeTypeId, false);
-                } else {
-                    Debug.logError("Not rendering content, WidgetDataResourceWorker.dataresourceWorker not found.", module);
-                }
-            }
-            if (UtilValidate.isEmpty(renderedContent)) {
-                String editRequest = content.getEditRequest(context);
-                if (UtilValidate.isNotEmpty(editRequest)) {
-                    if (WidgetContentWorker.contentWorker != null) {
-                        WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, "NOCONTENTFOUND", writer, contentContext, locale, mimeTypeId, true);
-                    } else {
-                        Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
-                    }
-                }
-            } else {
-                if (content.xmlEscape()) {
-                    renderedContent = UtilFormatOut.encodeXmlValue(renderedContent);
-                }
-
-                writer.append(renderedContent);
-            }
-
-        } catch (GeneralException e) {
-            String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e.toString();
-            Debug.logError(e, errMsg, module);
-            //throw new RuntimeException(errMsg);
-        } catch (IOException e2) {
-            String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e2.toString();
-            Debug.logError(e2, errMsg, module);
-            //throw new RuntimeException(errMsg);
-        }
-    }
-
-    public void renderContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        String expandedContentId = content.getContentId(context);
-        String editMode = "Edit";
-        String editRequest = content.getEditRequest(context);
-        String enableEditName = content.getEnableEditName(context);
-        String enableEditValue = (String)context.get(enableEditName);
-        String urlString = "";
-        if (editRequest != null && editRequest.toUpperCase().indexOf("IMAGE") > 0) {
-            editMode += " Image";
-        }
-
-        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-            if (request != null && response != null) {
-                if (editRequest.indexOf("?") < 0)  editRequest += "?";
-                else editRequest += "&amp;";
-                editRequest += "contentId=" + expandedContentId;
-                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                urlString = rh.makeLink(request, response, editRequest, false, false, false);
-            }
-
-            Map<String, Object> parameters = new HashMap<String, Object>();
-            parameters.put("urlString", urlString);
-            parameters.put("editMode", editMode);
-            parameters.put("editContainerStyle", content.getEditContainerStyle(context));
-            parameters.put("editRequest", editRequest);
-            parameters.put("enableEditValue", enableEditValue);
-            executeMacro(writer, "renderContentEnd", parameters);
-        }
-    }
-
-    public void renderContentFrame(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        String dataResourceId = content.getDataResourceId(context);
-        String urlString = "/ViewSimpleContent?dataResourceId=" + dataResourceId;
-        String fullUrlString = "";
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        if (request != null && response != null) {
-            ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-            RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-            fullUrlString = rh.makeLink(request, response, urlString, true, false, false);
-        }
-
-        Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put("fullUrl", fullUrlString);
-        parameters.put("width", content.getWidth());
-        parameters.put("height", content.getHeight());
-        parameters.put("border", content.getBorder());
-        executeMacro(writer, "renderContentFrame", parameters);
-    }
-
-    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-         String enableEditName = content.getEnableEditName(context);
-         String enableEditValue = (String)context.get(enableEditName);
-
-         Map<String, Object> parameters = new HashMap<String, Object>();
-         parameters.put("editContainerStyle", content.getEditContainerStyle(context));
-         parameters.put("editRequest", content.getEditRequest(context));
-         parameters.put("enableEditValue", enableEditValue == null ? "" : enableEditValue);
-         executeMacro(writer, "renderSubContentBegin", parameters);
-    }
-
-    public void renderSubContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-         Locale locale = UtilMisc.ensureLocale(context.get("locale"));
-         String mimeTypeId = "text/html";
-         String expandedContentId = content.getContentId(context);
-         String expandedMapKey = content.getMapKey(context);
-         String renderedContent = "";
-         LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
-         Delegator delegator = (Delegator) context.get("delegator");
-
-         // create a new map for the content rendering; so our current context does not get overwritten!
-         Map<String, Object> contentContext = new HashMap<String, Object>();
-         contentContext.putAll(context);
-
-         try {
-             if (WidgetContentWorker.contentWorker != null) {
-                 renderedContent = WidgetContentWorker.contentWorker.renderSubContentAsTextExt(dispatcher, delegator, expandedContentId, expandedMapKey, contentContext, locale, mimeTypeId, true);
-                 //Debug.logInfo("renderedContent=" + renderedContent, module);
-             } else {
-                 Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
-             }
-             if (UtilValidate.isEmpty(renderedContent)) {
-                 String editRequest = content.getEditRequest(context);
-                 if (UtilValidate.isNotEmpty(editRequest)) {
-                     if (WidgetContentWorker.contentWorker != null) {
-                         WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, "NOCONTENTFOUND", writer, contentContext, locale, mimeTypeId, true);
-                     } else {
-                         Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
-                     }
-                 }
-             } else {
-                 if (content.xmlEscape()) {
-                     renderedContent = UtilFormatOut.encodeXmlValue(renderedContent);
-                 }
-
-                 writer.append(renderedContent);
-             }
-
-         } catch (GeneralException e) {
-             String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e.toString();
-             Debug.logError(e, errMsg, module);
-             //throw new RuntimeException(errMsg);
-         } catch (IOException e2) {
-             String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e2.toString();
-             Debug.logError(e2, errMsg, module);
-             //throw new RuntimeException(errMsg);
-         }
-    }
-
-    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-         String editMode = "Edit";
-         String editRequest = content.getEditRequest(context);
-         String enableEditName = content.getEnableEditName(context);
-         String enableEditValue = (String)context.get(enableEditName);
-         String expandedContentId = content.getContentId(context);
-         String expandedMapKey = content.getMapKey(context);
-         String urlString = "";
-         if (editRequest != null && editRequest.toUpperCase().indexOf("IMAGE") > 0) {
-             editMode += " Image";
-         }
-         if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
-             HttpServletResponse response = (HttpServletResponse) context.get("response");
-             HttpServletRequest request = (HttpServletRequest) context.get("request");
-             if (request != null && response != null) {
-                 if (editRequest.indexOf("?") < 0)  editRequest += "?";
-                 else editRequest += "&amp;";
-                 editRequest += "contentId=" + expandedContentId;
-                 if (UtilValidate.isNotEmpty(expandedMapKey)) {
-                     editRequest += "&amp;mapKey=" + expandedMapKey;
-                 }
-                 ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                 RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                 urlString = rh.makeLink(request, response, editRequest, false, false, false);
-             }
-         }
-
-         Map<String, Object> parameters = new HashMap<String, Object>();
-         parameters.put("urlString", urlString);
-         parameters.put("editMode", editMode);
-         parameters.put("editContainerStyle", content.getEditContainerStyle(context));
-         parameters.put("editRequest", editRequest);
-         parameters.put("enableEditValue", enableEditValue == null ? "" : enableEditValue);
-         executeMacro(writer, "renderSubContentEnd", parameters);
-    }
-
-
-    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, ModelScreenWidget.Screenlet screenlet) throws IOException {
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        boolean javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
-        ModelScreenWidget.Menu tabMenu = screenlet.getTabMenu();
-        if (tabMenu != null) {
-            tabMenu.renderWidgetString(writer, context, this);
-        }
-
-        String title = screenlet.getTitle(context);
-        boolean collapsible = screenlet.collapsible();
-        ModelScreenWidget.Menu navMenu = screenlet.getNavigationMenu();
-        ModelScreenWidget.Form navForm = screenlet.getNavigationForm();
-        String expandToolTip = "";
-        String collapseToolTip = "";
-        String fullUrlString = "";
-        String menuString = "";
-        boolean showMore = false;
-        if (UtilValidate.isNotEmpty(title) || navMenu != null || navForm != null || collapsible) {
-            showMore = true;
-            if (collapsible) {
-                this.getNextElementId();
-                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
-                Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
-                Map<String, Object> requestParameters = new HashMap<String, Object>(paramMap);
-                if (uiLabelMap != null) {
-                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
-                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
-                }
-                if (!javaScriptEnabled) {
-                    requestParameters.put(screenlet.getPreferenceKey(context) + "_collapsed", collapsed ? "false" : "true");
-                    String queryString = UtilHttp.urlEncodeArgs(requestParameters);
-                    fullUrlString = request.getRequestURI() + "?" + queryString;
-                }
-            }
-            StringWriter sb = new StringWriter();
-            if (navMenu != null) {
-                MenuStringRenderer savedRenderer = (MenuStringRenderer) context.get("menuStringRenderer");
-                MenuStringRenderer renderer = new ScreenletMenuRenderer(request, response);
-                context.put("menuStringRenderer", renderer);
-                navMenu.renderWidgetString(sb, context, this);
-                context.put("menuStringRenderer", savedRenderer);
-            } else if (navForm != null) {
-                renderScreenletPaginateMenu(sb, context, navForm);
-            }
-            menuString = sb.toString();
-        }
-
-        Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put("title", title);
-        parameters.put("collapsible", collapsible);
-        parameters.put("saveCollapsed", screenlet.saveCollapsed());
-        if (UtilValidate.isNotEmpty (screenlet.getId(context))) {
-            parameters.put("id", screenlet.getId(context));
-            parameters.put("collapsibleAreaId", screenlet.getId(context) + "_col");
-        } else {
-            parameters.put("id", "screenlet_" + screenLetsIdCounter);
-            parameters.put("collapsibleAreaId","screenlet_" + screenLetsIdCounter + "_col");
-            screenLetsIdCounter++;
-        }
-        parameters.put("expandToolTip", expandToolTip);
-        parameters.put("collapseToolTip", collapseToolTip);
-        parameters.put("fullUrlString", fullUrlString);
-        parameters.put("padded", screenlet.padded());
-        parameters.put("menuString", menuString);
-        parameters.put("showMore", showMore);
-        parameters.put("collapsed", collapsed);
-        parameters.put("javaScriptEnabled", javaScriptEnabled);
-        executeMacro(writer, "renderScreenletBegin", parameters);
-    }
-
-    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, ModelScreenWidget.Screenlet screenlet) throws GeneralException, IOException  {
-        if (subWidget.equals(screenlet.getNavigationForm())) {
-            HttpServletRequest request = (HttpServletRequest) context.get("request");
-            HttpServletResponse response = (HttpServletResponse) context.get("response");
-            if (request != null && response != null) {
-                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
-                globalCtx.put("NO_PAGINATOR", true);
-                FormStringRenderer savedRenderer = (FormStringRenderer) context.get("formStringRenderer");
-                MacroFormRenderer renderer = null;
-                try {
-                    renderer = new MacroFormRenderer(formrenderer, request, response);
-                } catch (TemplateException e) {
-                    Debug.logError("Not rendering content, error on MacroFormRenderer creation.", module);
-                }
-                renderer.setRenderPagination(false);
-                context.put("formStringRenderer", renderer);
-                subWidget.renderWidgetString(writer, context, this);
-                context.put("formStringRenderer", savedRenderer);
-            }
-        } else {
-            subWidget.renderWidgetString(writer, context, this);
-        }
-    }
-    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Screenlet screenlet) throws IOException {
-        executeMacro(writer, "renderScreenletEnd", null);
-    }
-
-    protected void renderScreenletPaginateMenu(Appendable writer, Map<String, Object> context, ModelScreenWidget.Form form) throws IOException {
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        ModelForm modelForm = form.getModelForm(context);
-        modelForm.runFormActions(context);
-        Paginator.preparePager(modelForm, context);
-        String targetService = modelForm.getPaginateTarget(context);
-        if (targetService == null) {
-            targetService = "${targetService}";
-        }
-
-        // get the parametrized pagination index and size fields
-        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
-        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
-        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
-
-        int viewIndex = Paginator.getViewIndex(modelForm, context);
-        int viewSize = Paginator.getViewSize(modelForm, context);
-        int listSize = Paginator.getListSize(context);
-
-        int highIndex = Paginator.getHighIndex(context);
-        int actualPageSize = Paginator.getActualPageSize(context);
-
-        // if this is all there seems to be (if listSize < 0, then size is unknown)
-        if (actualPageSize >= listSize && listSize >= 0) return;
-
-        // needed for the "Page" and "rows" labels
-        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
-        String ofLabel = "";
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        } else {
-            ofLabel = uiLabelMap.get("CommonOf");
-            ofLabel = ofLabel.toLowerCase();
-        }
-
-        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
-        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber)) viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
-        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber)) viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;
-
-        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-
-        Map<String, Object> inputFields = UtilGenerics.toMap(context.get("requestParameters"));
-        // strip out any multi form fields if the form is of type multi
-        if (modelForm.getType().equals("multi")) {
-            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
-        }
-        String queryString = UtilHttp.urlEncodeArgs(inputFields);
-        // strip legacy viewIndex/viewSize params from the query string
-        queryString = UtilHttp.stripViewParamsFromQueryString(queryString, "" + paginatorNumber);
-        // strip parametrized index/size params from the query string
-        HashSet<String> paramNames = new HashSet<String>();
-        paramNames.add(viewIndexParam);
-        paramNames.add(viewSizeParam);
-        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);
-
-        String anchor = "";
-        String paginateAnchor = modelForm.getPaginateTargetAnchor();
-        if (paginateAnchor != null) anchor = "#" + paginateAnchor;
-
-        // preparing the link text, so that later in the code we can reuse this and just add the viewIndex
-        String prepLinkText = "";
-        prepLinkText = targetService;
-        if (prepLinkText.indexOf("?") < 0) {
-            prepLinkText += "?";
-        } else if (!prepLinkText.endsWith("?")) {
-            prepLinkText += "&amp;";
-        }
-        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
-            prepLinkText += queryString + "&amp;";
-        }
-        prepLinkText += viewSizeParam + "=" + viewSize + "&amp;" + viewIndexParam + "=";
-
-        String linkText;
-
-
-        // The current screenlet title bar navigation syling requires rendering
-        // these links in reverse order
-        // Last button
-        String lastLinkUrl = "";
-        if (highIndex < listSize) {
-            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
-            linkText = prepLinkText + lastIndex + anchor;
-            lastLinkUrl = rh.makeLink(request, response, linkText);
-        }
-        String nextLinkUrl = "";
-        if (highIndex < listSize) {
-            linkText = prepLinkText + (viewIndex + 1) + anchor;
-            // - make the link
-            nextLinkUrl = rh.makeLink(request, response, linkText);
-        }
-        String previousLinkUrl = "";
-        if (viewIndex > 0) {
-            linkText = prepLinkText + (viewIndex - 1) + anchor;
-            previousLinkUrl = rh.makeLink(request, response, linkText);
-        }
-        String firstLinkUrl = "";
-        if (viewIndex > 0) {
-            linkText = prepLinkText + 0 + anchor;
-            firstLinkUrl = rh.makeLink(request, response, linkText);
-        }
-
-        Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put("lowIndex", Paginator.getLowIndex(context));
-        parameters.put("actualPageSize", actualPageSize);
-        parameters.put("ofLabel", ofLabel);
-        parameters.put("listSize", listSize);
-        parameters.put("paginateLastStyle", modelForm.getPaginateLastStyle());
-        parameters.put("lastLinkUrl", lastLinkUrl);
-        parameters.put("paginateLastLabel", modelForm.getPaginateLastLabel(context));
-        parameters.put("paginateNextStyle", modelForm.getPaginateNextStyle());
-        parameters.put("nextLinkUrl", nextLinkUrl);
-        parameters.put("paginateNextLabel", modelForm.getPaginateNextLabel(context));
-        parameters.put("paginatePreviousStyle", modelForm.getPaginatePreviousStyle());
-        parameters.put("paginatePreviousLabel", modelForm.getPaginatePreviousLabel(context));
-        parameters.put("previousLinkUrl", previousLinkUrl);
-        parameters.put("paginateFirstStyle", modelForm.getPaginateFirstStyle());
-        parameters.put("paginateFirstLabel", modelForm.getPaginateFirstLabel(context));
-        parameters.put("firstLinkUrl", firstLinkUrl);
-        executeMacro(writer, "renderScreenletPaginateMenu", parameters);
-    }
-
-    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
-        String portalPageId = portalPage.getActualPortalPageId(context);
-        String originalPortalPageId = portalPage.getOriginalPortalPageId(context);
-        String confMode = portalPage.getConfMode(context);
-
-        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
-        String addColumnLabel = "";
-        String addColumnHint = "";
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        } else {
-            addColumnLabel = uiLabelMap.get("CommonAddColumn");
-            addColumnHint = uiLabelMap.get("CommonAddAColumnToThisPortalPage");
-        }
-
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderPortalPageBegin ");
-        sr.append("originalPortalPageId=\"");
-        sr.append(originalPortalPageId);
-        sr.append("\" portalPageId=\"");
-        sr.append(portalPageId);
-        sr.append("\" confMode=\"");
-        sr.append(confMode);
-        sr.append("\" addColumnLabel=\"");
-        sr.append(addColumnLabel);
-        sr.append("\" addColumnHint=\"");
-        sr.append(addColumnHint);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderPortalPageEnd/>");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
-        String portalPageId = portalPage.getActualPortalPageId(context);
-        String originalPortalPageId = portalPage.getOriginalPortalPageId(context);
-        String columnSeqId = portalPageColumn.getString("columnSeqId");
-        String columnWidthPercentage = portalPageColumn.getString("columnWidthPercentage");
-        String columnWidthPixels = portalPageColumn.getString("columnWidthPixels");
-        String confMode = portalPage.getConfMode(context);
-
-        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
-        String delColumnLabel = "";
-        String delColumnHint = "";
-        String addPortletLabel = "";
-        String addPortletHint = "";
-        String colWidthLabel = "";
-        String setColumnSizeHint = "";
-        
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        } else {
-            delColumnLabel = uiLabelMap.get("CommonDeleteColumn");
-            delColumnHint = uiLabelMap.get("CommonDeleteThisColumn");
-
-            addPortletLabel = uiLabelMap.get("CommonAddAPortlet");
-            addPortletHint = uiLabelMap.get("CommonAddPortletToPage");
-            colWidthLabel = uiLabelMap.get("CommonWidth");
-            setColumnSizeHint = uiLabelMap.get("CommonSetColumnWidth");
-        }
-
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderPortalPageColumnBegin ");
-        sr.append("originalPortalPageId=\"");
-        sr.append(originalPortalPageId);
-        sr.append("\" portalPageId=\"");
-        sr.append(portalPageId);
-        sr.append("\" columnSeqId=\"");
-        sr.append(columnSeqId);
-        sr.append("\" ");
-        if (UtilValidate.isNotEmpty(columnWidthPixels)) {
-            sr.append("width=\"");
-            sr.append(columnWidthPixels);
-            sr.append("px\"");
-        } else if (UtilValidate.isNotEmpty(columnWidthPercentage)) {
-            sr.append("width=\"");
-            sr.append(columnWidthPercentage);
-            sr.append("%\"");
-        }
-        sr.append(" confMode=\"");
-        sr.append(confMode);
-        sr.append("\" delColumnLabel=\"");
-        sr.append(delColumnLabel);
-        sr.append("\" delColumnHint=\"");
-        sr.append(delColumnHint);
-        sr.append("\" addPortletLabel=\"");
-        sr.append(addPortletLabel);
-        sr.append("\" addPortletHint=\"");
-        sr.append(addPortletHint);
-        sr.append("\" colWidthLabel=\"");
-        sr.append(colWidthLabel);
-        sr.append("\" setColumnSizeHint=\"");
-        sr.append(setColumnSizeHint);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }   
-
-    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderPortalPageColumnEnd/>");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        String portalPageId = portalPage.getActualPortalPageId(context);
-        String originalPortalPageId = portalPage.getOriginalPortalPageId(context);
-        String portalPortletId = portalPortlet.getString("portalPortletId");
-        String portletSeqId = portalPortlet.getString("portletSeqId");
-        String columnSeqId = portalPortlet.getString("columnSeqId");
-        String confMode = portalPage.getConfMode(context);
-        String editFormName = portalPortlet.getString("editFormName");
-        String editFormLocation = portalPortlet.getString("editFormLocation");
-
-        String prevPortletId = (String) context.get("prevPortletId");
-        String prevPortletSeqId = (String) context.get("prevPortletSeqId");
-        String nextPortletId = (String) context.get("nextPortletId");
-        String nextPortletSeqId = (String) context.get("nextPortletSeqId");
-        String prevColumnSeqId = (String) context.get("prevColumnSeqId");
-        String nextColumnSeqId = (String) context.get("nextColumnSeqId");
-
-        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
-        String delPortletHint = "";
-        String editAttributeHint = "";
-        if (uiLabelMap == null) {
-            Debug.logWarning("Could not find uiLabelMap in context", module);
-        } else {
-            delPortletHint = uiLabelMap.get("CommonDeleteThisPortlet");
-            editAttributeHint = uiLabelMap.get("CommonEditPortletAttributes");
-        }
-
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderPortalPagePortletBegin ");
-        sr.append("originalPortalPageId=\"");
-        sr.append(originalPortalPageId);
-        sr.append("\" portalPageId=\"");
-        sr.append(portalPageId);
-        sr.append("\" portalPortletId=\"");
-        sr.append(portalPortletId);
-        sr.append("\" portletSeqId=\"");
-        sr.append(portletSeqId);
-        sr.append("\" prevPortletId=\"");
-        sr.append(prevPortletId);
-        sr.append("\" prevPortletSeqId=\"");
-        sr.append(prevPortletSeqId);
-        sr.append("\" nextPortletId=\"");
-        sr.append(nextPortletId);
-        sr.append("\" nextPortletSeqId=\"");
-        sr.append(nextPortletSeqId);
-        sr.append("\" columnSeqId=\"");
-        sr.append(columnSeqId);
-        sr.append("\" prevColumnSeqId=\"");
-        sr.append(prevColumnSeqId);
-        sr.append("\" nextColumnSeqId=\"");
-        sr.append(nextColumnSeqId);
-        sr.append("\" delPortletHint=\"");
-        sr.append(delPortletHint);
-        sr.append("\" editAttributeHint=\"");
-        sr.append(editAttributeHint);
-        sr.append("\" confMode=\"");
-        sr.append(confMode);
-        sr.append("\"");
-        if (UtilValidate.isNotEmpty(editFormName) && UtilValidate.isNotEmpty(editFormLocation)) {
-            sr.append(" editAttribute=\"true\"");
-        }
-        sr.append("/>");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        String confMode = portalPage.getConfMode(context);
-
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderPortalPagePortletEnd ");
-        sr.append(" confMode=\"");
-        sr.append(confMode);
-        sr.append("\" />");
-        executeMacro(writer, sr.toString());
-    }
-
-    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        String portalPortletId = portalPortlet.getString("portalPortletId");
-        String screenName = portalPortlet.getString("screenName");
-        String screenLocation = portalPortlet.getString("screenLocation");
-
-        ModelScreen modelScreen = null;
-        if (UtilValidate.isNotEmpty(screenName) && UtilValidate.isNotEmpty(screenLocation)) {
-            try {
-                modelScreen = ScreenFactory.getScreenFromLocation(screenLocation, screenName);
-            } catch (IOException e) {
-                String errMsg = "Error rendering portlet ID [" + portalPortletId + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (SAXException e) {
-                String errMsg = "Error rendering portlet ID [" + portalPortletId + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (ParserConfigurationException e) {
-                String errMsg = "Error rendering portlet ID [" + portalPortletId + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-        modelScreen.renderScreenString(writer, context, this);
-    }
-
-    @Override
-    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ColumnContainer columnContainer) throws IOException {
-        String id = columnContainer.getId(context);
-        String style = columnContainer.getStyle(context);
-        StringBuilder sb = new StringBuilder("<@renderColumnContainerBegin");
-        sb.append(" id=\"");
-        sb.append(id);
-        sb.append("\" style=\"");
-        sb.append(style);
-        sb.append("\" />");
-        executeMacro(writer, sb.toString());
-        for (Column column : columnContainer.getColumns()) {
-            id = column.getId(context);
-            style = column.getStyle(context);
-            sb = new StringBuilder("<@renderColumnBegin");
-            sb.append(" id=\"");
-            sb.append(id);
-            sb.append("\" style=\"");
-            sb.append(style);
-            sb.append("\" />");
-            executeMacro(writer, sb.toString());
-            for (ModelScreenWidget subWidget : column.getSubWidgets()) {
-                try {
-                    subWidget.renderWidgetString(writer, context, this);
-                } catch (GeneralException e) {
-                    throw new IOException(e);
-                }
-            }
-            executeMacro(writer, "<@renderColumnEnd />");
-        }
-        executeMacro(writer, "<@renderColumnContainerEnd />");
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.macro;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilHttp;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.template.FreeMarkerWorker;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.webapp.control.RequestHandler;
+import org.ofbiz.webapp.taglib.ContentUrlTag;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.content.WidgetContentWorker;
+import org.ofbiz.widget.content.WidgetDataResourceWorker;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelScreen;
+import org.ofbiz.widget.model.ModelScreenWidget;
+import org.ofbiz.widget.model.ModelScreenWidget.Column;
+import org.ofbiz.widget.model.ModelScreenWidget.ColumnContainer;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.model.ScreenFactory;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+import org.ofbiz.widget.renderer.Paginator;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.html.HtmlScreenRenderer.ScreenletMenuRenderer;
+import org.xml.sax.SAXException;
+
+import freemarker.core.Environment;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+public class MacroScreenRenderer implements ScreenStringRenderer {
+
+    public static final String module = MacroScreenRenderer.class.getName();
+    private Template macroLibrary;
+    private WeakHashMap<Appendable, Environment> environments = new WeakHashMap<Appendable, Environment>();
+    private String rendererName;
+    private int elementId = 999;
+    protected boolean widgetCommentsEnabled = false;
+    private static final String formrenderer = UtilProperties.getPropertyValue("widget", "screen.formrenderer");
+    private int screenLetsIdCounter = 1;
+
+    public MacroScreenRenderer(String name, String macroLibraryPath) throws TemplateException, IOException {
+        macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
+        rendererName = name;
+    }
+
+    @Deprecated
+    public MacroScreenRenderer(String name, String macroLibraryPath, Appendable writer) throws TemplateException, IOException {
+        this(name, macroLibraryPath);
+    }
+
+    private String getNextElementId() {
+        elementId++;
+        return "hsr" + elementId;
+    }
+
+    private void executeMacro(Appendable writer, String macro) throws IOException {
+        try {
+            Environment environment = getEnvironment(writer);
+            Reader templateReader = new StringReader(macro);
+            // FIXME: I am using a Date as an hack to provide a unique name for the template...
+            Template template = new Template((new java.util.Date()).toString(), templateReader, FreeMarkerWorker.getDefaultOfbizConfig());
+            templateReader.close();
+            environment.include(template);
+        } catch (TemplateException e) {
+            Debug.logError(e, "Error rendering screen macro [" + macro + "] thru ftl", module);
+        } catch (IOException e) {
+            Debug.logError(e, "Error rendering screen macro [" + macro + "] thru ftl", module);
+        }
+    }
+
+    private void executeMacro(Appendable writer, String macroName, Map<String, Object> parameters) throws IOException {
+        StringBuilder sb = new StringBuilder("<@");
+        sb.append(macroName);
+        if (parameters != null) {
+            for (Map.Entry<String, Object> parameter : parameters.entrySet()) {
+                sb.append(' ');
+                sb.append(parameter.getKey());
+                sb.append("=");
+                Object value = parameter.getValue();
+                if (value instanceof String) {
+                    sb.append('"');
+                    sb.append(((String) value).replaceAll("\"", "\\\\\""));
+                    sb.append('"');
+                } else {
+                    sb.append(value);
+                }
+            }
+        }
+        sb.append(" />");
+        executeMacro(writer, sb.toString());
+    }
+
+    private Environment getEnvironment(Appendable writer) throws TemplateException, IOException {
+        Environment environment = environments.get(writer);
+        if (environment == null) {
+            Map<String, Object> input = UtilMisc.toMap("key", null);
+            environment = FreeMarkerWorker.renderTemplate(macroLibrary, input, writer);
+            environments.put(writer, environment);
+        }
+        return environment;
+    }
+
+    public String getRendererName() {
+        return rendererName;
+    }
+
+    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException {
+        executeMacro(writer, "renderScreenBegin", null);
+    }
+
+    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException {
+        executeMacro(writer, "renderScreenEnd", null);
+    }
+
+    public void renderSectionBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
+        if (section.isMainSection()) {
+            this.widgetCommentsEnabled = ModelWidget.widgetBoundaryCommentsEnabled(context);
+        }
+        if (this.widgetCommentsEnabled) {
+            Map<String, Object> parameters = new HashMap<String, Object>();
+            StringBuilder sb = new StringBuilder("Begin ");
+            sb.append(section.isMainSection() ? "Screen " : "Section Widget ");
+            sb.append(section.getBoundaryCommentName());
+            parameters.put("boundaryComment", sb.toString());
+            executeMacro(writer, "renderSectionBegin", parameters);
+        }
+    }
+    public void renderSectionEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
+        if (this.widgetCommentsEnabled) {
+            Map<String, Object> parameters = new HashMap<String, Object>();
+            StringBuilder sb = new StringBuilder();
+            sb.append("End ");
+            sb.append(section.isMainSection() ? "Screen " : "Section Widget ");
+            sb.append(section.getBoundaryCommentName());
+            parameters.put("boundaryComment", sb.toString());
+            executeMacro(writer, "renderSectionEnd", parameters);
+        }
+    }
+
+    public void renderContainerBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
+        String containerId = container.getId(context);
+        String autoUpdateTarget = container.getAutoUpdateTargetExdr(context);
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        String autoUpdateLink = "";
+        if (UtilValidate.isNotEmpty(autoUpdateTarget) && UtilHttp.isJavaScriptEnabled(request)) {
+            if (UtilValidate.isEmpty(containerId)) {
+                containerId = getNextElementId();
+            }
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+            RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+            autoUpdateLink = rh.makeLink(request, response, autoUpdateTarget);
+        }
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("id", containerId);
+        parameters.put("style", container.getStyle(context));
+        parameters.put("autoUpdateLink", autoUpdateLink);
+        parameters.put("autoUpdateInterval", container.getAutoUpdateInterval(context));
+        executeMacro(writer, "renderContainerBegin", parameters);
+    }
+
+    public void renderContainerEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
+        executeMacro(writer, "renderContainerEnd", null);
+    }
+
+    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException {
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("text", label.getText(context));
+        parameters.put("id", label.getId(context));
+        parameters.put("style", label.getStyle(context));
+        executeMacro(writer, "renderLabel", parameters);
+    }
+
+    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.HorizontalSeparator separator) throws IOException {
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("id", separator.getId(context));
+        parameters.put("style", separator.getStyle(context));
+        executeMacro(writer, "renderHorizontalSeparator", parameters);
+    }
+
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenLink link) throws IOException {
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+
+        String targetWindow = link.getTargetWindow(context);
+        String target = link.getTarget(context);
+
+        String uniqueItemName = link.getModelScreen().getName() + "_LF_" + UtilMisc.<String>addToBigDecimalInMap(context, "screenUniqueItemIndex", BigDecimal.ONE);
+
+        String linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), target, link.getUrlMode(), request);
+        String linkUrl = "";
+        String actionUrl = "";
+        StringBuilder parameters=new StringBuilder();
+        String width = link.getWidth();
+        if (UtilValidate.isEmpty(width)) {
+            width = "300";
+        }
+        String height = link.getHeight();
+        if (UtilValidate.isEmpty(height)) {
+            height = "200";
+        }
+        if ("hidden-form".equals(linkType) || "ajax-window".equals(linkType)) {
+            StringBuilder sb = new StringBuilder();
+            WidgetWorker.buildHyperlinkUrl(sb, target, link.getUrlMode(), null, link.getPrefix(context),
+                    link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
+            actionUrl = sb.toString();
+            parameters.append("[");
+            for (Map.Entry<String, String> parameter: link.getParameterMap(context).entrySet()) {
+                if (parameters.length() >1) {
+                    parameters.append(",");
+                }
+                parameters.append("{'name':'");
+                parameters.append(parameter.getKey());
+                parameters.append("'");
+                parameters.append(",'value':'");
+                parameters.append(parameter.getValue());
+                parameters.append("'}");
+            }
+            parameters.append("]");
+
+        }
+        String id = link.getId(context);
+        String style = link.getStyle(context);
+        String name = link.getName(context);
+        String text = link.getText(context);
+        if (UtilValidate.isNotEmpty(target)) {
+            if (!"hidden-form".equals(linkType)) {
+                StringBuilder sb = new StringBuilder();
+                WidgetWorker.buildHyperlinkUrl(sb, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
+                        link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);
+                linkUrl = sb.toString();
+            }
+        }
+        String imgStr = "";
+        ModelScreenWidget.ScreenImage img = link.getImage();
+        if (img != null) {
+            StringWriter sw = new StringWriter();
+            renderImage(sw, context, img);
+            imgStr = sw.toString();
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderLink ");
+        sr.append("parameterList=");
+        sr.append(parameters.length()==0?"\"\"":parameters.toString());
+        sr.append(" targetWindow=\"");
+        sr.append(targetWindow);
+        sr.append("\" target=\"");
+        sr.append(target);
+        sr.append("\" uniqueItemName=\"");
+        sr.append(uniqueItemName);
+        sr.append("\" linkType=\"");
+        sr.append(linkType);
+        sr.append("\" actionUrl=\"");
+        sr.append(actionUrl);
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" style=\"");
+        sr.append(style);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" width=\"");
+        sr.append(width);
+        sr.append("\" height=\"");
+        sr.append(height);
+        sr.append("\" linkUrl=\"");
+        sr.append(linkUrl);
+        sr.append("\" text=\"");
+        sr.append(text);
+        sr.append("\" imgStr=\"");
+        sr.append(imgStr.replaceAll("\"", "\\\\\""));
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenImage image) throws IOException {
+        if (image == null)
+            return ;
+        String src = image.getSrc(context);
+
+        String urlMode = image.getUrlMode();
+        boolean fullPath = false;
+        boolean secure = false;
+        boolean encode = false;
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        String urlString = "";
+        if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
+            if (request != null && response != null) {
+                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
+            } else {
+                urlString = src;
+            }
+        } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
+            if (request != null && response != null) {
+                StringBuilder newURL = new StringBuilder();
+                ContentUrlTag.appendContentPrefix(request, newURL);
+                newURL.append(src);
+                urlString = newURL.toString();
+            }
+        } else {
+            urlString = src;
+        }
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("src", src);
+        parameters.put("id", image.getId(context));
+        parameters.put("style", image.getStyle(context));
+        parameters.put("wid", image.getWidth(context));
+        parameters.put("hgt", image.getHeight(context));
+        parameters.put("border", image.getBorder(context));
+        parameters.put("alt", image.getAlt(context));
+        parameters.put("urlString", urlString);
+        executeMacro(writer, "renderImage", parameters);
+    }
+
+    public void renderContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+         String editRequest = content.getEditRequest(context);
+         String enableEditName = content.getEnableEditName(context);
+         String enableEditValue = (String)context.get(enableEditName);
+
+         if (Debug.verboseOn()) Debug.logVerbose("directEditRequest:" + editRequest, module);
+
+         Map<String, Object> parameters = new HashMap<String, Object>();
+         parameters.put("editRequest", editRequest);
+         parameters.put("enableEditValue", enableEditValue == null ? "" : enableEditValue);
+         parameters.put("editContainerStyle", content.getEditContainerStyle(context));
+         executeMacro(writer, "renderContentBegin", parameters);
+    }
+
+    public void renderContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        Locale locale = UtilMisc.ensureLocale(context.get("locale"));
+        //Boolean nullThruDatesOnly = Boolean.valueOf(false);
+        String mimeTypeId = "text/html";
+        String expandedContentId = content.getContentId(context);
+        String expandedDataResourceId = content.getDataResourceId(context);
+        String renderedContent = null;
+        LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+        Delegator delegator = (Delegator) context.get("delegator");
+
+        // make a new map for content rendering; so our current map does not get clobbered
+        Map<String, Object> contentContext = new HashMap<String, Object>();
+        contentContext.putAll(context);
+        String dataResourceId = (String)contentContext.get("dataResourceId");
+        if (Debug.verboseOn()) Debug.logVerbose("expandedContentId:" + expandedContentId, module);
+
+        try {
+            if (UtilValidate.isNotEmpty(dataResourceId)) {
+                if (WidgetDataResourceWorker.dataresourceWorker != null) {
+                    renderedContent = WidgetDataResourceWorker.dataresourceWorker.renderDataResourceAsTextExt(delegator, dataResourceId, contentContext, locale, mimeTypeId, false);
+                } else {
+                    Debug.logError("Not rendering content, WidgetDataResourceWorker.dataresourceWorker not found.", module);
+                }
+            } else if (UtilValidate.isNotEmpty(expandedContentId)) {
+                if (WidgetContentWorker.contentWorker != null) {
+                    renderedContent = WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, expandedContentId, contentContext, locale, mimeTypeId, true);
+                } else {
+                    Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
+                }
+            } else if (UtilValidate.isNotEmpty(expandedDataResourceId)) {
+                if (WidgetDataResourceWorker.dataresourceWorker != null) {
+                    renderedContent = WidgetDataResourceWorker.dataresourceWorker.renderDataResourceAsTextExt(delegator, expandedDataResourceId, contentContext, locale, mimeTypeId, false);
+                } else {
+                    Debug.logError("Not rendering content, WidgetDataResourceWorker.dataresourceWorker not found.", module);
+                }
+            }
+            if (UtilValidate.isEmpty(renderedContent)) {
+                String editRequest = content.getEditRequest(context);
+                if (UtilValidate.isNotEmpty(editRequest)) {
+                    if (WidgetContentWorker.contentWorker != null) {
+                        WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, "NOCONTENTFOUND", writer, contentContext, locale, mimeTypeId, true);
+                    } else {
+                        Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
+                    }
+                }
+            } else {
+                if (content.xmlEscape()) {
+                    renderedContent = UtilFormatOut.encodeXmlValue(renderedContent);
+                }
+
+                writer.append(renderedContent);
+            }
+
+        } catch (GeneralException e) {
+            String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e.toString();
+            Debug.logError(e, errMsg, module);
+            //throw new RuntimeException(errMsg);
+        } catch (IOException e2) {
+            String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e2.toString();
+            Debug.logError(e2, errMsg, module);
+            //throw new RuntimeException(errMsg);
+        }
+    }
+
+    public void renderContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        String expandedContentId = content.getContentId(context);
+        String editMode = "Edit";
+        String editRequest = content.getEditRequest(context);
+        String enableEditName = content.getEnableEditName(context);
+        String enableEditValue = (String)context.get(enableEditName);
+        String urlString = "";
+        if (editRequest != null && editRequest.toUpperCase().indexOf("IMAGE") > 0) {
+            editMode += " Image";
+        }
+
+        if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+            if (request != null && response != null) {
+                if (editRequest.indexOf("?") < 0)  editRequest += "?";
+                else editRequest += "&amp;";
+                editRequest += "contentId=" + expandedContentId;
+                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                urlString = rh.makeLink(request, response, editRequest, false, false, false);
+            }
+
+            Map<String, Object> parameters = new HashMap<String, Object>();
+            parameters.put("urlString", urlString);
+            parameters.put("editMode", editMode);
+            parameters.put("editContainerStyle", content.getEditContainerStyle(context));
+            parameters.put("editRequest", editRequest);
+            parameters.put("enableEditValue", enableEditValue);
+            executeMacro(writer, "renderContentEnd", parameters);
+        }
+    }
+
+    public void renderContentFrame(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        String dataResourceId = content.getDataResourceId(context);
+        String urlString = "/ViewSimpleContent?dataResourceId=" + dataResourceId;
+        String fullUrlString = "";
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        if (request != null && response != null) {
+            ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+            RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+            fullUrlString = rh.makeLink(request, response, urlString, true, false, false);
+        }
+
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("fullUrl", fullUrlString);
+        parameters.put("width", content.getWidth());
+        parameters.put("height", content.getHeight());
+        parameters.put("border", content.getBorder());
+        executeMacro(writer, "renderContentFrame", parameters);
+    }
+
+    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+         String enableEditName = content.getEnableEditName(context);
+         String enableEditValue = (String)context.get(enableEditName);
+
+         Map<String, Object> parameters = new HashMap<String, Object>();
+         parameters.put("editContainerStyle", content.getEditContainerStyle(context));
+         parameters.put("editRequest", content.getEditRequest(context));
+         parameters.put("enableEditValue", enableEditValue == null ? "" : enableEditValue);
+         executeMacro(writer, "renderSubContentBegin", parameters);
+    }
+
+    public void renderSubContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+         Locale locale = UtilMisc.ensureLocale(context.get("locale"));
+         String mimeTypeId = "text/html";
+         String expandedContentId = content.getContentId(context);
+         String expandedMapKey = content.getMapKey(context);
+         String renderedContent = "";
+         LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+         Delegator delegator = (Delegator) context.get("delegator");
+
+         // create a new map for the content rendering; so our current context does not get overwritten!
+         Map<String, Object> contentContext = new HashMap<String, Object>();
+         contentContext.putAll(context);
+
+         try {
+             if (WidgetContentWorker.contentWorker != null) {
+                 renderedContent = WidgetContentWorker.contentWorker.renderSubContentAsTextExt(dispatcher, delegator, expandedContentId, expandedMapKey, contentContext, locale, mimeTypeId, true);
+                 //Debug.logInfo("renderedContent=" + renderedContent, module);
+             } else {
+                 Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
+             }
+             if (UtilValidate.isEmpty(renderedContent)) {
+                 String editRequest = content.getEditRequest(context);
+                 if (UtilValidate.isNotEmpty(editRequest)) {
+                     if (WidgetContentWorker.contentWorker != null) {
+                         WidgetContentWorker.contentWorker.renderContentAsTextExt(dispatcher, delegator, "NOCONTENTFOUND", writer, contentContext, locale, mimeTypeId, true);
+                     } else {
+                         Debug.logError("Not rendering content, WidgetContentWorker.contentWorker not found.", module);
+                     }
+                 }
+             } else {
+                 if (content.xmlEscape()) {
+                     renderedContent = UtilFormatOut.encodeXmlValue(renderedContent);
+                 }
+
+                 writer.append(renderedContent);
+             }
+
+         } catch (GeneralException e) {
+             String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e.toString();
+             Debug.logError(e, errMsg, module);
+             //throw new RuntimeException(errMsg);
+         } catch (IOException e2) {
+             String errMsg = "Error rendering included content with id [" + expandedContentId + "] : " + e2.toString();
+             Debug.logError(e2, errMsg, module);
+             //throw new RuntimeException(errMsg);
+         }
+    }
+
+    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+         String editMode = "Edit";
+         String editRequest = content.getEditRequest(context);
+         String enableEditName = content.getEnableEditName(context);
+         String enableEditValue = (String)context.get(enableEditName);
+         String expandedContentId = content.getContentId(context);
+         String expandedMapKey = content.getMapKey(context);
+         String urlString = "";
+         if (editRequest != null && editRequest.toUpperCase().indexOf("IMAGE") > 0) {
+             editMode += " Image";
+         }
+         if (UtilValidate.isNotEmpty(editRequest) && "true".equals(enableEditValue)) {
+             HttpServletResponse response = (HttpServletResponse) context.get("response");
+             HttpServletRequest request = (HttpServletRequest) context.get("request");
+             if (request != null && response != null) {
+                 if (editRequest.indexOf("?") < 0)  editRequest += "?";
+                 else editRequest += "&amp;";
+                 editRequest += "contentId=" + expandedContentId;
+                 if (UtilValidate.isNotEmpty(expandedMapKey)) {
+                     editRequest += "&amp;mapKey=" + expandedMapKey;
+                 }
+                 ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                 RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                 urlString = rh.makeLink(request, response, editRequest, false, false, false);
+             }
+         }
+
+         Map<String, Object> parameters = new HashMap<String, Object>();
+         parameters.put("urlString", urlString);
+         parameters.put("editMode", editMode);
+         parameters.put("editContainerStyle", content.getEditContainerStyle(context));
+         parameters.put("editRequest", editRequest);
+         parameters.put("enableEditValue", enableEditValue == null ? "" : enableEditValue);
+         executeMacro(writer, "renderSubContentEnd", parameters);
+    }
+
+
+    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, ModelScreenWidget.Screenlet screenlet) throws IOException {
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        boolean javaScriptEnabled = UtilHttp.isJavaScriptEnabled(request);
+        ModelScreenWidget.Menu tabMenu = screenlet.getTabMenu();
+        if (tabMenu != null) {
+            tabMenu.renderWidgetString(writer, context, this);
+        }
+
+        String title = screenlet.getTitle(context);
+        boolean collapsible = screenlet.collapsible();
+        ModelScreenWidget.Menu navMenu = screenlet.getNavigationMenu();
+        ModelScreenWidget.Form navForm = screenlet.getNavigationForm();
+        String expandToolTip = "";
+        String collapseToolTip = "";
+        String fullUrlString = "";
+        String menuString = "";
+        boolean showMore = false;
+        if (UtilValidate.isNotEmpty(title) || navMenu != null || navForm != null || collapsible) {
+            showMore = true;
+            if (collapsible) {
+                this.getNextElementId();
+                Map<String, Object> uiLabelMap = UtilGenerics.checkMap(context.get("uiLabelMap"));
+                Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
+                Map<String, Object> requestParameters = new HashMap<String, Object>(paramMap);
+                if (uiLabelMap != null) {
+                    expandToolTip = (String) uiLabelMap.get("CommonExpand");
+                    collapseToolTip = (String) uiLabelMap.get("CommonCollapse");
+                }
+                if (!javaScriptEnabled) {
+                    requestParameters.put(screenlet.getPreferenceKey(context) + "_collapsed", collapsed ? "false" : "true");
+                    String queryString = UtilHttp.urlEncodeArgs(requestParameters);
+                    fullUrlString = request.getRequestURI() + "?" + queryString;
+                }
+            }
+            StringWriter sb = new StringWriter();
+            if (navMenu != null) {
+                MenuStringRenderer savedRenderer = (MenuStringRenderer) context.get("menuStringRenderer");
+                MenuStringRenderer renderer = new ScreenletMenuRenderer(request, response);
+                context.put("menuStringRenderer", renderer);
+                navMenu.renderWidgetString(sb, context, this);
+                context.put("menuStringRenderer", savedRenderer);
+            } else if (navForm != null) {
+                renderScreenletPaginateMenu(sb, context, navForm);
+            }
+            menuString = sb.toString();
+        }
+
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("title", title);
+        parameters.put("collapsible", collapsible);
+        parameters.put("saveCollapsed", screenlet.saveCollapsed());
+        if (UtilValidate.isNotEmpty (screenlet.getId(context))) {
+            parameters.put("id", screenlet.getId(context));
+            parameters.put("collapsibleAreaId", screenlet.getId(context) + "_col");
+        } else {
+            parameters.put("id", "screenlet_" + screenLetsIdCounter);
+            parameters.put("collapsibleAreaId","screenlet_" + screenLetsIdCounter + "_col");
+            screenLetsIdCounter++;
+        }
+        parameters.put("expandToolTip", expandToolTip);
+        parameters.put("collapseToolTip", collapseToolTip);
+        parameters.put("fullUrlString", fullUrlString);
+        parameters.put("padded", screenlet.padded());
+        parameters.put("menuString", menuString);
+        parameters.put("showMore", showMore);
+        parameters.put("collapsed", collapsed);
+        parameters.put("javaScriptEnabled", javaScriptEnabled);
+        executeMacro(writer, "renderScreenletBegin", parameters);
+    }
+
+    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, ModelScreenWidget.Screenlet screenlet) throws GeneralException, IOException  {
+        if (subWidget.equals(screenlet.getNavigationForm())) {
+            HttpServletRequest request = (HttpServletRequest) context.get("request");
+            HttpServletResponse response = (HttpServletResponse) context.get("response");
+            if (request != null && response != null) {
+                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
+                globalCtx.put("NO_PAGINATOR", true);
+                FormStringRenderer savedRenderer = (FormStringRenderer) context.get("formStringRenderer");
+                MacroFormRenderer renderer = null;
+                try {
+                    renderer = new MacroFormRenderer(formrenderer, request, response);
+                } catch (TemplateException e) {
+                    Debug.logError("Not rendering content, error on MacroFormRenderer creation.", module);
+                }
+                renderer.setRenderPagination(false);
+                context.put("formStringRenderer", renderer);
+                subWidget.renderWidgetString(writer, context, this);
+                context.put("formStringRenderer", savedRenderer);
+            }
+        } else {
+            subWidget.renderWidgetString(writer, context, this);
+        }
+    }
+    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Screenlet screenlet) throws IOException {
+        executeMacro(writer, "renderScreenletEnd", null);
+    }
+
+    protected void renderScreenletPaginateMenu(Appendable writer, Map<String, Object> context, ModelScreenWidget.Form form) throws IOException {
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        ModelForm modelForm = form.getModelForm(context);
+        modelForm.runFormActions(context);
+        Paginator.preparePager(modelForm, context);
+        String targetService = modelForm.getPaginateTarget(context);
+        if (targetService == null) {
+            targetService = "${targetService}";
+        }
+
+        // get the parametrized pagination index and size fields
+        int paginatorNumber = WidgetWorker.getPaginatorNumber(context);
+        String viewIndexParam = modelForm.getMultiPaginateIndexField(context);
+        String viewSizeParam = modelForm.getMultiPaginateSizeField(context);
+
+        int viewIndex = Paginator.getViewIndex(modelForm, context);
+        int viewSize = Paginator.getViewSize(modelForm, context);
+        int listSize = Paginator.getListSize(context);
+
+        int highIndex = Paginator.getHighIndex(context);
+        int actualPageSize = Paginator.getActualPageSize(context);
+
+        // if this is all there seems to be (if listSize < 0, then size is unknown)
+        if (actualPageSize >= listSize && listSize >= 0) return;
+
+        // needed for the "Page" and "rows" labels
+        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
+        String ofLabel = "";
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        } else {
+            ofLabel = uiLabelMap.get("CommonOf");
+            ofLabel = ofLabel.toLowerCase();
+        }
+
+        // for legacy support, the viewSizeParam is VIEW_SIZE and viewIndexParam is VIEW_INDEX when the fields are "viewSize" and "viewIndex"
+        if (viewIndexParam.equals("viewIndex" + "_" + paginatorNumber)) viewIndexParam = "VIEW_INDEX" + "_" + paginatorNumber;
+        if (viewSizeParam.equals("viewSize" + "_" + paginatorNumber)) viewSizeParam = "VIEW_SIZE" + "_" + paginatorNumber;
+
+        ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+        RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+
+        Map<String, Object> inputFields = UtilGenerics.toMap(context.get("requestParameters"));
+        // strip out any multi form fields if the form is of type multi
+        if (modelForm.getType().equals("multi")) {
+            inputFields = UtilHttp.removeMultiFormParameters(inputFields);
+        }
+        String queryString = UtilHttp.urlEncodeArgs(inputFields);
+        // strip legacy viewIndex/viewSize params from the query string
+        queryString = UtilHttp.stripViewParamsFromQueryString(queryString, "" + paginatorNumber);
+        // strip parametrized index/size params from the query string
+        HashSet<String> paramNames = new HashSet<String>();
+        paramNames.add(viewIndexParam);
+        paramNames.add(viewSizeParam);
+        queryString = UtilHttp.stripNamedParamsFromQueryString(queryString, paramNames);
+
+        String anchor = "";
+        String paginateAnchor = modelForm.getPaginateTargetAnchor();
+        if (paginateAnchor != null) anchor = "#" + paginateAnchor;
+
+        // preparing the link text, so that later in the code we can reuse this and just add the viewIndex
+        String prepLinkText = "";
+        prepLinkText = targetService;
+        if (prepLinkText.indexOf("?") < 0) {
+            prepLinkText += "?";
+        } else if (!prepLinkText.endsWith("?")) {
+            prepLinkText += "&amp;";
+        }
+        if (!UtilValidate.isEmpty(queryString) && !queryString.equals("null")) {
+            prepLinkText += queryString + "&amp;";
+        }
+        prepLinkText += viewSizeParam + "=" + viewSize + "&amp;" + viewIndexParam + "=";
+
+        String linkText;
+
+
+        // The current screenlet title bar navigation syling requires rendering
+        // these links in reverse order
+        // Last button
+        String lastLinkUrl = "";
+        if (highIndex < listSize) {
+            int lastIndex = UtilMisc.getViewLastIndex(listSize, viewSize);
+            linkText = prepLinkText + lastIndex + anchor;
+            lastLinkUrl = rh.makeLink(request, response, linkText);
+        }
+        String nextLinkUrl = "";
+        if (highIndex < listSize) {
+            linkText = prepLinkText + (viewIndex + 1) + anchor;
+            // - make the link
+            nextLinkUrl = rh.makeLink(request, response, linkText);
+        }
+        String previousLinkUrl = "";
+        if (viewIndex > 0) {
+            linkText = prepLinkText + (viewIndex - 1) + anchor;
+            previousLinkUrl = rh.makeLink(request, response, linkText);
+        }
+        String firstLinkUrl = "";
+        if (viewIndex > 0) {
+            linkText = prepLinkText + 0 + anchor;
+            firstLinkUrl = rh.makeLink(request, response, linkText);
+        }
+
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("lowIndex", Paginator.getLowIndex(context));
+        parameters.put("actualPageSize", actualPageSize);
+        parameters.put("ofLabel", ofLabel);
+        parameters.put("listSize", listSize);
+        parameters.put("paginateLastStyle", modelForm.getPaginateLastStyle());
+        parameters.put("lastLinkUrl", lastLinkUrl);
+        parameters.put("paginateLastLabel", modelForm.getPaginateLastLabel(context));
+        parameters.put("paginateNextStyle", modelForm.getPaginateNextStyle());
+        parameters.put("nextLinkUrl", nextLinkUrl);
+        parameters.put("paginateNextLabel", modelForm.getPaginateNextLabel(context));
+        parameters.put("paginatePreviousStyle", modelForm.getPaginatePreviousStyle());
+        parameters.put("paginatePreviousLabel", modelForm.getPaginatePreviousLabel(context));
+        parameters.put("previousLinkUrl", previousLinkUrl);
+        parameters.put("paginateFirstStyle", modelForm.getPaginateFirstStyle());
+        parameters.put("paginateFirstLabel", modelForm.getPaginateFirstLabel(context));
+        parameters.put("firstLinkUrl", firstLinkUrl);
+        executeMacro(writer, "renderScreenletPaginateMenu", parameters);
+    }
+
+    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
+        String portalPageId = portalPage.getActualPortalPageId(context);
+        String originalPortalPageId = portalPage.getOriginalPortalPageId(context);
+        String confMode = portalPage.getConfMode(context);
+
+        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
+        String addColumnLabel = "";
+        String addColumnHint = "";
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        } else {
+            addColumnLabel = uiLabelMap.get("CommonAddColumn");
+            addColumnHint = uiLabelMap.get("CommonAddAColumnToThisPortalPage");
+        }
+
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderPortalPageBegin ");
+        sr.append("originalPortalPageId=\"");
+        sr.append(originalPortalPageId);
+        sr.append("\" portalPageId=\"");
+        sr.append(portalPageId);
+        sr.append("\" confMode=\"");
+        sr.append(confMode);
+        sr.append("\" addColumnLabel=\"");
+        sr.append(addColumnLabel);
+        sr.append("\" addColumnHint=\"");
+        sr.append(addColumnHint);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderPortalPageEnd/>");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
+        String portalPageId = portalPage.getActualPortalPageId(context);
+        String originalPortalPageId = portalPage.getOriginalPortalPageId(context);
+        String columnSeqId = portalPageColumn.getString("columnSeqId");
+        String columnWidthPercentage = portalPageColumn.getString("columnWidthPercentage");
+        String columnWidthPixels = portalPageColumn.getString("columnWidthPixels");
+        String confMode = portalPage.getConfMode(context);
+
+        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
+        String delColumnLabel = "";
+        String delColumnHint = "";
+        String addPortletLabel = "";
+        String addPortletHint = "";
+        String colWidthLabel = "";
+        String setColumnSizeHint = "";
+        
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        } else {
+            delColumnLabel = uiLabelMap.get("CommonDeleteColumn");
+            delColumnHint = uiLabelMap.get("CommonDeleteThisColumn");
+
+            addPortletLabel = uiLabelMap.get("CommonAddAPortlet");
+            addPortletHint = uiLabelMap.get("CommonAddPortletToPage");
+            colWidthLabel = uiLabelMap.get("CommonWidth");
+            setColumnSizeHint = uiLabelMap.get("CommonSetColumnWidth");
+        }
+
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderPortalPageColumnBegin ");
+        sr.append("originalPortalPageId=\"");
+        sr.append(originalPortalPageId);
+        sr.append("\" portalPageId=\"");
+        sr.append(portalPageId);
+        sr.append("\" columnSeqId=\"");
+        sr.append(columnSeqId);
+        sr.append("\" ");
+        if (UtilValidate.isNotEmpty(columnWidthPixels)) {
+            sr.append("width=\"");
+            sr.append(columnWidthPixels);
+            sr.append("px\"");
+        } else if (UtilValidate.isNotEmpty(columnWidthPercentage)) {
+            sr.append("width=\"");
+            sr.append(columnWidthPercentage);
+            sr.append("%\"");
+        }
+        sr.append(" confMode=\"");
+        sr.append(confMode);
+        sr.append("\" delColumnLabel=\"");
+        sr.append(delColumnLabel);
+        sr.append("\" delColumnHint=\"");
+        sr.append(delColumnHint);
+        sr.append("\" addPortletLabel=\"");
+        sr.append(addPortletLabel);
+        sr.append("\" addPortletHint=\"");
+        sr.append(addPortletHint);
+        sr.append("\" colWidthLabel=\"");
+        sr.append(colWidthLabel);
+        sr.append("\" setColumnSizeHint=\"");
+        sr.append(setColumnSizeHint);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }   
+
+    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderPortalPageColumnEnd/>");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        String portalPageId = portalPage.getActualPortalPageId(context);
+        String originalPortalPageId = portalPage.getOriginalPortalPageId(context);
+        String portalPortletId = portalPortlet.getString("portalPortletId");
+        String portletSeqId = portalPortlet.getString("portletSeqId");
+        String columnSeqId = portalPortlet.getString("columnSeqId");
+        String confMode = portalPage.getConfMode(context);
+        String editFormName = portalPortlet.getString("editFormName");
+        String editFormLocation = portalPortlet.getString("editFormLocation");
+
+        String prevPortletId = (String) context.get("prevPortletId");
+        String prevPortletSeqId = (String) context.get("prevPortletSeqId");
+        String nextPortletId = (String) context.get("nextPortletId");
+        String nextPortletSeqId = (String) context.get("nextPortletSeqId");
+        String prevColumnSeqId = (String) context.get("prevColumnSeqId");
+        String nextColumnSeqId = (String) context.get("nextColumnSeqId");
+
+        Map<String, String> uiLabelMap = UtilGenerics.cast(context.get("uiLabelMap"));
+        String delPortletHint = "";
+        String editAttributeHint = "";
+        if (uiLabelMap == null) {
+            Debug.logWarning("Could not find uiLabelMap in context", module);
+        } else {
+            delPortletHint = uiLabelMap.get("CommonDeleteThisPortlet");
+            editAttributeHint = uiLabelMap.get("CommonEditPortletAttributes");
+        }
+
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderPortalPagePortletBegin ");
+        sr.append("originalPortalPageId=\"");
+        sr.append(originalPortalPageId);
+        sr.append("\" portalPageId=\"");
+        sr.append(portalPageId);
+        sr.append("\" portalPortletId=\"");
+        sr.append(portalPortletId);
+        sr.append("\" portletSeqId=\"");
+        sr.append(portletSeqId);
+        sr.append("\" prevPortletId=\"");
+        sr.append(prevPortletId);
+        sr.append("\" prevPortletSeqId=\"");
+        sr.append(prevPortletSeqId);
+        sr.append("\" nextPortletId=\"");
+        sr.append(nextPortletId);
+        sr.append("\" nextPortletSeqId=\"");
+        sr.append(nextPortletSeqId);
+        sr.append("\" columnSeqId=\"");
+        sr.append(columnSeqId);
+        sr.append("\" prevColumnSeqId=\"");
+        sr.append(prevColumnSeqId);
+        sr.append("\" nextColumnSeqId=\"");
+        sr.append(nextColumnSeqId);
+        sr.append("\" delPortletHint=\"");
+        sr.append(delPortletHint);
+        sr.append("\" editAttributeHint=\"");
+        sr.append(editAttributeHint);
+        sr.append("\" confMode=\"");
+        sr.append(confMode);
+        sr.append("\"");
+        if (UtilValidate.isNotEmpty(editFormName) && UtilValidate.isNotEmpty(editFormLocation)) {
+            sr.append(" editAttribute=\"true\"");
+        }
+        sr.append("/>");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        String confMode = portalPage.getConfMode(context);
+
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderPortalPagePortletEnd ");
+        sr.append(" confMode=\"");
+        sr.append(confMode);
+        sr.append("\" />");
+        executeMacro(writer, sr.toString());
+    }
+
+    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        String portalPortletId = portalPortlet.getString("portalPortletId");
+        String screenName = portalPortlet.getString("screenName");
+        String screenLocation = portalPortlet.getString("screenLocation");
+
+        ModelScreen modelScreen = null;
+        if (UtilValidate.isNotEmpty(screenName) && UtilValidate.isNotEmpty(screenLocation)) {
+            try {
+                modelScreen = ScreenFactory.getScreenFromLocation(screenLocation, screenName);
+            } catch (IOException e) {
+                String errMsg = "Error rendering portlet ID [" + portalPortletId + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            } catch (SAXException e) {
+                String errMsg = "Error rendering portlet ID [" + portalPortletId + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            } catch (ParserConfigurationException e) {
+                String errMsg = "Error rendering portlet ID [" + portalPortletId + "]: " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new RuntimeException(errMsg);
+            }
+        }
+        modelScreen.renderScreenString(writer, context, this);
+    }
+
+    @Override
+    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ColumnContainer columnContainer) throws IOException {
+        String id = columnContainer.getId(context);
+        String style = columnContainer.getStyle(context);
+        StringBuilder sb = new StringBuilder("<@renderColumnContainerBegin");
+        sb.append(" id=\"");
+        sb.append(id);
+        sb.append("\" style=\"");
+        sb.append(style);
+        sb.append("\" />");
+        executeMacro(writer, sb.toString());
+        for (Column column : columnContainer.getColumns()) {
+            id = column.getId(context);
+            style = column.getStyle(context);
+            sb = new StringBuilder("<@renderColumnBegin");
+            sb.append(" id=\"");
+            sb.append(id);
+            sb.append("\" style=\"");
+            sb.append(style);
+            sb.append("\" />");
+            executeMacro(writer, sb.toString());
+            for (ModelScreenWidget subWidget : column.getSubWidgets()) {
+                try {
+                    subWidget.renderWidgetString(writer, context, this);
+                } catch (GeneralException e) {
+                    throw new IOException(e);
+                }
+            }
+            executeMacro(writer, "<@renderColumnEnd />");
+        }
+        executeMacro(writer, "<@renderColumnContainerEnd />");
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
similarity index 96%
rename from framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java
rename to framework/widget/src/org/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
index d6f1290..b431fd7 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/MacroScreenViewHandler.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroScreenViewHandler.java
@@ -1,168 +1,167 @@
-/*******************************************************************************
- * 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.ofbiz.widget.screen;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilProperties;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.collections.MapStack;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.util.EntityUtilProperties;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.service.ModelService;
-import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.webapp.view.AbstractViewHandler;
-import org.ofbiz.webapp.view.ViewHandlerException;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.MacroFormRenderer;
-import org.ofbiz.widget.menu.MacroMenuRenderer;
-import org.ofbiz.widget.menu.MenuStringRenderer;
-import org.ofbiz.widget.tree.MacroTreeRenderer;
-import org.ofbiz.widget.tree.TreeStringRenderer;
-import org.xml.sax.SAXException;
-
-import freemarker.template.TemplateException;
-import freemarker.template.utility.StandardCompress;
-
-public class MacroScreenViewHandler extends AbstractViewHandler {
-
-    public static final String module = MacroScreenViewHandler.class.getName();
-
-    protected ServletContext servletContext = null;
-
-    public void init(ServletContext context) throws ViewHandlerException {
-        this.servletContext = context;
-    }
-
-    private ScreenStringRenderer loadRenderers(HttpServletRequest request, HttpServletResponse response,
-            Map<String, Object> context, Writer writer) throws GeneralException, TemplateException, IOException {
-        String screenMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".screenrenderer");
-        String formMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".formrenderer");
-        String treeMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".treerenderer");
-        String menuMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".menurenderer");
-        Map<String, Object> userPreferences = UtilGenerics.cast(context.get("userPreferences"));
-        if (userPreferences != null) {
-            String visualThemeId = (String) userPreferences.get("VISUAL_THEME");
-            if (visualThemeId != null) {
-                LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
-                Map<String, Object> serviceCtx = dispatcher.getDispatchContext().makeValidContext("getVisualThemeResources",
-                        ModelService.IN_PARAM, context);
-                serviceCtx.put("visualThemeId", visualThemeId);
-                Map<String, Object> serviceResult = dispatcher.runSync("getVisualThemeResources", serviceCtx);
-                if (ServiceUtil.isSuccess(serviceResult)) {
-                    Map<String, List<String>> themeResources = UtilGenerics.cast(serviceResult.get("themeResources"));
-                    List<String> resourceList = UtilGenerics.cast(themeResources.get("VT_SCRN_MACRO_LIB"));
-                    if (resourceList != null && !resourceList.isEmpty()) {
-                        String macroLibraryPath = resourceList.get(0);
-                        if (macroLibraryPath != null) {
-                            screenMacroLibraryPath = macroLibraryPath;
-                        }
-                    }
-                    resourceList = UtilGenerics.cast(themeResources.get("VT_FORM_MACRO_LIB"));
-                    if (resourceList != null && !resourceList.isEmpty()) {
-                        String macroLibraryPath = resourceList.get(0);
-                        if (macroLibraryPath != null) {
-                            formMacroLibraryPath = macroLibraryPath;
-                        }
-                    }
-                    resourceList = UtilGenerics.cast(themeResources.get("VT_TREE_MACRO_LIB"));
-                    if (resourceList != null && !resourceList.isEmpty()) {
-                        String macroLibraryPath = resourceList.get(0);
-                        if (macroLibraryPath != null) {
-                            treeMacroLibraryPath = macroLibraryPath;
-                        }
-                    }
-                    resourceList = UtilGenerics.cast(themeResources.get("VT_MENU_MACRO_LIB"));
-                    if (resourceList != null && !resourceList.isEmpty()) {
-                        String macroLibraryPath = resourceList.get(0);
-                        if (macroLibraryPath != null) {
-                            menuMacroLibraryPath = macroLibraryPath;
-                        }
-                    }
-                }
-            }
-        }
-        ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(UtilProperties.getPropertyValue("widget", getName()
-                + ".name"), screenMacroLibraryPath);
-        FormStringRenderer formStringRenderer = new MacroFormRenderer(formMacroLibraryPath, request, response);
-        context.put("formStringRenderer", formStringRenderer);
-        TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(treeMacroLibraryPath, writer);
-        context.put("treeStringRenderer", treeStringRenderer);
-        MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(menuMacroLibraryPath, request, response);
-        context.put("menuStringRenderer", menuStringRenderer);
-        return screenStringRenderer;
-    }
-
-    public void render(String name, String page, String info, String contentType, String encoding, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
-        try {
-            Writer writer = response.getWriter();
-            Delegator delegator = (Delegator) request.getAttribute("delegator");
-            // compress output if configured to do so
-            if (UtilValidate.isEmpty(encoding)) {
-                encoding = EntityUtilProperties.getPropertyValue("widget", getName() + ".default.encoding", "none", delegator);
-            }
-            boolean compressOutput = "compressed".equals(encoding);
-            if (!compressOutput) {
-                compressOutput = "true".equals(EntityUtilProperties.getPropertyValue("widget", getName() + ".compress", delegator));
-            }
-            if (!compressOutput && this.servletContext != null) {
-                compressOutput = "true".equals(this.servletContext.getAttribute("compressHTML"));
-            }
-            if (compressOutput) {
-                // StandardCompress defaults to a 2k buffer. That could be increased
-                // to speed up output.
-                writer = new StandardCompress().getWriter(writer, null);
-            }
-            MapStack<String> context = MapStack.create();
-            ScreenRenderer.populateContextForRequest(context, null, request, response, servletContext);
-            ScreenStringRenderer screenStringRenderer = loadRenderers(request, response, context, writer);
-            ScreenRenderer screens = new ScreenRenderer(writer, context, screenStringRenderer);
-            context.put("screens", screens);
-            context.put("simpleEncoder", UtilCodec.getEncoder(UtilProperties.getPropertyValue("widget", getName() + ".encoder")));
-            screenStringRenderer.renderScreenBegin(writer, context);
-            screens.render(page);
-            screenStringRenderer.renderScreenEnd(writer, context);
-            writer.flush();
-        } catch (TemplateException e) {
-            Debug.logError(e, "Error initializing screen renderer", module);
-            throw new ViewHandlerException(e.getMessage());
-        } catch (IOException e) {
-            throw new ViewHandlerException("Error in the response writer/output stream: " + e.toString(), e);
-        } catch (SAXException e) {
-            throw new ViewHandlerException("XML Error rendering page: " + e.toString(), e);
-        } catch (ParserConfigurationException e) {
-            throw new ViewHandlerException("XML Error rendering page: " + e.toString(), e);
-        } catch (GeneralException e) {
-            throw new ViewHandlerException("Lower level error rendering page: " + e.toString(), e);
-        }
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.macro;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilProperties;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.collections.MapStack;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.util.EntityUtilProperties;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ModelService;
+import org.ofbiz.service.ServiceUtil;
+import org.ofbiz.webapp.view.AbstractViewHandler;
+import org.ofbiz.webapp.view.ViewHandlerException;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+import org.ofbiz.widget.renderer.MenuStringRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.TreeStringRenderer;
+import org.xml.sax.SAXException;
+
+import freemarker.template.TemplateException;
+import freemarker.template.utility.StandardCompress;
+
+public class MacroScreenViewHandler extends AbstractViewHandler {
+
+    public static final String module = MacroScreenViewHandler.class.getName();
+
+    protected ServletContext servletContext = null;
+
+    public void init(ServletContext context) throws ViewHandlerException {
+        this.servletContext = context;
+    }
+
+    private ScreenStringRenderer loadRenderers(HttpServletRequest request, HttpServletResponse response,
+            Map<String, Object> context, Writer writer) throws GeneralException, TemplateException, IOException {
+        String screenMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".screenrenderer");
+        String formMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".formrenderer");
+        String treeMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".treerenderer");
+        String menuMacroLibraryPath = UtilProperties.getPropertyValue("widget", getName() + ".menurenderer");
+        Map<String, Object> userPreferences = UtilGenerics.cast(context.get("userPreferences"));
+        if (userPreferences != null) {
+            String visualThemeId = (String) userPreferences.get("VISUAL_THEME");
+            if (visualThemeId != null) {
+                LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+                Map<String, Object> serviceCtx = dispatcher.getDispatchContext().makeValidContext("getVisualThemeResources",
+                        ModelService.IN_PARAM, context);
+                serviceCtx.put("visualThemeId", visualThemeId);
+                Map<String, Object> serviceResult = dispatcher.runSync("getVisualThemeResources", serviceCtx);
+                if (ServiceUtil.isSuccess(serviceResult)) {
+                    Map<String, List<String>> themeResources = UtilGenerics.cast(serviceResult.get("themeResources"));
+                    List<String> resourceList = UtilGenerics.cast(themeResources.get("VT_SCRN_MACRO_LIB"));
+                    if (resourceList != null && !resourceList.isEmpty()) {
+                        String macroLibraryPath = resourceList.get(0);
+                        if (macroLibraryPath != null) {
+                            screenMacroLibraryPath = macroLibraryPath;
+                        }
+                    }
+                    resourceList = UtilGenerics.cast(themeResources.get("VT_FORM_MACRO_LIB"));
+                    if (resourceList != null && !resourceList.isEmpty()) {
+                        String macroLibraryPath = resourceList.get(0);
+                        if (macroLibraryPath != null) {
+                            formMacroLibraryPath = macroLibraryPath;
+                        }
+                    }
+                    resourceList = UtilGenerics.cast(themeResources.get("VT_TREE_MACRO_LIB"));
+                    if (resourceList != null && !resourceList.isEmpty()) {
+                        String macroLibraryPath = resourceList.get(0);
+                        if (macroLibraryPath != null) {
+                            treeMacroLibraryPath = macroLibraryPath;
+                        }
+                    }
+                    resourceList = UtilGenerics.cast(themeResources.get("VT_MENU_MACRO_LIB"));
+                    if (resourceList != null && !resourceList.isEmpty()) {
+                        String macroLibraryPath = resourceList.get(0);
+                        if (macroLibraryPath != null) {
+                            menuMacroLibraryPath = macroLibraryPath;
+                        }
+                    }
+                }
+            }
+        }
+        ScreenStringRenderer screenStringRenderer = new MacroScreenRenderer(UtilProperties.getPropertyValue("widget", getName()
+                + ".name"), screenMacroLibraryPath);
+        FormStringRenderer formStringRenderer = new MacroFormRenderer(formMacroLibraryPath, request, response);
+        context.put("formStringRenderer", formStringRenderer);
+        TreeStringRenderer treeStringRenderer = new MacroTreeRenderer(treeMacroLibraryPath, writer);
+        context.put("treeStringRenderer", treeStringRenderer);
+        MenuStringRenderer menuStringRenderer = new MacroMenuRenderer(menuMacroLibraryPath, request, response);
+        context.put("menuStringRenderer", menuStringRenderer);
+        return screenStringRenderer;
+    }
+
+    public void render(String name, String page, String info, String contentType, String encoding, HttpServletRequest request, HttpServletResponse response) throws ViewHandlerException {
+        try {
+            Writer writer = response.getWriter();
+            Delegator delegator = (Delegator) request.getAttribute("delegator");
+            // compress output if configured to do so
+            if (UtilValidate.isEmpty(encoding)) {
+                encoding = EntityUtilProperties.getPropertyValue("widget", getName() + ".default.encoding", "none", delegator);
+            }
+            boolean compressOutput = "compressed".equals(encoding);
+            if (!compressOutput) {
+                compressOutput = "true".equals(EntityUtilProperties.getPropertyValue("widget", getName() + ".compress", delegator));
+            }
+            if (!compressOutput && this.servletContext != null) {
+                compressOutput = "true".equals(this.servletContext.getAttribute("compressHTML"));
+            }
+            if (compressOutput) {
+                // StandardCompress defaults to a 2k buffer. That could be increased
+                // to speed up output.
+                writer = new StandardCompress().getWriter(writer, null);
+            }
+            MapStack<String> context = MapStack.create();
+            ScreenRenderer.populateContextForRequest(context, null, request, response, servletContext);
+            ScreenStringRenderer screenStringRenderer = loadRenderers(request, response, context, writer);
+            ScreenRenderer screens = new ScreenRenderer(writer, context, screenStringRenderer);
+            context.put("screens", screens);
+            context.put("simpleEncoder", UtilCodec.getEncoder(UtilProperties.getPropertyValue("widget", getName() + ".encoder")));
+            screenStringRenderer.renderScreenBegin(writer, context);
+            screens.render(page);
+            screenStringRenderer.renderScreenEnd(writer, context);
+            writer.flush();
+        } catch (TemplateException e) {
+            Debug.logError(e, "Error initializing screen renderer", module);
+            throw new ViewHandlerException(e.getMessage());
+        } catch (IOException e) {
+            throw new ViewHandlerException("Error in the response writer/output stream: " + e.toString(), e);
+        } catch (SAXException e) {
+            throw new ViewHandlerException("XML Error rendering page: " + e.toString(), e);
+        } catch (ParserConfigurationException e) {
+            throw new ViewHandlerException("XML Error rendering page: " + e.toString(), e);
+        } catch (GeneralException e) {
+            throw new ViewHandlerException("Lower level error rendering page: " + e.toString(), e);
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroTreeRenderer.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/macro/MacroTreeRenderer.java
index 24d3f5c..07ed850 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/MacroTreeRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroTreeRenderer.java
@@ -1,370 +1,370 @@
-/*******************************************************************************
- * 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.ofbiz.widget.tree;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.StringUtil;
-import org.ofbiz.base.util.UtilGenerics;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.template.FreeMarkerWorker;
-import org.ofbiz.webapp.control.RequestHandler;
-import org.ofbiz.webapp.taglib.ContentUrlTag;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.screen.ScreenRenderer;
-import org.ofbiz.widget.screen.ScreenStringRenderer;
-import org.ofbiz.widget.tree.ModelTree;
-import org.ofbiz.widget.tree.TreeStringRenderer;
-
-import freemarker.core.Environment;
-import freemarker.template.Template;
-import freemarker.template.TemplateException;
-
-/**
- * Widget Library - Tree Renderer implementation based on Freemarker macros
- * 
- */
-public class MacroTreeRenderer implements TreeStringRenderer {
-
-    public static final String module = MacroTreeRenderer.class.getName();
-    private Template macroLibrary;
-    private Environment environment;
-
-
-    public MacroTreeRenderer(String macroLibraryPath, Appendable writer) throws TemplateException, IOException {
-        this.macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
-        Map<String, Object> input = UtilMisc.toMap("key", null);
-        this.environment = FreeMarkerWorker.renderTemplate(this.macroLibrary, input, writer);
-    }
-
-    private void executeMacro(String macro) throws IOException {
-        try {
-            Reader templateReader = new StringReader(macro);
-            // FIXME: I am using a Date as an hack to provide a unique name for the template...
-            Template template = new Template((new java.util.Date()).toString(), templateReader,
-                    FreeMarkerWorker.getDefaultOfbizConfig());
-            templateReader.close();
-            this.environment.include(template);
-        } catch (TemplateException e) {
-            Debug.logError(e, "Error rendering tree thru ftl", module);
-        } catch (IOException e) {
-            Debug.logError(e, "Error rendering tree thru ftl", module);
-        }
-    }
- 
-    /**
-     * Renders the beginning boundary comment string.
-     * @param writer The writer to write to
-     * @param widgetType The widget type: "Screen Widget", "Tree Widget", etc.
-     * @param modelWidget The widget
-     */
-    public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@formatBoundaryComment ");
-        sr.append(" boundaryType=\"");
-        sr.append("Begin");
-        sr.append("\" widgetType=\"");
-        sr.append(widgetType);
-        sr.append("\" widgetName=\"");
-        sr.append(modelWidget.getBoundaryCommentName());
-        sr.append("\" />");
-        executeMacro(sr.toString());
-    }
-    
-    /**
-     * Renders the ending boundary comment string.
-     * @param writer The writer to write to
-     * @param widgetType The widget type: "Screen Widget", "Tree Widget", etc.
-     * @param modelWidget The widget
-     */
-    public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
-        StringWriter sr = new StringWriter();
-        sr.append("<@formatBoundaryComment ");
-        sr.append(" boundaryType=\"");
-        sr.append("End");
-        sr.append("\" widgetType=\"");
-        sr.append(widgetType);
-        sr.append("\" widgetName=\"");
-        sr.append(modelWidget.getBoundaryCommentName());
-        sr.append("\" />");
-        executeMacro(sr.toString());
-    }
-    
-    public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException {
-        String currentNodeTrailPiped = null;
-        List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
-        
-        String style = "";
-        if (node.isRootNode()) {
-            if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
-                renderBeginningBoundaryComment(writer, "Tree Widget", node.getModelTree());
-            }
-            style = "basic-tree";
-        }
- 
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderNodeBegin ");
-        sr.append(" style=\"");
-        sr.append(style);
-        sr.append("\" />");
-        executeMacro(sr.toString());
-
-        String pkName = node.getPkName(context);
-        String entityId = null;
-        String entryName = node.getEntryName();
-        if (UtilValidate.isNotEmpty(entryName)) {
-            Map<String, String> map = UtilGenerics.checkMap(context.get(entryName));
-            entityId = map.get(pkName);
-        } else {
-            entityId = (String) context.get(pkName);
-        }
-        boolean hasChildren = node.hasChildren(context);
-
-        // check to see if this node needs to be expanded.
-        if (hasChildren && node.isExpandCollapse()) {
-            // FIXME: Using a widget model in this way is an ugly hack.
-            ModelTree.ModelNode.Link expandCollapseLink = null;
-            String targetEntityId = null;
-            List<String> targetNodeTrail = UtilGenerics.toList(context.get("targetNodeTrail"));
-            if (depth < targetNodeTrail.size()) {
-                targetEntityId = targetNodeTrail.get(depth);
-            }
-
-            int openDepth = node.getModelTree().getOpenDepth();
-            if (depth >= openDepth && (targetEntityId == null || !targetEntityId.equals(entityId))) {
-                // Not on the trail
-                if (node.showPeers(depth, context)) {
-                    context.put("processChildren", Boolean.FALSE);
-                    //expandCollapseLink.setText("&nbsp;+&nbsp;");
-                    currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
-                    StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
-                    String trailName = node.getModelTree().getTrailName(context);
-                    if (target.indexOf("?") < 0) {
-                        target.append("?");
-                    } else {
-                        target.append("&");
-                    }
-                    target.append(trailName).append("=").append(currentNodeTrailPiped);
-                    expandCollapseLink = new ModelTree.ModelNode.Link("collapsed", target.toString(), " ");
-                }
-            } else {
-                context.put("processChildren", Boolean.TRUE);
-                //expandCollapseLink.setText("&nbsp;-&nbsp;");
-                String lastContentId = currentNodeTrail.remove(currentNodeTrail.size() - 1);
-                currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
-                if (currentNodeTrailPiped == null) {
-                    currentNodeTrailPiped = "";
-                }
-                StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
-                String trailName = node.getModelTree().getTrailName(context);
-                if (target.indexOf("?") < 0) {
-                    target.append("?");
-                } else {
-                    target.append("&");
-                }
-                target.append(trailName).append("=").append(currentNodeTrailPiped);
-                expandCollapseLink = new ModelTree.ModelNode.Link("expanded", target.toString(), " ");
-                // add it so it can be remove in renderNodeEnd
-                currentNodeTrail.add(lastContentId);
-            }
-            if (expandCollapseLink != null) {
-                renderLink(writer, context, expandCollapseLink);
-            }
-        } else if (!hasChildren) {
-            context.put("processChildren", Boolean.FALSE);
-            ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link("leafnode", "", " ");
-            renderLink(writer, context, expandCollapseLink);
-        }
-    }
-
-    public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
-        Boolean processChildren = (Boolean) context.get("processChildren");
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderNodeEnd ");
-        sr.append(" processChildren=");
-        sr.append(Boolean.toString(processChildren.booleanValue()));
-        sr.append(" isRootNode=");
-        sr.append(Boolean.toString(node.isRootNode()));
-        sr.append(" />");
-        executeMacro(sr.toString());
-        if (node.isRootNode()) {
-            if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
-                renderEndingBoundaryComment(writer, "Tree Widget", node.getModelTree());
-            }
-        }
-    }
-
-    public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
-        Boolean processChildren = (Boolean) context.get("processChildren");
-        if (processChildren.booleanValue()) {            
-            StringWriter sr = new StringWriter();
-            sr.append("<@renderLastElement ");
-            sr.append("style=\"");
-            sr.append("basic-tree");
-            sr.append("\" />");
-            executeMacro(sr.toString());
-        }
-    }
-
-    public void renderLabel(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Label label) throws IOException {
-        String id = label.getId(context); 
-        String style = label.getStyle(context);
-        String labelText = label.getText(context);
-
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderLabel ");
-        sr.append("id=\"");
-        sr.append(id);
-        sr.append("\" style=\"");
-        sr.append(style);
-        sr.append("\" labelText=\"");
-        sr.append(labelText);        
-        sr.append("\" />");
-        executeMacro(sr.toString());        
-    }
-
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Link link) throws IOException {
-        String target = link.getTarget(context);
-        StringBuilder linkUrl = new StringBuilder();
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        
-        if (UtilValidate.isNotEmpty(target)) {
-            WidgetWorker.buildHyperlinkUrl(linkUrl, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
-                    link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);            
-        }        
-        
-        String id = link.getId(context);
-        String style = link.getStyle(context);
-        String name = link.getName(context);
-        String title = link.getTitle(context);
-        String targetWindow = link.getTargetWindow(context);
-        String linkText = link.getText(context);
-        
-        String imgStr = "";
-        ModelTree.ModelNode.Image img = link.getImage();
-        if (img != null) {
-            StringWriter sw = new StringWriter();
-            renderImage(sw, context, img);
-            imgStr = sw.toString();
-        }
-        
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderLink ");
-        sr.append("id=\"");
-        sr.append(id);
-        sr.append("\" style=\"");
-        sr.append(style);
-        sr.append("\" name=\"");
-        sr.append(name);
-        sr.append("\" title=\"");
-        sr.append(title);
-        sr.append("\" targetWindow=\"");
-        sr.append(targetWindow);  
-        sr.append("\" linkUrl=\"");
-        sr.append(linkUrl);     
-        sr.append("\" linkText=\"");
-        sr.append(linkText);           
-        sr.append("\" imgStr=\"");
-        sr.append(imgStr.replaceAll("\"", "\\\\\""));
-        sr.append("\" />");
-        executeMacro(sr.toString());
-    }
-  
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Image image) throws IOException {
-        if (image == null) {
-            return ;            
-        }
-        HttpServletResponse response = (HttpServletResponse) context.get("response");
-        HttpServletRequest request = (HttpServletRequest) context.get("request");
-        
-        String urlMode = image.getUrlMode();
-        String src = image.getSrc(context);
-        String id = image.getId(context);
-        String style = image.getStyle(context);
-        String wid = image.getWidth(context);
-        String hgt = image.getHeight(context);
-        String border = image.getBorder(context);
-        String alt = ""; //TODO add alt to tree images image.getAlt(context);
- 
-        boolean fullPath = false;
-        boolean secure = false;
-        boolean encode = false;
-        String urlString = "";
-        
-        if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
-            if (request != null && response != null) {
-                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
-                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
-                urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
-            } else {
-                urlString = src;
-            }
-        } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
-            if (request != null && response != null) {
-                StringBuilder newURL = new StringBuilder();
-                ContentUrlTag.appendContentPrefix(request, newURL);
-                newURL.append(src);
-                urlString = newURL.toString();
-            }
-        } else {
-            urlString = src;
-        }
-        StringWriter sr = new StringWriter();
-        sr.append("<@renderImage ");
-        sr.append("src=\"");
-        sr.append(src);
-        sr.append("\" id=\"");
-        sr.append(id);
-        sr.append("\" style=\"");
-        sr.append(style);
-        sr.append("\" wid=\"");
-        sr.append(wid);
-        sr.append("\" hgt=\"");
-        sr.append(hgt);
-        sr.append("\" border=\"");
-        sr.append(border);
-        sr.append("\" alt=\"");
-        sr.append(alt);
-        sr.append("\" urlString=\"");
-        sr.append(urlString);
-        sr.append("\" />");
-        executeMacro(sr.toString());        
-    }
-
-    public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context) {
-        ScreenRenderer screenRenderer = (ScreenRenderer)context.get("screens");
-        if (screenRenderer != null) {
-            return screenRenderer.getScreenStringRenderer();
-        } 
-        return null;
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.macro;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.template.FreeMarkerWorker;
+import org.ofbiz.webapp.control.RequestHandler;
+import org.ofbiz.webapp.taglib.ContentUrlTag;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.ModelTree;
+import org.ofbiz.widget.model.ModelWidget;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+import org.ofbiz.widget.renderer.TreeStringRenderer;
+
+import freemarker.core.Environment;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+/**
+ * Widget Library - Tree Renderer implementation based on Freemarker macros
+ * 
+ */
+public class MacroTreeRenderer implements TreeStringRenderer {
+
+    public static final String module = MacroTreeRenderer.class.getName();
+    private Template macroLibrary;
+    private Environment environment;
+
+
+    public MacroTreeRenderer(String macroLibraryPath, Appendable writer) throws TemplateException, IOException {
+        this.macroLibrary = FreeMarkerWorker.getTemplate(macroLibraryPath);
+        Map<String, Object> input = UtilMisc.toMap("key", null);
+        this.environment = FreeMarkerWorker.renderTemplate(this.macroLibrary, input, writer);
+    }
+
+    private void executeMacro(String macro) throws IOException {
+        try {
+            Reader templateReader = new StringReader(macro);
+            // FIXME: I am using a Date as an hack to provide a unique name for the template...
+            Template template = new Template((new java.util.Date()).toString(), templateReader,
+                    FreeMarkerWorker.getDefaultOfbizConfig());
+            templateReader.close();
+            this.environment.include(template);
+        } catch (TemplateException e) {
+            Debug.logError(e, "Error rendering tree thru ftl", module);
+        } catch (IOException e) {
+            Debug.logError(e, "Error rendering tree thru ftl", module);
+        }
+    }
+ 
+    /**
+     * Renders the beginning boundary comment string.
+     * @param writer The writer to write to
+     * @param widgetType The widget type: "Screen Widget", "Tree Widget", etc.
+     * @param modelWidget The widget
+     */
+    public void renderBeginningBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@formatBoundaryComment ");
+        sr.append(" boundaryType=\"");
+        sr.append("Begin");
+        sr.append("\" widgetType=\"");
+        sr.append(widgetType);
+        sr.append("\" widgetName=\"");
+        sr.append(modelWidget.getBoundaryCommentName());
+        sr.append("\" />");
+        executeMacro(sr.toString());
+    }
+    
+    /**
+     * Renders the ending boundary comment string.
+     * @param writer The writer to write to
+     * @param widgetType The widget type: "Screen Widget", "Tree Widget", etc.
+     * @param modelWidget The widget
+     */
+    public void renderEndingBoundaryComment(Appendable writer, String widgetType, ModelWidget modelWidget) throws IOException {
+        StringWriter sr = new StringWriter();
+        sr.append("<@formatBoundaryComment ");
+        sr.append(" boundaryType=\"");
+        sr.append("End");
+        sr.append("\" widgetType=\"");
+        sr.append(widgetType);
+        sr.append("\" widgetName=\"");
+        sr.append(modelWidget.getBoundaryCommentName());
+        sr.append("\" />");
+        executeMacro(sr.toString());
+    }
+    
+    public void renderNodeBegin(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node, int depth) throws IOException {
+        String currentNodeTrailPiped = null;
+        List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
+        
+        String style = "";
+        if (node.isRootNode()) {
+            if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
+                renderBeginningBoundaryComment(writer, "Tree Widget", node.getModelTree());
+            }
+            style = "basic-tree";
+        }
+ 
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderNodeBegin ");
+        sr.append(" style=\"");
+        sr.append(style);
+        sr.append("\" />");
+        executeMacro(sr.toString());
+
+        String pkName = node.getPkName(context);
+        String entityId = null;
+        String entryName = node.getEntryName();
+        if (UtilValidate.isNotEmpty(entryName)) {
+            Map<String, String> map = UtilGenerics.checkMap(context.get(entryName));
+            entityId = map.get(pkName);
+        } else {
+            entityId = (String) context.get(pkName);
+        }
+        boolean hasChildren = node.hasChildren(context);
+
+        // check to see if this node needs to be expanded.
+        if (hasChildren && node.isExpandCollapse()) {
+            // FIXME: Using a widget model in this way is an ugly hack.
+            ModelTree.ModelNode.Link expandCollapseLink = null;
+            String targetEntityId = null;
+            List<String> targetNodeTrail = UtilGenerics.toList(context.get("targetNodeTrail"));
+            if (depth < targetNodeTrail.size()) {
+                targetEntityId = targetNodeTrail.get(depth);
+            }
+
+            int openDepth = node.getModelTree().getOpenDepth();
+            if (depth >= openDepth && (targetEntityId == null || !targetEntityId.equals(entityId))) {
+                // Not on the trail
+                if (node.showPeers(depth, context)) {
+                    context.put("processChildren", Boolean.FALSE);
+                    //expandCollapseLink.setText("&nbsp;+&nbsp;");
+                    currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
+                    StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
+                    String trailName = node.getModelTree().getTrailName(context);
+                    if (target.indexOf("?") < 0) {
+                        target.append("?");
+                    } else {
+                        target.append("&");
+                    }
+                    target.append(trailName).append("=").append(currentNodeTrailPiped);
+                    expandCollapseLink = new ModelTree.ModelNode.Link("collapsed", target.toString(), " ");
+                }
+            } else {
+                context.put("processChildren", Boolean.TRUE);
+                //expandCollapseLink.setText("&nbsp;-&nbsp;");
+                String lastContentId = currentNodeTrail.remove(currentNodeTrail.size() - 1);
+                currentNodeTrailPiped = StringUtil.join(currentNodeTrail, "|");
+                if (currentNodeTrailPiped == null) {
+                    currentNodeTrailPiped = "";
+                }
+                StringBuilder target = new StringBuilder(node.getModelTree().getExpandCollapseRequest(context));
+                String trailName = node.getModelTree().getTrailName(context);
+                if (target.indexOf("?") < 0) {
+                    target.append("?");
+                } else {
+                    target.append("&");
+                }
+                target.append(trailName).append("=").append(currentNodeTrailPiped);
+                expandCollapseLink = new ModelTree.ModelNode.Link("expanded", target.toString(), " ");
+                // add it so it can be remove in renderNodeEnd
+                currentNodeTrail.add(lastContentId);
+            }
+            if (expandCollapseLink != null) {
+                renderLink(writer, context, expandCollapseLink);
+            }
+        } else if (!hasChildren) {
+            context.put("processChildren", Boolean.FALSE);
+            ModelTree.ModelNode.Link expandCollapseLink = new ModelTree.ModelNode.Link("leafnode", "", " ");
+            renderLink(writer, context, expandCollapseLink);
+        }
+    }
+
+    public void renderNodeEnd(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
+        Boolean processChildren = (Boolean) context.get("processChildren");
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderNodeEnd ");
+        sr.append(" processChildren=");
+        sr.append(Boolean.toString(processChildren.booleanValue()));
+        sr.append(" isRootNode=");
+        sr.append(Boolean.toString(node.isRootNode()));
+        sr.append(" />");
+        executeMacro(sr.toString());
+        if (node.isRootNode()) {
+            if (ModelWidget.widgetBoundaryCommentsEnabled(context)) {
+                renderEndingBoundaryComment(writer, "Tree Widget", node.getModelTree());
+            }
+        }
+    }
+
+    public void renderLastElement(Appendable writer, Map<String, Object> context, ModelTree.ModelNode node) throws IOException {
+        Boolean processChildren = (Boolean) context.get("processChildren");
+        if (processChildren.booleanValue()) {            
+            StringWriter sr = new StringWriter();
+            sr.append("<@renderLastElement ");
+            sr.append("style=\"");
+            sr.append("basic-tree");
+            sr.append("\" />");
+            executeMacro(sr.toString());
+        }
+    }
+
+    public void renderLabel(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Label label) throws IOException {
+        String id = label.getId(context); 
+        String style = label.getStyle(context);
+        String labelText = label.getText(context);
+
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderLabel ");
+        sr.append("id=\"");
+        sr.append(id);
+        sr.append("\" style=\"");
+        sr.append(style);
+        sr.append("\" labelText=\"");
+        sr.append(labelText);        
+        sr.append("\" />");
+        executeMacro(sr.toString());        
+    }
+
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Link link) throws IOException {
+        String target = link.getTarget(context);
+        StringBuilder linkUrl = new StringBuilder();
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        
+        if (UtilValidate.isNotEmpty(target)) {
+            WidgetWorker.buildHyperlinkUrl(linkUrl, target, link.getUrlMode(), link.getParameterMap(context), link.getPrefix(context),
+                    link.getFullPath(), link.getSecure(), link.getEncode(), request, response, context);            
+        }        
+        
+        String id = link.getId(context);
+        String style = link.getStyle(context);
+        String name = link.getName(context);
+        String title = link.getTitle(context);
+        String targetWindow = link.getTargetWindow(context);
+        String linkText = link.getText(context);
+        
+        String imgStr = "";
+        ModelTree.ModelNode.Image img = link.getImage();
+        if (img != null) {
+            StringWriter sw = new StringWriter();
+            renderImage(sw, context, img);
+            imgStr = sw.toString();
+        }
+        
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderLink ");
+        sr.append("id=\"");
+        sr.append(id);
+        sr.append("\" style=\"");
+        sr.append(style);
+        sr.append("\" name=\"");
+        sr.append(name);
+        sr.append("\" title=\"");
+        sr.append(title);
+        sr.append("\" targetWindow=\"");
+        sr.append(targetWindow);  
+        sr.append("\" linkUrl=\"");
+        sr.append(linkUrl);     
+        sr.append("\" linkText=\"");
+        sr.append(linkText);           
+        sr.append("\" imgStr=\"");
+        sr.append(imgStr.replaceAll("\"", "\\\\\""));
+        sr.append("\" />");
+        executeMacro(sr.toString());
+    }
+  
+    public void renderImage(Appendable writer, Map<String, Object> context, ModelTree.ModelNode.Image image) throws IOException {
+        if (image == null) {
+            return ;            
+        }
+        HttpServletResponse response = (HttpServletResponse) context.get("response");
+        HttpServletRequest request = (HttpServletRequest) context.get("request");
+        
+        String urlMode = image.getUrlMode();
+        String src = image.getSrc(context);
+        String id = image.getId(context);
+        String style = image.getStyle(context);
+        String wid = image.getWidth(context);
+        String hgt = image.getHeight(context);
+        String border = image.getBorder(context);
+        String alt = ""; //TODO add alt to tree images image.getAlt(context);
+ 
+        boolean fullPath = false;
+        boolean secure = false;
+        boolean encode = false;
+        String urlString = "";
+        
+        if (urlMode != null && urlMode.equalsIgnoreCase("intra-app")) {
+            if (request != null && response != null) {
+                ServletContext ctx = (ServletContext) request.getAttribute("servletContext");
+                RequestHandler rh = (RequestHandler) ctx.getAttribute("_REQUEST_HANDLER_");
+                urlString = rh.makeLink(request, response, src, fullPath, secure, encode);
+            } else {
+                urlString = src;
+            }
+        } else  if (urlMode != null && urlMode.equalsIgnoreCase("content")) {
+            if (request != null && response != null) {
+                StringBuilder newURL = new StringBuilder();
+                ContentUrlTag.appendContentPrefix(request, newURL);
+                newURL.append(src);
+                urlString = newURL.toString();
+            }
+        } else {
+            urlString = src;
+        }
+        StringWriter sr = new StringWriter();
+        sr.append("<@renderImage ");
+        sr.append("src=\"");
+        sr.append(src);
+        sr.append("\" id=\"");
+        sr.append(id);
+        sr.append("\" style=\"");
+        sr.append(style);
+        sr.append("\" wid=\"");
+        sr.append(wid);
+        sr.append("\" hgt=\"");
+        sr.append(hgt);
+        sr.append("\" border=\"");
+        sr.append(border);
+        sr.append("\" alt=\"");
+        sr.append(alt);
+        sr.append("\" urlString=\"");
+        sr.append(urlString);
+        sr.append("\" />");
+        executeMacro(sr.toString());        
+    }
+
+    public ScreenStringRenderer getScreenStringRenderer(Map<String, Object> context) {
+        ScreenRenderer screenRenderer = (ScreenRenderer)context.get("screens");
+        if (screenRenderer != null) {
+            return screenRenderer.getScreenStringRenderer();
+        } 
+        return null;
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/text/TextFormRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
similarity index 90%
rename from framework/widget/src/org/ofbiz/widget/text/TextFormRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
index 2189128..dbbbec9 100644
--- a/framework/widget/src/org/ofbiz/widget/text/TextFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/text/TextFormRenderer.java
@@ -1,302 +1,302 @@
-/*******************************************************************************
- * 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.ofbiz.widget.text;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.ModelFormField;
-import org.ofbiz.widget.form.ModelFormField.CheckField;
-import org.ofbiz.widget.form.ModelFormField.ContainerField;
-import org.ofbiz.widget.form.ModelFormField.DateFindField;
-import org.ofbiz.widget.form.ModelFormField.DateTimeField;
-import org.ofbiz.widget.form.ModelFormField.DisplayField;
-import org.ofbiz.widget.form.ModelFormField.DropDownField;
-import org.ofbiz.widget.form.ModelFormField.FieldInfoWithOptions;
-import org.ofbiz.widget.form.ModelFormField.FileField;
-import org.ofbiz.widget.form.ModelFormField.HiddenField;
-import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
-import org.ofbiz.widget.form.ModelFormField.IgnoredField;
-import org.ofbiz.widget.form.ModelFormField.ImageField;
-import org.ofbiz.widget.form.ModelFormField.LookupField;
-import org.ofbiz.widget.form.ModelFormField.PasswordField;
-import org.ofbiz.widget.form.ModelFormField.RadioField;
-import org.ofbiz.widget.form.ModelFormField.RangeFindField;
-import org.ofbiz.widget.form.ModelFormField.ResetField;
-import org.ofbiz.widget.form.ModelFormField.SubmitField;
-import org.ofbiz.widget.form.ModelFormField.TextField;
-import org.ofbiz.widget.form.ModelFormField.TextFindField;
-import org.ofbiz.widget.form.ModelFormField.TextareaField;
-
-
-/**
- * Widget Library - Csv Form Renderer implementation
- *
- */
-public class TextFormRenderer implements FormStringRenderer {
-
-    public static final String module = TextFormRenderer.class.getName();
-
-    HttpServletRequest request;
-    HttpServletResponse response;
-
-    protected TextFormRenderer() {}
-
-    public TextFormRenderer(HttpServletRequest request, HttpServletResponse response) {
-        this.request = request;
-        this.response = response;
-    }
-
-    public void appendWhitespace(Appendable writer) throws IOException {
-        // appending line ends for now, but this could be replaced with a simple space or something
-        writer.append("\r\n");
-        //writer.append(' ');
-    }
-
-    private void makeTextString(Appendable writer, String widgetStyle, String text) throws IOException {
-        // TODO: escape characters here
-        writer.append(text);
-    }
-
-    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
-        ModelFormField modelFormField = displayField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), displayField.getDescription(context));
-    }
-
-    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
-        ModelFormField modelFormField = hyperlinkField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), hyperlinkField.getDescription(context));
-    }
-
-    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
-    }
-
-    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
-        ModelFormField modelFormField = textareaField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textareaField.getDefaultValue(context)));
-    }
-
-    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
-        ModelFormField modelFormField = dateTimeField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateTimeField.getDefaultValue(context)));
-    }
-
-    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
-        ModelFormField modelFormField = dropDownField.getModelFormField();
-        String currentValue = modelFormField.getEntry(context);
-        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-        // if the current value should go first, display it
-        if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
-            String explicitDescription = dropDownField.getCurrentDescription(context);
-            if (UtilValidate.isNotEmpty(explicitDescription)) {
-                this.makeTextString(writer, modelFormField.getWidgetStyle(), explicitDescription);
-            } else {
-                this.makeTextString(writer, modelFormField.getWidgetStyle(), FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues));
-            }
-        } else {
-            for (ModelFormField.OptionValue optionValue: allOptionValues) {
-                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
-                if ((UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) ||
-                        (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey()))) {
-                    this.makeTextString(writer, modelFormField.getWidgetStyle(), optionValue.getDescription());
-                    break;
-                }
-            }
-        }
-    }
-
-    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) {
-    }
-
-    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) {
-    }
-
-    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) {
-    }
-
-    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) {
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) {
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) {
-    }
-
-    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) {
-    }
-
-    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getTitle(context));
-    }
-
-    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        renderFieldTitle(writer, context, modelFormField);
-    }
-
-    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) {
-    }
-
-    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) {
-    }
-
-    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) {
-    }
-
-    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) {
-    }
-
-    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) {
-    }
-
-    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) {
-    }
-
-    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) {
-    }
-
-    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) {
-    }
-
-    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) {
-    }
-
-    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) {
-    }
-
-    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-        // TODO
-    }
-
-    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
-        ModelFormField modelFormField = textFindField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textFindField.getDefaultValue(context)));
-    }
-
-    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
-        ModelFormField modelFormField = rangeFindField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, rangeFindField.getDefaultValue(context)));
-    }
-
-    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
-        ModelFormField modelFormField = dateFindField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateFindField.getDefaultValue(context)));
-    }
-
-    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
-        ModelFormField modelFormField = lookupField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, lookupField.getDefaultValue(context)));
-    }
-
-    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
-    }
-
-    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
-    }
-
-    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) {
-    }
-
-    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) {
-        // TODO
-    }
-
-    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) {
-        // TODO
-    }
-
-    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) {
-        // TODO
-    }
-
-    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) {
-        // TODO
-    }
-
-    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) {
-    }
-
-    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.text;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelFormField;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+
+
+/**
+ * Widget Library - Csv Form Renderer implementation
+ *
+ */
+public class TextFormRenderer implements FormStringRenderer {
+
+    public static final String module = TextFormRenderer.class.getName();
+
+    HttpServletRequest request;
+    HttpServletResponse response;
+
+    protected TextFormRenderer() {}
+
+    public TextFormRenderer(HttpServletRequest request, HttpServletResponse response) {
+        this.request = request;
+        this.response = response;
+    }
+
+    public void appendWhitespace(Appendable writer) throws IOException {
+        // appending line ends for now, but this could be replaced with a simple space or something
+        writer.append("\r\n");
+        //writer.append(' ');
+    }
+
+    private void makeTextString(Appendable writer, String widgetStyle, String text) throws IOException {
+        // TODO: escape characters here
+        writer.append(text);
+    }
+
+    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
+        ModelFormField modelFormField = displayField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), displayField.getDescription(context));
+    }
+
+    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
+        ModelFormField modelFormField = hyperlinkField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), hyperlinkField.getDescription(context));
+    }
+
+    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
+    }
+
+    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
+        ModelFormField modelFormField = textareaField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textareaField.getDefaultValue(context)));
+    }
+
+    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
+        ModelFormField modelFormField = dateTimeField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateTimeField.getDefaultValue(context)));
+    }
+
+    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
+        ModelFormField modelFormField = dropDownField.getModelFormField();
+        String currentValue = modelFormField.getEntry(context);
+        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+        // if the current value should go first, display it
+        if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
+            String explicitDescription = dropDownField.getCurrentDescription(context);
+            if (UtilValidate.isNotEmpty(explicitDescription)) {
+                this.makeTextString(writer, modelFormField.getWidgetStyle(), explicitDescription);
+            } else {
+                this.makeTextString(writer, modelFormField.getWidgetStyle(), FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues));
+            }
+        } else {
+            for (ModelFormField.OptionValue optionValue: allOptionValues) {
+                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
+                if ((UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) ||
+                        (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey()))) {
+                    this.makeTextString(writer, modelFormField.getWidgetStyle(), optionValue.getDescription());
+                    break;
+                }
+            }
+        }
+    }
+
+    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) {
+    }
+
+    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) {
+    }
+
+    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) {
+    }
+
+    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) {
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) {
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) {
+    }
+
+    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) {
+    }
+
+    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getTitle(context));
+    }
+
+    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        renderFieldTitle(writer, context, modelFormField);
+    }
+
+    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) {
+    }
+
+    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) {
+    }
+
+    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) {
+    }
+
+    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) {
+    }
+
+    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) {
+    }
+
+    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) {
+    }
+
+    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) {
+    }
+
+    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) {
+    }
+
+    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) {
+    }
+
+    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) {
+    }
+
+    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+        // TODO
+    }
+
+    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
+        ModelFormField modelFormField = textFindField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textFindField.getDefaultValue(context)));
+    }
+
+    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
+        ModelFormField modelFormField = rangeFindField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, rangeFindField.getDefaultValue(context)));
+    }
+
+    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
+        ModelFormField modelFormField = dateFindField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateFindField.getDefaultValue(context)));
+    }
+
+    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
+        ModelFormField modelFormField = lookupField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, lookupField.getDefaultValue(context)));
+    }
+
+    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) {
+    }
+
+    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
+    }
+
+    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) {
+    }
+
+    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) {
+        // TODO
+    }
+
+    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) {
+        // TODO
+    }
+
+    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) {
+        // TODO
+    }
+
+    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) {
+        // TODO
+    }
+
+    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) {
+    }
+
+    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/text/TextScreenRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/text/TextScreenRenderer.java
similarity index 96%
rename from framework/widget/src/org/ofbiz/widget/text/TextScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/text/TextScreenRenderer.java
index 74c3a2f..9843f1c 100644
--- a/framework/widget/src/org/ofbiz/widget/text/TextScreenRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/text/TextScreenRenderer.java
@@ -1,153 +1,153 @@
-/*******************************************************************************
- * 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.ofbiz.widget.text;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.ofbiz.base.util.GeneralException;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.widget.screen.ModelScreenWidget;
-import org.ofbiz.widget.screen.ScreenStringRenderer;
-import org.ofbiz.widget.screen.ModelScreenWidget.ColumnContainer;
-import org.ofbiz.entity.GenericValue;
-
-/**
- * Widget Library - Text Screen Renderer implementation
- * @deprecated Use MacroScreenRenderer.
- */
-public class TextScreenRenderer implements ScreenStringRenderer {
-
-    public static final String module = TextScreenRenderer.class.getName();
-
-    public TextScreenRenderer() {}
-
-    public String getRendererName() {
-        return "text";
-    }
-
-    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException {
-    }
-
-    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException {
-    }
-
-    public void renderSectionBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
-        // do nothing, this is just a place holder container for HTML
-    }
-    public void renderSectionEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
-        // do nothing, this is just a place holder container for HTML
-    }
-
-    public void renderContainerBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
-    }
-    public void renderContainerEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
-        appendWhitespace(writer);
-    }
-
-    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException {
-        String labelText = label.getText(context);
-        if (UtilValidate.isEmpty(labelText)) {
-            // nothing to render
-            return;
-        }
-        writer.append(labelText);
-        appendWhitespace(writer);
-    }
-
-    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.HorizontalSeparator separator) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderLink(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenLink link) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenImage image) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderContentFrame(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderSubContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void appendWhitespace(Appendable writer) throws IOException {
-        // appending line ends for now, but this could be replaced with a simple space or something
-        writer.append("\r\n");
-    }
-    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, ModelScreenWidget.Screenlet screenlet) throws IOException {
-        // TODO: not implemented
-    }
-    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, ModelScreenWidget.Screenlet screenlet) throws GeneralException {
-        // TODO: not implemented
-    }
-    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Screenlet screenlet) throws IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
-        // TODO: not implemented
-    }
-
-    @Override
-    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ColumnContainer columnContainer) throws IOException {
-        // TODO: not implemented
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.text;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.widget.model.ModelScreenWidget;
+import org.ofbiz.widget.model.ModelScreenWidget.ColumnContainer;
+import org.ofbiz.widget.renderer.ScreenStringRenderer;
+
+/**
+ * Widget Library - Text Screen Renderer implementation
+ * @deprecated Use MacroScreenRenderer.
+ */
+public class TextScreenRenderer implements ScreenStringRenderer {
+
+    public static final String module = TextScreenRenderer.class.getName();
+
+    public TextScreenRenderer() {}
+
+    public String getRendererName() {
+        return "text";
+    }
+
+    public void renderScreenBegin(Appendable writer, Map<String, Object> context) throws IOException {
+    }
+
+    public void renderScreenEnd(Appendable writer, Map<String, Object> context) throws IOException {
+    }
+
+    public void renderSectionBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
+        // do nothing, this is just a place holder container for HTML
+    }
+    public void renderSectionEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Section section) throws IOException {
+        // do nothing, this is just a place holder container for HTML
+    }
+
+    public void renderContainerBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
+    }
+    public void renderContainerEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Container container) throws IOException {
+        appendWhitespace(writer);
+    }
+
+    public void renderLabel(Appendable writer, Map<String, Object> context, ModelScreenWidget.Label label) throws IOException {
+        String labelText = label.getText(context);
+        if (UtilValidate.isEmpty(labelText)) {
+            // nothing to render
+            return;
+        }
+        writer.append(labelText);
+        appendWhitespace(writer);
+    }
+
+    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.HorizontalSeparator separator) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderLink(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenLink link) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.ScreenImage image) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderContentFrame(Appendable writer, Map<String, Object> context, ModelScreenWidget.Content content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderSubContentBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderSubContentBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void renderSubContentEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.SubContent content) throws IOException {
+        // TODO: not implemented
+    }
+
+    public void appendWhitespace(Appendable writer) throws IOException {
+        // appending line ends for now, but this could be replaced with a simple space or something
+        writer.append("\r\n");
+    }
+    public void renderScreenletBegin(Appendable writer, Map<String, Object> context, boolean collapsed, ModelScreenWidget.Screenlet screenlet) throws IOException {
+        // TODO: not implemented
+    }
+    public void renderScreenletSubWidget(Appendable writer, Map<String, Object> context, ModelScreenWidget subWidget, ModelScreenWidget.Screenlet screenlet) throws GeneralException {
+        // TODO: not implemented
+    }
+    public void renderScreenletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.Screenlet screenlet) throws IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageColumnBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPageColumnEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPageColumn) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletBegin(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletEnd(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+    public void renderPortalPagePortletBody(Appendable writer, Map<String, Object> context, ModelScreenWidget.PortalPage portalPage, GenericValue portalPortlet) throws GeneralException, IOException {
+        // TODO: not implemented
+    }
+
+    @Override
+    public void renderColumnContainer(Appendable writer, Map<String, Object> context, ColumnContainer columnContainer) throws IOException {
+        // TODO: not implemented
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/xml/XmlFormRenderer.java b/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
similarity index 91%
rename from framework/widget/src/org/ofbiz/widget/xml/XmlFormRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
index 3f037b5..a1c49ef 100644
--- a/framework/widget/src/org/ofbiz/widget/xml/XmlFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/xml/XmlFormRenderer.java
@@ -1,343 +1,343 @@
-/*******************************************************************************
- * 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.ofbiz.widget.xml;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.form.FormStringRenderer;
-import org.ofbiz.widget.form.ModelForm;
-import org.ofbiz.widget.form.ModelFormField;
-import org.ofbiz.widget.form.ModelFormField.CheckField;
-import org.ofbiz.widget.form.ModelFormField.ContainerField;
-import org.ofbiz.widget.form.ModelFormField.DateFindField;
-import org.ofbiz.widget.form.ModelFormField.DateTimeField;
-import org.ofbiz.widget.form.ModelFormField.DisplayField;
-import org.ofbiz.widget.form.ModelFormField.DropDownField;
-import org.ofbiz.widget.form.ModelFormField.FieldInfoWithOptions;
-import org.ofbiz.widget.form.ModelFormField.FileField;
-import org.ofbiz.widget.form.ModelFormField.HiddenField;
-import org.ofbiz.widget.form.ModelFormField.HyperlinkField;
-import org.ofbiz.widget.form.ModelFormField.IgnoredField;
-import org.ofbiz.widget.form.ModelFormField.ImageField;
-import org.ofbiz.widget.form.ModelFormField.LookupField;
-import org.ofbiz.widget.form.ModelFormField.PasswordField;
-import org.ofbiz.widget.form.ModelFormField.RadioField;
-import org.ofbiz.widget.form.ModelFormField.RangeFindField;
-import org.ofbiz.widget.form.ModelFormField.ResetField;
-import org.ofbiz.widget.form.ModelFormField.SubmitField;
-import org.ofbiz.widget.form.ModelFormField.TextField;
-import org.ofbiz.widget.form.ModelFormField.TextFindField;
-import org.ofbiz.widget.form.ModelFormField.TextareaField;
-
-
-/**
- * Widget Library - Xml Form Renderer implementation
- *
- */
-public class XmlFormRenderer implements FormStringRenderer {
-
-    public static final String module = XmlFormRenderer.class.getName();
-
-    HttpServletRequest request;
-    HttpServletResponse response;
-
-    protected XmlFormRenderer() throws IOException {}
-
-    public XmlFormRenderer(HttpServletRequest request, HttpServletResponse response) throws IOException {
-        this.request = request;
-        this.response = response;
-    }
-
-    public void appendWhitespace(Appendable writer) throws IOException {
-        // appending line ends for now, but this could be replaced with a simple space or something
-        writer.append("\r\n");
-        //writer.append(' ');
-    }
-
-    private void makeTextString(Appendable writer, String widgetStyle, String text) throws IOException {
-        // TODO: escape characters here
-        writer.append(text);
-    }
-
-    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
-        ModelFormField modelFormField = displayField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), displayField.getDescription(context));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
-        ModelFormField modelFormField = hyperlinkField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), hyperlinkField.getDescription(context));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
-        ModelFormField modelFormField = textareaField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textareaField.getDefaultValue(context)));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
-        ModelFormField modelFormField = dateTimeField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateTimeField.getDefaultValue(context)));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
-        ModelFormField modelFormField = dropDownField.getModelFormField();
-        String currentValue = modelFormField.getEntry(context);
-        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
-        // if the current value should go first, display it
-        if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
-            String explicitDescription = dropDownField.getCurrentDescription(context);
-            if (UtilValidate.isNotEmpty(explicitDescription)) {
-                this.makeTextString(writer, modelFormField.getWidgetStyle(), explicitDescription);
-            } else {
-                this.makeTextString(writer, modelFormField.getWidgetStyle(), FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues));
-            }
-        } else {
-            for (ModelFormField.OptionValue optionValue : allOptionValues) {
-                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
-                if ((UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) ||
-                        (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey()))) {
-                    this.makeTextString(writer, modelFormField.getWidgetStyle(), optionValue.getDescription());
-                    break;
-                }
-            }
-        }
-        this.appendWhitespace(writer);
-    }
-
-    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
-    }
-
-    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
-    }
-
-    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
-    }
-
-    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
-    }
-
-    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
-    }
-
-    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) throws IOException {
-    }
-
-    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-    }
-
-    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-        renderFieldTitle(writer, context, modelFormField);
-    }
-
-    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<");
-        writer.append(modelForm.getName());
-        writer.append("Export>");
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</");
-        writer.append(modelForm.getName());
-        writer.append("Export>");
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
-    }
-
-    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
-    }
-
-    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {
-    }
-
-    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<");
-        writer.append(modelForm.getName());
-        writer.append(">");
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</");
-        writer.append(modelForm.getName());
-        writer.append(">");
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
-        writer.append("<");
-        writer.append(modelFormField.getName());
-        writer.append(">");
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
-        writer.append("</");
-        writer.append(modelFormField.getName());
-        writer.append(">");
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("<");
-        writer.append(modelForm.getName());
-        writer.append("Export>");
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        writer.append("</");
-        writer.append(modelForm.getName());
-        writer.append("Export>");
-        this.appendWhitespace(writer);
-    }
-
-    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-
-    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-    }
-
-    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-    }
-
-    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
-    }
-
-    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
-    }
-
-    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
-    }
-
-    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-        // TODO
-    }
-
-    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
-        ModelFormField modelFormField = textFindField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textFindField.getDefaultValue(context)));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
-        ModelFormField modelFormField = rangeFindField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, rangeFindField.getDefaultValue(context)));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
-        ModelFormField modelFormField = dateFindField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateFindField.getDefaultValue(context)));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
-        ModelFormField modelFormField = lookupField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, lookupField.getDefaultValue(context)));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
-    }
-
-    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
-        ModelFormField modelFormField = textField.getModelFormField();
-        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
-        this.appendWhitespace(writer);
-    }
-
-    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
-    }
-
-    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
-        // TODO
-    }
-
-    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
-        // TODO
-    }
-
-    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
-        // TODO
-    }
-
-    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
-        // TODO
-    }
-
-    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
-    }
-
-    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
-    }
-}
+/*******************************************************************************
+ * 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.ofbiz.widget.renderer.xml;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.widget.WidgetWorker;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelFormField;
+import org.ofbiz.widget.model.ModelFormField.CheckField;
+import org.ofbiz.widget.model.ModelFormField.ContainerField;
+import org.ofbiz.widget.model.ModelFormField.DateFindField;
+import org.ofbiz.widget.model.ModelFormField.DateTimeField;
+import org.ofbiz.widget.model.ModelFormField.DisplayField;
+import org.ofbiz.widget.model.ModelFormField.DropDownField;
+import org.ofbiz.widget.model.ModelFormField.FieldInfoWithOptions;
+import org.ofbiz.widget.model.ModelFormField.FileField;
+import org.ofbiz.widget.model.ModelFormField.HiddenField;
+import org.ofbiz.widget.model.ModelFormField.HyperlinkField;
+import org.ofbiz.widget.model.ModelFormField.IgnoredField;
+import org.ofbiz.widget.model.ModelFormField.ImageField;
+import org.ofbiz.widget.model.ModelFormField.LookupField;
+import org.ofbiz.widget.model.ModelFormField.PasswordField;
+import org.ofbiz.widget.model.ModelFormField.RadioField;
+import org.ofbiz.widget.model.ModelFormField.RangeFindField;
+import org.ofbiz.widget.model.ModelFormField.ResetField;
+import org.ofbiz.widget.model.ModelFormField.SubmitField;
+import org.ofbiz.widget.model.ModelFormField.TextField;
+import org.ofbiz.widget.model.ModelFormField.TextFindField;
+import org.ofbiz.widget.model.ModelFormField.TextareaField;
+import org.ofbiz.widget.renderer.FormStringRenderer;
+
+
+/**
+ * Widget Library - Xml Form Renderer implementation
+ *
+ */
+public class XmlFormRenderer implements FormStringRenderer {
+
+    public static final String module = XmlFormRenderer.class.getName();
+
+    HttpServletRequest request;
+    HttpServletResponse response;
+
+    protected XmlFormRenderer() throws IOException {}
+
+    public XmlFormRenderer(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        this.request = request;
+        this.response = response;
+    }
+
+    public void appendWhitespace(Appendable writer) throws IOException {
+        // appending line ends for now, but this could be replaced with a simple space or something
+        writer.append("\r\n");
+        //writer.append(' ');
+    }
+
+    private void makeTextString(Appendable writer, String widgetStyle, String text) throws IOException {
+        // TODO: escape characters here
+        writer.append(text);
+    }
+
+    public void renderDisplayField(Appendable writer, Map<String, Object> context, DisplayField displayField) throws IOException {
+        ModelFormField modelFormField = displayField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), displayField.getDescription(context));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderHyperlinkField(Appendable writer, Map<String, Object> context, HyperlinkField hyperlinkField) throws IOException {
+        ModelFormField modelFormField = hyperlinkField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), hyperlinkField.getDescription(context));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderTextField(Appendable writer, Map<String, Object> context, TextField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderTextareaField(Appendable writer, Map<String, Object> context, TextareaField textareaField) throws IOException {
+        ModelFormField modelFormField = textareaField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textareaField.getDefaultValue(context)));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderDateTimeField(Appendable writer, Map<String, Object> context, DateTimeField dateTimeField) throws IOException {
+        ModelFormField modelFormField = dateTimeField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateTimeField.getDefaultValue(context)));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderDropDownField(Appendable writer, Map<String, Object> context, DropDownField dropDownField) throws IOException {
+        ModelFormField modelFormField = dropDownField.getModelFormField();
+        String currentValue = modelFormField.getEntry(context);
+        List<ModelFormField.OptionValue> allOptionValues = dropDownField.getAllOptionValues(context, WidgetWorker.getDelegator(context));
+        // if the current value should go first, display it
+        if (UtilValidate.isNotEmpty(currentValue) && "first-in-list".equals(dropDownField.getCurrent())) {
+            String explicitDescription = dropDownField.getCurrentDescription(context);
+            if (UtilValidate.isNotEmpty(explicitDescription)) {
+                this.makeTextString(writer, modelFormField.getWidgetStyle(), explicitDescription);
+            } else {
+                this.makeTextString(writer, modelFormField.getWidgetStyle(), FieldInfoWithOptions.getDescriptionForOptionKey(currentValue, allOptionValues));
+            }
+        } else {
+            for (ModelFormField.OptionValue optionValue : allOptionValues) {
+                String noCurrentSelectedKey = dropDownField.getNoCurrentSelectedKey(context);
+                if ((UtilValidate.isNotEmpty(currentValue) && currentValue.equals(optionValue.getKey()) && "selected".equals(dropDownField.getCurrent())) ||
+                        (UtilValidate.isEmpty(currentValue) && noCurrentSelectedKey != null && noCurrentSelectedKey.equals(optionValue.getKey()))) {
+                    this.makeTextString(writer, modelFormField.getWidgetStyle(), optionValue.getDescription());
+                    break;
+                }
+            }
+        }
+        this.appendWhitespace(writer);
+    }
+
+    public void renderCheckField(Appendable writer, Map<String, Object> context, CheckField checkField) throws IOException {
+    }
+
+    public void renderRadioField(Appendable writer, Map<String, Object> context, RadioField radioField) throws IOException {
+    }
+
+    public void renderSubmitField(Appendable writer, Map<String, Object> context, SubmitField submitField) throws IOException {
+    }
+
+    public void renderResetField(Appendable writer, Map<String, Object> context, ResetField resetField) throws IOException {
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, HiddenField hiddenField) throws IOException {
+    }
+
+    public void renderHiddenField(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String value) throws IOException {
+    }
+
+    public void renderIgnoredField(Appendable writer, Map<String, Object> context, IgnoredField ignoredField) throws IOException {
+    }
+
+    public void renderFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+    }
+
+    public void renderSingleFormFieldTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+        renderFieldTitle(writer, context, modelFormField);
+    }
+
+    public void renderFormOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderMultiFormClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormatListWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<");
+        writer.append(modelForm.getName());
+        writer.append("Export>");
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatListWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</");
+        writer.append(modelForm.getName());
+        writer.append("Export>");
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatHeaderRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormatHeaderRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormatHeaderRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
+    }
+
+    public void renderFormatHeaderRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
+    }
+
+    public void renderFormatHeaderRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormatHeaderRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormatHeaderRowFormCellTitleSeparator(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, boolean isLast) throws IOException {
+    }
+
+    public void renderFormatItemRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<");
+        writer.append(modelForm.getName());
+        writer.append(">");
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</");
+        writer.append(modelForm.getName());
+        writer.append(">");
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField, int positionSpan) throws IOException {
+        writer.append("<");
+        writer.append(modelFormField.getName());
+        writer.append(">");
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm, ModelFormField modelFormField) throws IOException {
+        writer.append("</");
+        writer.append(modelFormField.getName());
+        writer.append(">");
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatItemRowFormCellOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormatItemRowFormCellClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormatSingleWrapperOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("<");
+        writer.append(modelForm.getName());
+        writer.append("Export>");
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatSingleWrapperClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        writer.append("</");
+        writer.append(modelForm.getName());
+        writer.append("Export>");
+        this.appendWhitespace(writer);
+    }
+
+    public void renderFormatFieldRowOpen(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFormatFieldRowClose(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+
+    public void renderFormatFieldRowTitleCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+    }
+
+    public void renderFormatFieldRowTitleCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+    }
+
+    public void renderFormatFieldRowSpacerCell(Appendable writer, Map<String, Object> context, ModelFormField modelFormField) throws IOException {
+    }
+
+    public void renderFormatFieldRowWidgetCellOpen(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
+    }
+
+    public void renderFormatFieldRowWidgetCellClose(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, int positions, int positionSpan, Integer nextPositionInRow) throws IOException {
+    }
+
+    public void renderFormatEmptySpace(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+        // TODO
+    }
+
+    public void renderTextFindField(Appendable writer, Map<String, Object> context, TextFindField textFindField) throws IOException {
+        ModelFormField modelFormField = textFindField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textFindField.getDefaultValue(context)));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderRangeFindField(Appendable writer, Map<String, Object> context, RangeFindField rangeFindField) throws IOException {
+        ModelFormField modelFormField = rangeFindField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, rangeFindField.getDefaultValue(context)));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderDateFindField(Appendable writer, Map<String, Object> context, DateFindField dateFindField) throws IOException {
+        ModelFormField modelFormField = dateFindField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, dateFindField.getDefaultValue(context)));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderLookupField(Appendable writer, Map<String, Object> context, LookupField lookupField) throws IOException {
+        ModelFormField modelFormField = lookupField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, lookupField.getDefaultValue(context)));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderNextPrev(Appendable writer, Map<String, Object> context, ModelForm modelForm) throws IOException {
+    }
+
+    public void renderFileField(Appendable writer, Map<String, Object> context, FileField textField) throws IOException {
+        ModelFormField modelFormField = textField.getModelFormField();
+        this.makeTextString(writer, modelFormField.getWidgetStyle(), modelFormField.getEntry(context, textField.getDefaultValue(context)));
+        this.appendWhitespace(writer);
+    }
+
+    public void renderPasswordField(Appendable writer, Map<String, Object> context, PasswordField passwordField) throws IOException {
+    }
+
+    public void renderImageField(Appendable writer, Map<String, Object> context, ImageField imageField) throws IOException {
+        // TODO
+    }
+
+    public void renderFieldGroupOpen(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
+        // TODO
+    }
+
+    public void renderFieldGroupClose(Appendable writer, Map<String, Object> context, ModelForm.FieldGroup fieldGroup) throws IOException {
+        // TODO
+    }
+
+    public void renderBanner(Appendable writer, Map<String, Object> context, ModelForm.Banner banner) throws IOException {
+        // TODO
+    }
+
+    public void renderHyperlinkTitle(Appendable writer, Map<String, Object> context, ModelFormField modelFormField, String titleText) throws IOException {
+    }
+
+    public void renderContainerFindField(Appendable writer, Map<String, Object> context, ContainerField containerField) throws IOException {
+    }
+}
diff --git a/framework/widget/templates/htmlFormMacroLibrary.ftl b/framework/widget/templates/htmlFormMacroLibrary.ftl
index 1b14fc7..a91dc8c 100644
--- a/framework/widget/templates/htmlFormMacroLibrary.ftl
+++ b/framework/widget/templates/htmlFormMacroLibrary.ftl
@@ -617,7 +617,7 @@
 Parameter: lastViewName, String, optional - If the ajaxEnabled parameter is true, the contents of lastViewName will be appended to the Ajax URL.
 -->
 <#macro renderLookupField name formName fieldFormName className="" alert="false" value="" size="" maxlength="" id="" event="" action="" readonly=false autocomplete="" descriptionFieldName="" targetParameterIter="" imgSrc="" ajaxUrl="" ajaxEnabled=javaScriptEnabled presentation="layer" width="" height="" position="" fadeBackground="true" clearText="" showDescription="" initiallyCollapsed="" lastViewName="main" >
-  <#if Static["org.ofbiz.widget.ModelWidget"].widgetBoundaryCommentsEnabled(context)>
+  <#if Static["org.ofbiz.widget.model.ModelWidget"].widgetBoundaryCommentsEnabled(context)>
   <!-- @renderLookupField -->
   </#if>
   <#if (!ajaxUrl?has_content) && ajaxEnabled?has_content && ajaxEnabled>
diff --git a/specialpurpose/birt/src/org/ofbiz/birt/BirtFactory.java b/specialpurpose/birt/src/org/ofbiz/birt/BirtFactory.java
index 5112344..36e4cc0 100644
--- a/specialpurpose/birt/src/org/ofbiz/birt/BirtFactory.java
+++ b/specialpurpose/birt/src/org/ofbiz/birt/BirtFactory.java
@@ -27,7 +27,7 @@
 import org.eclipse.birt.report.engine.api.IReportEngine;
 import org.ofbiz.base.location.FlexibleLocation;
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.widget.screen.ScreenFactory;
+import org.ofbiz.widget.model.ScreenFactory;
 import org.xml.sax.SAXException;
 
 /**
diff --git a/specialpurpose/birt/src/org/ofbiz/birt/email/BirtEmailServices.java b/specialpurpose/birt/src/org/ofbiz/birt/email/BirtEmailServices.java
index 98f0a4d..ee9082d 100644
--- a/specialpurpose/birt/src/org/ofbiz/birt/email/BirtEmailServices.java
+++ b/specialpurpose/birt/src/org/ofbiz/birt/email/BirtEmailServices.java
@@ -52,8 +52,8 @@
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.widget.html.HtmlScreenRenderer;
-import org.ofbiz.widget.screen.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.html.HtmlScreenRenderer;
 import org.xml.sax.SAXException;
 
 public class BirtEmailServices {
diff --git a/specialpurpose/birt/webapp/birt/WEB-INF/web.xml b/specialpurpose/birt/webapp/birt/WEB-INF/web.xml
index 25a19b7..d758c82 100644
--- a/specialpurpose/birt/webapp/birt/WEB-INF/web.xml
+++ b/specialpurpose/birt/webapp/birt/WEB-INF/web.xml
@@ -39,7 +39,7 @@
     <context-param>
         <param-name>widgetVerbose</param-name>
         <param-value>false</param-value>
-        <description>Enable widget boundary comments. See org.ofbiz.widget.ModelWidget.widgetBoundaryCommentsEnabled().</description>
+        <description>Enable widget boundary comments. See org.ofbiz.widget.model.ModelWidget.widgetBoundaryCommentsEnabled().</description>
     </context-param>
     <context-param>
         <param-name>compressHTML</param-name>
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Mrv.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Mrv.groovy
index b2d3958..26d40d1 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Mrv.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Mrv.groovy
@@ -32,8 +32,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.base.util.collections.LifoSet;
 
 import javax.servlet.*;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Search.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Search.groovy
index 969fa80..9f97520 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Search.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/content/Search.groovy
@@ -27,7 +27,7 @@
 import org.ofbiz.base.util.UtilHttp
 import org.ofbiz.content.search.SearchWorker
 import org.ofbiz.product.feature.ParametricSearch
-import org.ofbiz.widget.html.HtmlFormWrapper
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper
 import org.apache.lucene.search.*
 import org.apache.lucene.index.DirectoryReader
 import org.apache.lucene.store.Directory
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentAddPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentAddPrep.groovy
index e6626a9..872d335 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentAddPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentAddPrep.groovy
@@ -31,8 +31,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.securityext.login.*;
 import org.ofbiz.common.*;
 import org.ofbiz.entity.model.*;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentPrep.groovy
index 3690b25..87dcbcc 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ContentPrep.groovy
@@ -23,8 +23,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.content.data.DataResourceWorker;
 import org.ofbiz.webapp.ftl.FreeMarkerViewHandler;
 import org.ofbiz.content.content.ContentWorker;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/CurrentValPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/CurrentValPrep.groovy
index 58e925e..c3b6598 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/CurrentValPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/CurrentValPrep.groovy
@@ -31,8 +31,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.content.ContentManagementWorker;
 
 import javax.servlet.*;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/EditAddPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/EditAddPrep.groovy
index 39c6301..6c742fa 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/EditAddPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/EditAddPrep.groovy
@@ -31,8 +31,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.securityext.login.*;
 import org.ofbiz.common.*;
 import org.ofbiz.entity.model.*;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/FormPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/FormPrep.groovy
index dc3a55e..a4199db 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/FormPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/FormPrep.groovy
@@ -33,8 +33,8 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
+import org.ofbiz.widget.model.*;
 import org.ofbiz.content.data.DataResourceWorker;
 
 
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/HtmlAreaPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/HtmlAreaPrep.groovy
index 7d333a1..08b9d76 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/HtmlAreaPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/HtmlAreaPrep.groovy
@@ -22,8 +22,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.content.data.DataResourceWorker;
 import org.ofbiz.webapp.ftl.FreeMarkerViewHandler;
 
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/NodeTrailPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/NodeTrailPrep.groovy
index e63eb48..0083497 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/NodeTrailPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/NodeTrailPrep.groovy
@@ -32,8 +32,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.securityext.login.*;
 import org.ofbiz.common.*;
 import org.ofbiz.entity.model.*;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/OwnerContentPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/OwnerContentPrep.groovy
index cf2a018..03cdb9e 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/OwnerContentPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/OwnerContentPrep.groovy
@@ -22,8 +22,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.content.data.DataResourceWorker;
 import org.ofbiz.webapp.ftl.FreeMarkerViewHandler;
 import org.ofbiz.content.content.ContentWorker;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PermPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PermPrep.groovy
index 54defd4..1b239a2 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PermPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PermPrep.groovy
@@ -32,8 +32,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.content.content.PermissionRecorder;
 import org.ofbiz.content.ContentManagementWorker;
 
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PubInit.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PubInit.groovy
index e94b4fb..a2fc188 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PubInit.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/PubInit.groovy
@@ -32,8 +32,7 @@
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
 import org.ofbiz.webapp.website.WebSiteWorker;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.securityext.login.*;
 import org.ofbiz.common.*;
 import org.ofbiz.entity.model.*;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/RespondPermAndPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/RespondPermAndPrep.groovy
index 22d5a48..c1c8225 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/RespondPermAndPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/RespondPermAndPrep.groovy
@@ -32,8 +32,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.content.content.PermissionRecorder;
 
 import javax.servlet.*;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ResponsePrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ResponsePrep.groovy
index dc767ba..b43bf1e 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ResponsePrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ResponsePrep.groovy
@@ -32,8 +32,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.securityext.login.*;
 import org.ofbiz.common.*;
 import org.ofbiz.content.content.ContentWorker;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ViewPrep.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ViewPrep.groovy
index a66a665..49214ce 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ViewPrep.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/forum/ViewPrep.groovy
@@ -32,8 +32,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.securityext.login.*;
 import org.ofbiz.common.*;
 import org.ofbiz.content.content.ContentWorker;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/includes/MruAdd.groovy b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/includes/MruAdd.groovy
index a497978..bf30075 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/includes/MruAdd.groovy
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/actions/includes/MruAdd.groovy
@@ -32,8 +32,7 @@
 import org.ofbiz.security.*;
 import org.ofbiz.service.*;
 import org.ofbiz.entity.model.*;
-import org.ofbiz.widget.html.*;
-import org.ofbiz.widget.form.*;
+import org.ofbiz.widget.renderer.html.HtmlFormWrapper;
 import org.ofbiz.content.ContentManagementWorker;
 import org.ofbiz.content.content.ContentWorker;
 import org.ofbiz.base.util.collections.LifoSet;
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
index 7819d50..3cf26e9 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
+++ b/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
@@ -33,9 +33,9 @@
 
     <handler name="jsp" type="view" class="org.ofbiz.webapp.view.JspViewHandler"/>
     <handler name="http" type="view" class="org.ofbiz.webapp.view.HttpViewHandler"/>
-    <handler name="screen" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/>
+    <handler name="screen" type="view" class="org.ofbiz.widget.renderer.macro.MacroScreenViewHandler"/>
     <handler name="simplecontent" type="view" class="org.ofbiz.content.view.SimpleContentViewHandler"/>
-    <handler name="screenfop" type="view" class="org.ofbiz.widget.screen.ScreenFopViewHandler"/>
+    <handler name="screenfop" type="view" class="org.ofbiz.widget.renderer.fo.ScreenFopViewHandler"/>
 
     <!-- Events run from here for the first hit in a visit -->
     <firstvisit>
diff --git a/specialpurpose/example/src/org/ofbiz/example/ExamplePrintServices.java b/specialpurpose/example/src/org/ofbiz/example/ExamplePrintServices.java
index 28239f1..50b4973 100644
--- a/specialpurpose/example/src/org/ofbiz/example/ExamplePrintServices.java
+++ b/specialpurpose/example/src/org/ofbiz/example/ExamplePrintServices.java
@@ -49,8 +49,8 @@
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.webapp.view.ApacheFopWorker;
-import org.ofbiz.widget.html.HtmlScreenRenderer;
-import org.ofbiz.widget.screen.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.html.HtmlScreenRenderer;
 import org.xml.sax.SAXException;
 
 public class ExamplePrintServices {
diff --git a/specialpurpose/googlecheckout/script/org/ofbiz/googleCheckout/PrepareXMLTemplate.xml b/specialpurpose/googlecheckout/script/org/ofbiz/googleCheckout/PrepareXMLTemplate.xml
index bc13918..b51e4de 100644
--- a/specialpurpose/googlecheckout/script/org/ofbiz/googleCheckout/PrepareXMLTemplate.xml
+++ b/specialpurpose/googlecheckout/script/org/ofbiz/googleCheckout/PrepareXMLTemplate.xml
@@ -102,18 +102,18 @@
         <set field="xscreenContext.sendInitialAuthDetails" from-field="sendInitialAuthDetails"/>
         <set field="xscreenContext.shoppingCart" from-field="parameters.shoppingCart"/>
         <!-- create string renderer -->
-        <create-object class-name="org.ofbiz.widget.html.HtmlScreenRenderer" field="xhtmlStringRenderer"></create-object>
+        <create-object class-name="org.ofbiz.widget.renderer.html.HtmlScreenRenderer" field="xhtmlStringRenderer"></create-object>
         <!-- create screen renderer -->
-        <create-object class-name="org.ofbiz.widget.screen.ScreenRenderer" field="screens">
+        <create-object class-name="org.ofbiz.widget.renderer.ScreenRenderer" field="screens">
             <field field="XMLWriter" type="java.lang.Appendable"/>
             <field field="xscreenContext" type="org.ofbiz.base.util.collections.MapStack"/>
-            <field field="xhtmlStringRenderer" type="org.ofbiz.widget.screen.ScreenStringRenderer"/>
+            <field field="xhtmlStringRenderer" type="org.ofbiz.widget.renderer.ScreenStringRenderer"/>
         </create-object>
         <set field="xscreenContext.screens" from-field="screens"/>
-        <create-object class-name="org.ofbiz.widget.screen.ScreenRenderer" field="xscreens">
+        <create-object class-name="org.ofbiz.widget.renderer.ScreenRenderer" field="xscreens">
             <field field="XMLWriter" type="java.lang.Appendable"/>
             <field field="xscreenContext" type="org.ofbiz.base.util.collections.MapStack"/>
-            <field field="xhtmlStringRenderer" type="org.ofbiz.widget.screen.ScreenStringRenderer"/>
+            <field field="xhtmlStringRenderer" type="org.ofbiz.widget.renderer.ScreenStringRenderer"/>
         </create-object>
         <!-- get uri -->
         <property-to-field resource="googleCheckout" property="xmlTemplateUri" field="screenUri"/>
diff --git a/specialpurpose/googlecheckout/webapp/googlecheckout/WEB-INF/web.xml b/specialpurpose/googlecheckout/webapp/googlecheckout/WEB-INF/web.xml
index 22091dc..809b3ac 100644
--- a/specialpurpose/googlecheckout/webapp/googlecheckout/WEB-INF/web.xml
+++ b/specialpurpose/googlecheckout/webapp/googlecheckout/WEB-INF/web.xml
@@ -46,7 +46,7 @@
     <context-param>
         <param-name>widgetVerbose</param-name>
         <param-value>false</param-value>
-        <description>Enable widget boundary comments. See org.ofbiz.widget.ModelWidget.widgetBoundaryCommentsEnabled().</description>
+        <description>Enable widget boundary comments. See org.ofbiz.widget.model.ModelWidget.widgetBoundaryCommentsEnabled().</description>
     </context-param>
     <context-param>
         <param-name>compressHTML</param-name>
diff --git a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisServices.java b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisServices.java
index eb308d3..8bef31b 100644
--- a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisServices.java
+++ b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisServices.java
@@ -63,9 +63,9 @@
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.widget.fo.FoFormRenderer;
-import org.ofbiz.widget.html.HtmlScreenRenderer;
-import org.ofbiz.widget.screen.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.fo.FoFormRenderer;
+import org.ofbiz.widget.renderer.html.HtmlScreenRenderer;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
diff --git a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisShipmentServices.java b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisShipmentServices.java
index 7c00c37..158dc4a 100644
--- a/specialpurpose/oagis/src/org/ofbiz/oagis/OagisShipmentServices.java
+++ b/specialpurpose/oagis/src/org/ofbiz/oagis/OagisShipmentServices.java
@@ -61,9 +61,9 @@
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.widget.fo.FoFormRenderer;
-import org.ofbiz.widget.html.HtmlScreenRenderer;
-import org.ofbiz.widget.screen.ScreenRenderer;
+import org.ofbiz.widget.renderer.ScreenRenderer;
+import org.ofbiz.widget.renderer.fo.FoFormRenderer;
+import org.ofbiz.widget.renderer.html.HtmlScreenRenderer;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
diff --git a/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml b/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml
index efe5fcc..a516711 100644
--- a/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml
+++ b/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml
@@ -46,7 +46,7 @@
         <param-name>widgetVerbose</param-name>
         <param-value>false</param-value>
         <description>Enable widget boundary comments. See
-            org.ofbiz.widget.ModelWidget.widgetBoundaryCommentsEnabled().
+            org.ofbiz.widget.model.ModelWidget.widgetBoundaryCommentsEnabled().
         </description>
     </context-param>
     <context-param>
diff --git a/specialpurpose/scrum/webapp/scrum/WEB-INF/web.xml b/specialpurpose/scrum/webapp/scrum/WEB-INF/web.xml
index 2394a62..b40ecd5 100644
--- a/specialpurpose/scrum/webapp/scrum/WEB-INF/web.xml
+++ b/specialpurpose/scrum/webapp/scrum/WEB-INF/web.xml
@@ -38,7 +38,7 @@
     <context-param>
         <param-name>widgetVerbose</param-name>
         <param-value>false</param-value>
-        <description>Enable widget boundary comments. See org.ofbiz.widget.ModelWidget.widgetBoundaryCommentsEnabled().</description>
+        <description>Enable widget boundary comments. See org.ofbiz.widget.model.ModelWidget.widgetBoundaryCommentsEnabled().</description>
     </context-param>
     <context-param>
         <param-name>compressHTML</param-name>
diff --git a/specialpurpose/webpos/webapp/webpos/WEB-INF/controller.xml b/specialpurpose/webpos/webapp/webpos/WEB-INF/controller.xml
index cfc6e54..87b3c7f 100644
--- a/specialpurpose/webpos/webapp/webpos/WEB-INF/controller.xml
+++ b/specialpurpose/webpos/webapp/webpos/WEB-INF/controller.xml
@@ -28,7 +28,7 @@
     <handler name="simple" type="request" class="org.ofbiz.webapp.event.SimpleEventHandler"/>
     <handler name="groovy" type="request" class="org.ofbiz.webapp.event.GroovyEventHandler"/>    
     <handler name="jsp" type="view" class="org.ofbiz.webapp.view.JspViewHandler"/>
-    <handler name="screen" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/>
+    <handler name="screen" type="view" class="org.ofbiz.widget.renderer.macro.MacroScreenViewHandler"/>
     
     <!-- Events run from here for the first hit in a visit -->
     <firstvisit>
diff --git a/themes/bluelight/includes/appbarOpen.ftl b/themes/bluelight/includes/appbarOpen.ftl
index f32cd29..48716f9 100644
--- a/themes/bluelight/includes/appbarOpen.ftl
+++ b/themes/bluelight/includes/appbarOpen.ftl
@@ -23,7 +23,7 @@
 <#assign displayApps = Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security, userLogin, ofbizServerName, "main")>
 <#assign displaySecondaryApps = Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security, userLogin, ofbizServerName, "secondary")>
 
-<#assign appModelMenu = Static["org.ofbiz.widget.menu.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
+<#assign appModelMenu = Static["org.ofbiz.widget.model.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
 <#if appModelMenu.getModelMenuItemByName(headerItem)??>
   <#if headerItem!="main">
     <#assign show_last_menu = true>
diff --git a/themes/droppingcrumbs/includes/appbarClose.ftl b/themes/droppingcrumbs/includes/appbarClose.ftl
index d26504b..02ee335 100644
--- a/themes/droppingcrumbs/includes/appbarClose.ftl
+++ b/themes/droppingcrumbs/includes/appbarClose.ftl
@@ -16,7 +16,7 @@
 specific language governing permissions and limitations
 under the License.
 -->
-<#assign appModelMenu = Static["org.ofbiz.widget.menu.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
+<#assign appModelMenu = Static["org.ofbiz.widget.model.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
 <#if appModelMenu.getModelMenuItemByName(headerItem)??>
   <#if headerItem!="main">
     <div class="breadcrumbs-sep">
diff --git a/themes/droppingcrumbs/includes/appbarOpen.ftl b/themes/droppingcrumbs/includes/appbarOpen.ftl
index 54e62e8..08372b7 100644
--- a/themes/droppingcrumbs/includes/appbarOpen.ftl
+++ b/themes/droppingcrumbs/includes/appbarOpen.ftl
@@ -24,7 +24,7 @@
 <#assign displayApps = Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security, userLogin, ofbizServerName, "main")>
 <#assign displaySecondaryApps = Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security, userLogin, ofbizServerName, "secondary")>
 
-<#assign appModelMenu = Static["org.ofbiz.widget.menu.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
+<#assign appModelMenu = Static["org.ofbiz.widget.model.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
 <#if appModelMenu.getModelMenuItemByName(headerItem)??>
   <#if headerItem!="main">
     <#assign show_last_menu = true>
diff --git a/themes/tomahawk/includes/appbarClose.ftl b/themes/tomahawk/includes/appbarClose.ftl
index fb14d29..6bae13e 100644
--- a/themes/tomahawk/includes/appbarClose.ftl
+++ b/themes/tomahawk/includes/appbarClose.ftl
@@ -16,7 +16,7 @@
 specific language governing permissions and limitations
 under the License.
 -->
-<#assign appModelMenu = Static["org.ofbiz.widget.menu.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
+<#assign appModelMenu = Static["org.ofbiz.widget.model.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
 <#if person?has_content>
   <#assign userName = (person.firstName!) + " " + (person.middleName!) + " " + person.lastName!>
 <#elseif partyGroup?has_content>
diff --git a/themes/tomahawk/includes/appbarOpen.ftl b/themes/tomahawk/includes/appbarOpen.ftl
index dbba5bd..01ae98c 100644
--- a/themes/tomahawk/includes/appbarOpen.ftl
+++ b/themes/tomahawk/includes/appbarOpen.ftl
@@ -24,7 +24,7 @@
 <#assign displayApps = Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security, userLogin, ofbizServerName, "main")>
 <#assign displaySecondaryApps = Static["org.ofbiz.webapp.control.LoginWorker"].getAppBarWebInfos(security, userLogin, ofbizServerName, "secondary")>
 
-<#assign appModelMenu = Static["org.ofbiz.widget.menu.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
+<#assign appModelMenu = Static["org.ofbiz.widget.model.MenuFactory"].getMenuFromLocation(applicationMenuLocation,applicationMenuName)>
 <#if appModelMenu.getModelMenuItemByName(headerItem)??>
   <#if headerItem!="main">
     <#assign show_last_menu = true>
