diff --git a/README b/README
index c291f55..48e1aef 100644
--- a/README
+++ b/README
@@ -1,14 +1,15 @@
 
 Welcome to Apache OFBiz!
 
-All you need to run OFBiz is a 1.6 (version 6) JDK
+All you need to run OFBiz is a 1.7 (version 7) JDK
 (not just the JRE, the full JDK).
 http://java.sun.com/javase/downloads/index.jsp
 
 You can load the demo data (strongly advised if you are new to
 OFBiz) with the following command on the command line
 from the OFBiz home folder (in Unix-like operating systems
-type "./ant" rather than "ant"):
+type "./ant" rather than "ant" to use the embed ant version
+ if you haven't installed it on your system) :
 
 ant load-demo
 
@@ -17,10 +18,14 @@
 ant start
 
 (or "java -Xms128M -Xmx512M -XX:MaxPermSize=128m -jar ofbiz.jar")
+(you can also run directly "ant load-demo start")
 
 Once OFBiz starts, you can look at the demo storefront at:
 http://localhost:8080/ecommerce
 
+the back office at:
+https://localhost:8443/ordermgr
+
 and the administration interface at:
 https://localhost:8443/webtools
 
diff --git a/applications/accounting/script/org/ofbiz/accounting/cost/CostServices.xml b/applications/accounting/script/org/ofbiz/accounting/cost/CostServices.xml
deleted file mode 100644
index 6666c75..0000000
--- a/applications/accounting/script/org/ofbiz/accounting/cost/CostServices.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-
-<simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/simple-methods-v2.xsd">
-
-    <simple-method method-name="createCostComponentCalc" short-description="Create a CostComponentCalc entry">
-        <make-value entity-name="CostComponentCalc" value-field="newEntity"/>
-        <sequenced-id sequence-name="CostComponentCalc" field="costComponentCalcId"/>
-        <set from-field="costComponentCalcId" field="newEntity.costComponentCalcId"/>
-        <field-to-result field="costComponentCalcId" result-name="costComponentCalcId"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    <simple-method method-name="updateCostComponentCalc" short-description="Update a CostComponentCalc entry">
-        <entity-one entity-name="CostComponentCalc" value-field="costComponentCalc"/>
-        <set-nonpk-fields map="parameters" value-field="costComponentCalc"/>
-        <store-value value-field="costComponentCalc"/>
-    </simple-method>
-    <simple-method method-name="removeCostComponentCalc" short-description="Remove a CostComponentCalc entry">
-        <entity-one entity-name="CostComponentCalc" value-field="costComponentCalc"/>
-        <remove-value value-field="costComponentCalc"/>
-    </simple-method>
-    <simple-method method-name="createWorkEffortCostCalc" short-description="Create a WorkEffortCostCalc entry">
-        <make-value entity-name="WorkEffortCostCalc" value-field="newEntity"/>
-        <set-pk-fields map="parameters" value-field="newEntity"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <if-empty field="newEntity.fromDate">
-            <now-timestamp field="newEntity.fromDate"/>
-        </if-empty>
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    <simple-method method-name="removeWorkEffortCostCalc" short-description="Remove a WorkEffortCostCalc entry">
-        <entity-one entity-name="WorkEffortCostCalc" value-field="workEffortCostCalc"/>
-        <remove-value value-field="workEffortCostCalc"/>
-    </simple-method>
-</simple-methods>
diff --git a/applications/accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml b/applications/accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml
index c4323bc..7bcf9ff 100644
--- a/applications/accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml
+++ b/applications/accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml
@@ -21,131 +21,6 @@
 <simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/simple-methods-v2.xsd">
 
-    <!-- ================================================================ -->
-    <!-- FixedAsset Services -->
-    <!-- ================================================================ -->
-
-    <!-- create a new Fixed Asset header record -->
-    <simple-method method-name="createFixedAsset" short-description="Create an FixedAsset">
-          <!-- create new entity and create all the fields -->
-        <make-value value-field="newEntity" entity-name="FixedAsset"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-
-        <!-- create a non existing ID if not supplied -->
-        <if-empty field="parameters.fixedAssetId">
-            <sequenced-id sequence-name="FixedAsset" field="newEntity.fixedAssetId"/>
-        <else>
-            <!-- check the Duplicate ID> -->
-            <entity-one entity-name="FixedAsset" value-field="fixedAsset"/>
-            <if-not-empty field="fixedAsset">
-                <add-error>
-                    <fail-property resource="AccountingUiLabels" property="AccountingFixedAssetIdAlreadyExists"/>
-                </add-error>
-                <log level="info" message="${AccountingUiLabels.AccountingFixedAssetIdAlreadyExists}"/>
-                <else>
-                    <check-id field="parameters.fixedAssetId"/>
-                </else>                
-            </if-not-empty>
-            <check-errors/>
-            <set from-field="parameters.fixedAssetId" field="newEntity.fixedAssetId"/>
-        </else>
-        </if-empty>
-        <field-to-result field="newEntity.fixedAssetId" result-name="fixedAssetId"/>
-
-        <!-- finally create the record (should not exist already)-->
-        <create-value value-field="newEntity"/>
-    </simple-method>
-
-    <!-- update an existing Fixed Asset header Record -->
-    <simple-method method-name="updateFixedAsset" short-description="Update an existing FixedAsset">
-        <entity-one entity-name="FixedAsset" value-field="lookedUpValue"/>
-        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
-        <store-value value-field="lookedUpValue"/>
-    </simple-method>
-
-    <!-- ================================================================ -->
-    <!-- FixedAssetMember Services -->
-    <!-- ================================================================ -->
-
-    <!-- add a product to a fixed Asset -->
-    <simple-method method-name="addFixedAssetProduct" short-description="Add Product to FixedAsset">
-        <make-value value-field="newEntity" entity-name="FixedAssetProduct"/>
-        <set-pk-fields map="parameters" value-field="newEntity"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-
-        <if-empty field="newEntity.fromDate">
-            <now-timestamp field="newEntity.fromDate"/>
-        </if-empty>
-
-        <create-value value-field="newEntity"/>
-    </simple-method>
-
-    <!-- update the product to fixed Asset link -->
-    <simple-method method-name="updateFixedAssetProduct" short-description="Update Products of a FixedAsset">
-        <entity-one entity-name="FixedAssetProduct" value-field="lookedUpValue"/>
-        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
-        <store-value value-field="lookedUpValue"/>
-    </simple-method>
-
-    <!-- remove the productlink from the Fixed Asset -->
-    <simple-method method-name="removeFixedAssetProduct" short-description="Remove Product From FixedAsset">
-        <entity-one entity-name="FixedAssetProduct" value-field="lookedUpValue"/>
-        <remove-value value-field="lookedUpValue"/>
-    </simple-method>
-
-    <!-- ================================================================ -->
-    <!-- FixedAssetCalendar Services -->
-    <!-- ================================================================ -->
-    <!-- update the calendar of the fixed Asset -->
-<!--     <simple-method method-name="updateFixedAssetCalendar" short-description="Update the calendar of the FixedAsset">
-        <check-permission permission="ACCOUNTING" action="_UPDATE">
-            <alt-permission permission="ACCOUNTING_ROLE" action="_UPDATE"/>
-            <fail-property resource="AccountingUiLabels" property="AccountingUpdatePermissionError"/>
-        </check-permission>
-        <check-errors/>
-
-        <entity-one entity-name="FixedAsset" value-field="fixedAsset"/>
-
-        <make-value value-field="excDayPKMap" entity-name="TechDataCalendarExcDay"/>
-        <set-pk-fields field-name= "calendarId" map="fixedAsset" value-field="excDayPKMap"/>
-        <set-pk-fields fieldName= "exceptionDateStartTime" map="parameters" value-field="excDayPKMap"/>
-        <find-by entity-name="TechDataCalendarExcDay" map-name="excDayPKMap" value-name="lookedUpValue"/>
-        <set-nonpk-fields field-name="capacity" map="parameters" value-field="lookedUpValue"/>
-        <store-value value-field="lookedUpValue"/>
-    </simple-method>
-
-
- -->
-
-
-    <!-- create a new FixedAssetStdCost -->
-    <simple-method method-name="createFixedAssetStdCost" short-description="Create a FixedAssetStdCost">
-        <!-- TODO: we should cancel the existing costs of the same type -->
-        <!-- create new entity and create all the fields -->
-
-        <!-- Check, should not exist already -->
-        <entity-one entity-name="FixedAssetStdCost" value-field="fixedAssetStdCost"/>
-        <if-not-empty field="fixedAssetStdCost">
-            <add-error>
-                <fail-property resource="AccountingUiLabels" property="AccountingFixedAssetStdCostAlreadyExists"/>
-            </add-error>
-        </if-not-empty>
-        <check-errors/>
-
-        <make-value value-field="newEntity" entity-name="FixedAssetStdCost"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <set-pk-fields map="parameters" value-field="newEntity"/>
-
-        <!-- finally create the record (should not exist already)-->
-        <create-value value-field="newEntity"/>
-        <check-errors/>
-    </simple-method>
-    <!-- update an existing FixedAssetStdCost -->
-    <simple-method method-name="updateFixedAssetStdCost" short-description="Update an existing FixedAssetStdCost">
-        <entity-one entity-name="FixedAssetStdCost" value-field="fixedAssetStdCost"/>
-        <set-nonpk-fields map="parameters" value-field="fixedAssetStdCost"/>
-        <store-value value-field="fixedAssetStdCost"/>
-    </simple-method>
     <!-- cancel an existing Agreement -->
     <simple-method method-name="cancelFixedAssetStdCost" short-description="Cancel an existing FixedAssetStdCost">
         <entity-one entity-name="FixedAssetStdCost" value-field="fixedAssetStdCost"/>
@@ -153,43 +28,6 @@
         <store-value value-field="fixedAssetStdCost"/>
     </simple-method>
 
-    <!-- Fixed Asset Identification "FIXED_ASSET_IDENT"-->
-    <simple-method method-name="createFixedAssetIdent" short-description="Create an FixedAssetIdent">
-        <make-value value-field="newEntity" entity-name="FixedAssetIdent"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <set-pk-fields map="parameters" value-field="newEntity"/>
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    <simple-method method-name="updateFixedAssetIdent" short-description="Update an existing FixedAssetIdent">
-        <entity-one entity-name="FixedAssetIdent" value-field="lookedUpValue"/>
-        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
-        <store-value value-field="lookedUpValue"/>
-    </simple-method>
-    <simple-method method-name="removeFixedAssetIdent" short-description="Remove Fixed Assets Idents FixedAssetIdent">
-        <entity-one entity-name="FixedAssetIdent" value-field="lookedUpValue"/>
-        <remove-value value-field="lookedUpValue"/>
-    </simple-method>
-
-    <!-- FixedAsset Registration Create/Update/Delete"-->
-    <simple-method method-name="createFixedAssetRegistration" short-description="Create FixedAsset Registration">
-        <make-value value-field="newEntity" entity-name="FixedAssetRegistration"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <set-pk-fields map="parameters" value-field="newEntity"/>
-        <if-empty field="newEntity.fromDate">
-            <now-timestamp field="newEntity.fromDate"/>
-        </if-empty>
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    <simple-method method-name="updateFixedAssetRegistration" short-description="Update an existing FixedAsset Registration">
-        <entity-one entity-name="FixedAssetRegistration" value-field="lookedUpValue"/>
-        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
-        <store-value value-field="lookedUpValue"/>
-    </simple-method>
-    <simple-method method-name="deleteFixedAssetRegistration" short-description="Delete FixedAsset Registration">
-        <entity-one entity-name="FixedAssetRegistration" value-field="lookedUpValue"/>
-        <remove-value value-field="lookedUpValue"/>
-    </simple-method>
-
     <!--  create/update/delete FixedAssetMaint -->
     <simple-method method-name="createFixedAssetMaint" short-description="create a FixedAssetMaint">
         <make-value entity-name="FixedAssetMaint" value-field="newEntity"/>
@@ -305,10 +143,6 @@
             </then>
         </if>
     </simple-method>
-    <simple-method method-name="deleteFixedAssetMaint" short-description="Delete FixedAsset Maintenance">
-        <entity-one entity-name="FixedAssetMaint" value-field="lookedUpValue"/>
-        <remove-value value-field="lookedUpValue"/>
-    </simple-method>
 
     <!--  create/update/delete FixedAssetMeter -->
     <simple-method method-name="createFixedAssetMeter" short-description="Create a Fixed Asset Meter Reading">
@@ -328,10 +162,6 @@
         <set field="meterValue" from-field="lookedUpValue"/>
         <call-simple-method method-name="createMaintsFromMeterReading"/>
     </simple-method>
-    <simple-method method-name="deleteFixedAssetMeter" short-description="Delete a Fixed Asset Meter Reading">
-        <entity-one entity-name="FixedAssetMeter" value-field="lookedUpValue"/>
-        <remove-value value-field="lookedUpValue"/>
-    </simple-method>
     <simple-method method-name="createMaintsFromMeterReading" short-description="Create Fixed Asset Maintenances From A Meter Reading">
         <if-not-empty field="meterValue.maintHistSeqId">
             <return/>
@@ -507,33 +337,6 @@
         <set-nonpk-fields map="parameters" value-field="newEntity"/>
         <create-value value-field="newEntity"/>
     </simple-method>
-    <simple-method method-name="deleteFixedAssetMaintOrder" short-description="Delete FixedAsset Maintenance Order">
-        <entity-one entity-name="FixedAssetMaintOrder" value-field="lookedUpValue"/>
-        <remove-value value-field="lookedUpValue"/>
-    </simple-method>
-
-    <!-- ==============Party Fixed Asset Assignment============= -->
-    <simple-method method-name="createPartyFixedAssetAssignment" short-description="Associate Party to Fixed Asset">
-        <make-value entity-name="PartyFixedAssetAssignment" value-field="newEntity"/>
-        <set-pk-fields value-field="newEntity" map="parameters"/>
-        <set-nonpk-fields value-field="newEntity" map="parameters"/>
-        <if-empty field="newEntity.fromDate">
-            <now-timestamp field="nowTimestamp"/>
-            <set field="newEntity.fromDate" from-field="nowTimestamp"/>
-        </if-empty>
-        <create-value value-field="newEntity"/>
-    </simple-method>
-
-    <simple-method method-name="updatePartyFixedAssetAssignment" short-description="Update Party to Fixed Asset">
-        <entity-one entity-name="PartyFixedAssetAssignment" value-field="newEntity"/>
-        <set-nonpk-fields value-field="newEntity" map="parameters"/>
-        <store-value value-field="newEntity"/>
-    </simple-method>
-
-    <simple-method method-name="deletePartyFixedAssetAssignment" short-description="Delete Party to Fixed Asset">
-        <entity-one entity-name="PartyFixedAssetAssignment" value-field="newEntity"/>
-        <remove-value value-field="newEntity"/>
-    </simple-method>
 
     <simple-method method-name="autoAssignFixedAssetPartiesToMaintenance" login-required="true"
         short-description="Auto-assign Fixed Asset Parties to a Fixed Asset Maintenance">
diff --git a/applications/accounting/script/org/ofbiz/accounting/invoice/InvoiceServices.xml b/applications/accounting/script/org/ofbiz/accounting/invoice/InvoiceServices.xml
index b3f4905..c33d330 100644
--- a/applications/accounting/script/org/ofbiz/accounting/invoice/InvoiceServices.xml
+++ b/applications/accounting/script/org/ofbiz/accounting/invoice/InvoiceServices.xml
@@ -45,14 +45,14 @@
                     <set field="customMethodName" value="invoiceSequenceRestart"/>
                 </if-compare>
             </else>
-        </if-not-empty>        
+        </if-not-empty>
 
         <if-not-empty field="customMethodName">
             <set-service-fields service-name="${customMethodName}" map="parameters" to-map="customMethodMap"/>
             <set field="customMethodMap.partyAcctgPreference" from-field="partyAcctgPreference"/>
             <call-service service-name="${customMethodName}" in-map-name="customMethodMap">
                <result-to-field result-name="invoiceId" field="invoiceIdTemp"/>
-            </call-service>            
+            </call-service>
             <else>
                 <log level="info" message="In createInvoice sequence enum Standard"/>
                 <!-- default to the default sequencing: INVSQ_STANDARD -->
@@ -172,7 +172,7 @@
         <if-not-empty field="party.preferredCurrencyUomId">
             <set field="parameters.currencyUomId" from-field="party.preferredCurrencyUomId"/>
         </if-not-empty>
-        
+
         <set-nonpk-fields map="parameters" value-field="newEntity"/>
         <set-pk-fields map="parameters" value-field="newEntity"/>
         <create-value value-field="newEntity"/>
@@ -610,12 +610,6 @@
         <field-to-result field="contactMechId" result-name="invoiceContactMech"/>
     </simple-method>
 
-    <simple-method method-name="updateInvoiceItemType"  short-description="Updates a InvoiceItemType Record">
-        <entity-one entity-name="InvoiceItemType" value-field="lookedUpValue"/>
-        <set-nonpk-fields value-field="lookedUpValue" map="parameters"/>
-        <store-value value-field="lookedUpValue"/>
-   </simple-method>
-
    <simple-method method-name="autoGenerateInvoiceFromExistingInvoice" short-description="Scheduled service to generate Invoice from an existing Invoice">
        <entity-and entity-name="Invoice" list="invoices">
             <field-map field-name="recurrenceInfoId" from-field="parameters.recurrenceInfoId"/>
@@ -640,7 +634,7 @@
            <call-service service-name="updateInvoice" in-map-name="updateInvoiceCtx"/>
        </iterate>
    </simple-method>
-    
+
     <simple-method method-name="cancelInvoice" short-description="Service to cancel the Invoices">
         <entity-one entity-name="Invoice" value-field="invoice"/>
         <if-empty field="invoice">
@@ -697,7 +691,7 @@
         <set field="invoiceRunningTotal" value="${groovy:org.ofbiz.base.util.UtilFormatOut.formatCurrency(runningTotal, currencyUomId, parameters.locale)}"/>
         <field-to-result field="invoiceRunningTotal"/>
     </simple-method>
-    
+
     <simple-method method-name="getInvoicesFilterByAssocType" short-description="Filter invoices by invoiceItemAssocTypeId">
         <set field="invoiceList" from-field="parameters.invoiceList"/>
         <set field="invoiceItemAssocTypeId" from-field="parameters.invoiceItemAssocTypeId"/>
@@ -1010,7 +1004,7 @@
         <set-service-fields service-name="updateSimpleTextContent" map="parameters" to-map="updateSimpleText"/>
         <call-service service-name="updateSimpleTextContent" in-map-name="updateSimpleText"/>
     </simple-method>
-    
+
     <simple-method method-name="isInvoiceInForeignCurrency" short-description="check if a invoice is in a foreign currency related to the accounting company.">
         <entity-one value-field="invoice" entity-name="InvoiceAndType">
             <field-map field-name="invoiceId" from-field="parameters.invoiceId"/>
@@ -1021,10 +1015,10 @@
         </if-empty>
         <if-compare field="invoice.parentTypeId" operator="equals" value="PURCHASE_INVOICE">
             <set field="pref.organizationPartyId" from-field="invoice.partyId"/>
-        </if-compare>          
+        </if-compare>
         <if-compare field="invoice.parentTypeId" operator="equals" value="SALES_INVOICE">
             <set field="pref.organizationPartyId" from-field="invoice.partyIdFrom"/>
-        </if-compare>          
+        </if-compare>
         <call-service service-name="getPartyAccountingPreferences" in-map-name="pref">
             <result-to-field result-name="partyAccountingPreference"/>
         </call-service>
@@ -1036,5 +1030,5 @@
         </if-compare-field>
         <field-to-result field="isForeign"/>
     </simple-method>
-       
+
 </simple-methods>
diff --git a/applications/accounting/script/org/ofbiz/accounting/payment/BillingServices.xml b/applications/accounting/script/org/ofbiz/accounting/payment/BillingServices.xml
deleted file mode 100644
index f5c9fc6..0000000
--- a/applications/accounting/script/org/ofbiz/accounting/payment/BillingServices.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-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.
--->
-
-<simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/simple-methods-v2.xsd">
-    <simple-method method-name="createBillingAccount" short-description="Create Billing Account">
-        <make-value value-field="newEntity" entity-name="BillingAccount"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-
-        <sequenced-id sequence-name="BillingAccount" field="billingAccountId"/>
-        <to-string field="billingAccountId"/>
-        <set from-field="billingAccountId" field="newEntity.billingAccountId"/>
-        <field-to-result field="billingAccountId" result-name="billingAccountId"/>
-
-        <if-empty field="newEntity.fromDate">
-            <now-timestamp field="nowTimestamp"/>
-            <set from-field="nowTimestamp" field="newEntity.fromDate"/>
-        </if-empty>
-
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    <simple-method method-name="updateBillingAccount" short-description="Update Billing Account">
-        <make-value value-field="lookupPKMap" entity-name="BillingAccount"/>
-        <set-pk-fields map="parameters" value-field="lookupPKMap"/>
-        <find-by-primary-key entity-name="BillingAccount" map="lookupPKMap" value-field="lookedUpValue"/>
-        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
-        <store-value value-field="lookedUpValue"/>
-    </simple-method>
-    <simple-method method-name="createBillingAccountRole" short-description="Create Billing Account Role">
-        <make-value value-field="newEntity" entity-name="BillingAccountRole"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-        <set-pk-fields map="parameters" value-field="newEntity"/>
-        <if-empty field="newEntity.fromDate">
-            <now-timestamp field="nowTimestamp"/>
-            <set from-field="nowTimestamp" field="newEntity.fromDate"/>
-        </if-empty>
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    <simple-method method-name="updateBillingAccountRole" short-description="Update Billing Account Role">
-        <make-value value-field="lookupPKMap" entity-name="BillingAccountRole"/>
-        <set-pk-fields map="parameters" value-field="lookupPKMap"/>
-        <find-by-primary-key entity-name="BillingAccountRole" map="lookupPKMap" value-field="lookedUpValue"/>
-        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
-        <store-value value-field="lookedUpValue"/>
-    </simple-method>
-    <simple-method method-name="removeBillingAccountRole" short-description="Remove Billing Account Role">
-        <make-value value-field="lookupPKMap" entity-name="BillingAccountRole"/>
-        <set-pk-fields map="parameters" value-field="lookupPKMap"/>
-        <find-by-primary-key entity-name="BillingAccountRole" map="lookupPKMap" value-field="lookedUpValue"/>
-        <remove-value value-field="lookedUpValue"/>
-    </simple-method>
-    <simple-method method-name="createBillingAccountTerm" short-description="Create Billing Account Term">
-        <make-value value-field="newEntity" entity-name="BillingAccountTerm"/>
-        <set-nonpk-fields map="parameters" value-field="newEntity"/>
-
-        <sequenced-id sequence-name="BillingAccountTerm" field="billingAccountTermId"/>
-        <to-string field="billingAccountTermId"/>
-        <set from-field="billingAccountTermId" field="newEntity.billingAccountTermId"/>
-        <field-to-result field="billingAccountTermId" result-name="billingAccountTermId"/>
-
-        <create-value value-field="newEntity"/>
-    </simple-method>
-    <simple-method method-name="updateBillingAccountTerm" short-description="Update Billing Account Term">
-        <make-value value-field="lookupPKMap" entity-name="BillingAccountTerm"/>
-        <set-pk-fields map="parameters" value-field="lookupPKMap"/>
-        <find-by-primary-key entity-name="BillingAccountTerm" map="lookupPKMap" value-field="lookedUpValue"/>
-        <set-nonpk-fields map="parameters" value-field="lookedUpValue"/>
-        <store-value value-field="lookedUpValue"/>
-    </simple-method>
-    <simple-method method-name="removeBillingAccountTerm" short-description="Remove Billing Account Term">
-        <make-value entity-name="BillingAccountTerm" value-field="lookupPKMap"/>
-        <set-pk-fields map="parameters" value-field="lookupPKMap"/>
-        <find-by-primary-key entity-name="BillingAccountTerm" map="lookupPKMap" value-field="lookedUpValue"/>
-        <remove-value value-field="lookedUpValue"/>
-    </simple-method>
-</simple-methods>
diff --git a/applications/accounting/script/org/ofbiz/accounting/payment/PaymentServices.xml b/applications/accounting/script/org/ofbiz/accounting/payment/PaymentServices.xml
index 677df2d..40893b0 100644
--- a/applications/accounting/script/org/ofbiz/accounting/payment/PaymentServices.xml
+++ b/applications/accounting/script/org/ofbiz/accounting/payment/PaymentServices.xml
@@ -125,9 +125,9 @@
         </if-compare>
         <check-errors/>
 
-        <set field="statusIdSave" from-field="payment.statusId"/>    <!-- do not allow status change here -->
+        <set field="statusIdSave" from-field="payment.statusId"/><!-- do not allow status change here -->
         <set-nonpk-fields map="parameters" value-field="payment"/>
-        <set field="payment.statusId" from-field="statusIdSave"/>    <!-- do not allow status change here -->
+        <set field="payment.statusId" from-field="statusIdSave"/><!-- do not allow status change here -->
 
         <if-empty field="payment.effectiveDate">
             <now-timestamp field="payment.effectiveDate"/>
@@ -262,20 +262,19 @@
                 </if-compare-field>
             </if-empty>
         </if-not-empty>
-            
-        
+
         <if-not-empty field="parameters.billingAccountId">
             <if-empty field="paymentAppl.amountApplied">
                 <set field="paymentAppl.amountApplied" from-field="notAppliedPayment"/>
             </if-empty>
         </if-not-empty>
-        
+
         <if-not-empty field="parameters.taxAuthGeoId">
             <if-empty field="paymentAppl.amountApplied">
                 <set field="paymentAppl.amountApplied" from-field="notAppliedPayment"/>
             </if-empty>
         </if-not-empty>
-        
+
         <sequenced-id sequence-name="PaymentApplication" field="paymentAppl.paymentApplicationId"/>
         <field-to-result field="paymentAppl.amountApplied" result-name="amountApplied"/>
         <field-to-result field="paymentAppl.paymentApplicationId" result-name="paymentApplicationId"/>
@@ -283,7 +282,6 @@
         <create-value value-field="paymentAppl"/>
         <entity-one value-field="payment" entity-name="Payment"/>
         <field-to-result field="payment.paymentTypeId" result-name="paymentTypeId"/>
-        
     </simple-method>
 
     <simple-method method-name="setPaymentStatus" short-description="Set The Payment Status">
@@ -330,7 +328,6 @@
                         </then>
                     </if>
 
-
                     <!-- check if the payment fully applied when set to confirmed-->
                     <if-compare field="parameters.statusId" operator="equals" value="PMNT_CONFIRMED">
                         <set field="notYetApplied" value="${groovy:org.ofbiz.accounting.payment.PaymentWorker.getPaymentNotApplied(payment)}"/>
@@ -362,7 +359,6 @@
                     <!-- everything ok so now change the status field -->
                     <set from-field="parameters.statusId" field="payment.statusId"/>
                     <store-value value-field="payment"/>
-
                 </else>
             </if-empty>
         </if-compare-field>
@@ -536,7 +532,7 @@
         </iterate>
         <field-to-result field="selectedInvoicePaymentInfoList" result-name="invoicePaymentInfoList"/>
     </simple-method>
-    
+
     <simple-method method-name="voidPayment" short-description="Service to void a payment">
         <check-permission permission="ACCOUNTING" action="_UPDATE">
             <alt-permission permission="ACCOUNTING_ROLE" action="_UPDATE"/>
@@ -620,7 +616,7 @@
                     <fail-property resource="AccountingUiLabels" property="AccountingTransactionIsAlreadyReconciled"/>
                 </add-error>
                 <check-errors/>
-            </if-compare>      
+            </if-compare>
             <iterate list="paymentGroupMemberAndTransList" entry="paymentGroupMemberAndTrans">
                 <set-service-fields service-name="expirePaymentGroupMember" map="paymentGroupMemberAndTrans" to-map="expirePaymentGroupMemberMap"/>
                 <call-service service-name="expirePaymentGroupMember" in-map-name="expirePaymentGroupMemberMap"/>
@@ -635,7 +631,7 @@
             </iterate>
         </if-not-empty>
     </simple-method>
-    
+
     <simple-method method-name="createPaymentAndPaymentGroupForInvoices" short-description="Creates Payments, PaymentApplications and PaymentGroup for the same">
         <entity-one entity-name="PaymentMethod" value-field="paymentMethod" auto-field-map="true"/>
         <entity-one entity-name="FinAccount" value-field="finAccount" auto-field-map="false">
@@ -653,7 +649,7 @@
         </if-compare>
         <check-errors/>
         <set field="invoices" type="List"/>
-        <iterate list="parameters.invoiceIds" entry="invoiceId">  
+        <iterate list="parameters.invoiceIds" entry="invoiceId">
             <entity-one entity-name="Invoice" value-field="invoice" auto-field-map="true"/>
             <clear-field field="invoices"/>
             <set field="invoices" from-field="partyInvoices.${invoice.partyIdFrom}"/>
@@ -689,7 +685,7 @@
             <field-to-result field="errorMessage" result-name="errorMessage"/>
         </if-empty>
     </simple-method>
-    
+
     <simple-method method-name="createPaymentAndApplicationForParty" short-description="create Payment and PaymentApplications for multiple invoices for one party">
         <set field="paymentAmount" type="BigDecimal" value="0"/>
         <iterate list="parameters.invoices" entry="invoice">
@@ -748,14 +744,14 @@
         <set field="amount" type="BigDecimal" from-field="paymentAmount"/>
         <field-to-result field="amount"/>
     </simple-method>
-    
+
     <simple-method method-name="createFinAccoutnTransFromPayment" short-description="Creates a record for FinAccountTrans on creation of payment.">
         <set-service-fields service-name="createFinAccountTrans" map="parameters" to-map="createFinAccountTransMap"/>
         <set field="createFinAccountTransMap.finAccountTransTypeId" value="WITHDRAWAL"/>
         <set field="createFinAccountTransMap.partyId" from-field="parameters.organizationPartyId"/>
         <now-timestamp field="createFinAccountTransMap.transactionDate"/>
         <now-timestamp field="createFinAccountTransMap.entryDate"/>
-        <!-- set field="createFinAccountTransMap.statusId" value="CREATE"/>  --> <!-- TODO: It will uncomment when status Id field will add in FinAccountTrans Entity. -->
+        <!-- set field="createFinAccountTransMap.statusId" value="CREATE"/>--><!-- TODO: It will uncomment when status Id field will add in FinAccountTrans Entity. -->
         <set field="createFinAccountTransMap.comments" value="Pay to ${parameters.partyId} for invoice Ids - ${parameters.invoiceIds}"/>
         <call-service service-name="createFinAccountTrans" in-map-name="createFinAccountTransMap">
             <result-to-field result-name="finAccountTransId"/>
@@ -784,7 +780,7 @@
             <call-service service-name="createPaymentGroupMember" in-map-name="createPaymentGroupMemberMap"/>
         </iterate>
     </simple-method>
-    
+
     <simple-method method-name="cancelCheckRunPayments" short-description="Cancel all payments for payment group">
         <entity-and entity-name="PmtGrpMembrPaymentAndFinAcctTrans"  list="paymentGroupMemberAndTransList">
             <field-map field-name="paymentGroupId" from-field="parameters.paymentGroupId"/>
@@ -810,7 +806,7 @@
         </else>
         </if-compare>
     </simple-method>
-    
+
     <simple-method method-name="getPayments" short-description="Get list of payment">
         <set field="paymentGroupId" from-field="parameters.paymentGroupId"/>
         <if-not-empty field="paymentGroupId">
@@ -878,11 +874,11 @@
             <set-service-fields service-name="createPaymentGroupAndMember" map="parameters" to-map="createPaymentGroupAndMemberMap"/>
             <call-service service-name="createPaymentGroupAndMember" in-map-name="createPaymentGroupAndMemberMap">
                 <result-to-result result-name="paymentGroupId"/>
-            </call-service>            
+            </call-service>
         </else>
         </if-not-empty>
     </simple-method>
-    
+
     <simple-method method-name="massChangePaymentStatus" short-description="Service set status of Payments in bulk.">
         <iterate list="parameters.paymentIds" entry="paymentId">
             <set field="setPaymentStatusMap.paymentId" from-field="paymentId"/>
@@ -893,7 +889,6 @@
     </simple-method>
 
     <simple-method method-name="createPaymentFromOrder" short-description="Service auto create Payment from Order when payment does exist yet and not diabled by accountingconfig">
-        
         <entity-one value-field="orderHeader" entity-name="OrderHeader"/>
 
         <if-compare operator="equals" value="PURCHASE_ORDER" field="orderHeader.orderTypeId">
@@ -1015,7 +1010,7 @@
                 <set field="parameters.amount" from-field="orderHeader.grandTotal" />
             </else>
         </if>
-        
+
         <set field="parameters.partyIdFrom" from-field="orderRoleFrom.partyId"/>
         <set field="parameters.partyIdTo" from-field="orderRoleTo.partyId"/>
         <set field="parameters.paymentMethodTypeId" value="COMPANY_ACCOUNT"/>
@@ -1036,15 +1031,14 @@
         <field-to-result field="parameters.paymentId" result-name="paymentId"/>
         <log level="info" message="payment ${parameters.paymentId} with the not-paid status automatically created from order: ${parameters.orderId} (can be disabled in AccountingConfig.properties)"/>
     </simple-method>
-    
+
     <simple-method method-name="createMatchingPaymentApplication" short-description="Create a payment application if either the invoice of payment could be found">
-    
         <property-to-field resource="AccountingConfig" property="accounting.payment.application.autocreate" field="autoCreate" default="Y"/>
         <if-compare operator="not-equals" value="Y" field="autoCreate">
             <log level="info" message="payment application not automatically created because config is not set to Y"/>
             <return/>
         </if-compare>
-    
+
         <if-not-empty field="parameters.invoiceId">
             <entity-one value-field="invoice" entity-name="Invoice"/>
             <if-not-empty field="invoice">
@@ -1099,7 +1093,7 @@
                 </if-not-empty>
             </if-not-empty>
         </if-not-empty>
-    
+
         <if-not-empty field="parameters.paymentId">
             <entity-one value-field="payment" entity-name="Payment"/>
             <if-not-empty field="payment">
@@ -1123,21 +1117,21 @@
                     <set field="checkInvoice.invoiceId" from="invoice.invoiceId"/>
                     <call-service service-name="isInvoiceInForeignCurrency" in-map-name="checkInvoice">
                         <result-to-field result-name="isForeign"/>
-                    </call-service>                    
+                    </call-service>
                     <if-compare operator="equals" value="true" field="isForeign">
                         <if-compare-field operator="equals" field="invoiceTotal" to-field="payment.actualCurrencyAmount">
                             <if-compare-field operator="equals" field="invoice.currencyUomId" to-field="payment.actualCurrencyUomId">
                                 <set field="invoiceId" from-field="invoice.invoiceId"/>
                                 <set field="amountApplied" from-field="payment.actualCurrencyAmount"/>
-                            </if-compare-field>                
-                        </if-compare-field>                
+                            </if-compare-field>
+                        </if-compare-field>
                         <else>
                             <if-compare-field operator="equals" field="invoiceTotal" to-field="payment.amount">
                                 <if-compare-field operator="equals" field="invoice.currencyUomId" to-field="payment.currencyUomId">
                                     <set field="invoiceId" from-field="invoice.invoiceId"/>
                                     <set field="amountApplied" from-field="payment.amount"/>
-                                </if-compare-field>                
-                            </if-compare-field>                
+                                </if-compare-field>
+                            </if-compare-field>
                         </else>
                     </if-compare>
                 </iterate>
@@ -1153,16 +1147,15 @@
                 </if-not-empty>
             </if-not-empty>
         </if-not-empty>
-    
-    
+
         <if-not-empty field="createAppl.paymentId">
             <if-not-empty field="createAppl.invoiceId">
-                <call-service service-name="createPaymentApplication" in-map-name="createAppl"/>    
+                <call-service service-name="createPaymentApplication" in-map-name="createAppl"/>
                 <log level="info" message="payment application automatically created between invoiceId: ${createAppl.invoiceId} and paymentId: ${createAppl.paymentId} for the amount: ${createAppl.appliedAmount} (can be disabled in AccountingConfig.properties)"/>
             </if-not-empty>
         </if-not-empty>
     </simple-method>
-    
+
     <!-- PaymentContent -->
     <simple-method method-name="createPaymentContent" short-description="Create Content For Payment">
         <make-value value-field="newEntity" entity-name="PaymentContent"/>
diff --git a/applications/accounting/servicedef/services_billing.xml b/applications/accounting/servicedef/services_billing.xml
index ba1e87f..482fb5e 100644
--- a/applications/accounting/servicedef/services_billing.xml
+++ b/applications/accounting/servicedef/services_billing.xml
@@ -25,83 +25,63 @@
     <version>1.0</version>
 
     <!-- Billing Account Services -->
-    <service name="createBillingAccount" engine="simple"
-            location="component://accounting/script/org/ofbiz/accounting/payment/BillingServices.xml" invoke="createBillingAccount">
+    <service name="createBillingAccount" default-entity-name="BillingAccount" engine="entity-auto" invoke="create" auth="true">
         <description>Create a Billing Account</description>
         <permission-service service-name="acctgBillingAcctCheck" main-action="CREATE"/>
-        <attribute name="accountLimit" type="BigDecimal" mode="IN" optional="true"/>
-        <attribute name="accountCurrencyUomId" type="String" mode="IN" optional="true"/>
-        <attribute name="description" type="String" mode="IN" optional="true"/>
-        <attribute name="contactMechId" type="String" mode="IN" optional="true"/>
-        <attribute name="fromDate" type="Timestamp" mode="IN" optional="true"/>
-        <attribute name="thruDate" type="Timestamp" mode="IN" optional="true"/>
-        <attribute name="roleTypeId" type="String" mode="IN" optional="true"/>
-        <attribute name="partyId" type="String" mode="IN" optional="true"/>
-        <attribute name="billingAccountId" type="String" mode="OUT" optional="false"/>
+        <auto-attributes include="pk" mode="OUT" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="updateBillingAccount" engine="simple"
-            location="component://accounting/script/org/ofbiz/accounting/payment/BillingServices.xml" invoke="updateBillingAccount">
+    <service name="updateBillingAccount" default-entity-name="BillingAccount" engine="entity-auto" invoke="update" auth="true">
         <description>Update a Billing Account</description>
         <permission-service service-name="acctgBillingAcctCheck" main-action="UPDATE"/>
-        <attribute name="billingAccountId" type="String" mode="IN" optional="false"/>
-        <attribute name="accountLimit" type="BigDecimal" mode="IN" optional="true"/>
-        <attribute name="accountCurrencyUomId" type="String" mode="IN" optional="true"/>
-        <attribute name="description" type="String" mode="IN" optional="true"/>
-        <attribute name="contactMechId" type="String" mode="IN" optional="true"/>
-        <attribute name="fromDate" type="Timestamp" mode="IN" optional="true"/>
-        <attribute name="thruDate" type="Timestamp" mode="IN" optional="true"/>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="createBillingAccountRole" engine="simple"
-            location="component://accounting/script/org/ofbiz/accounting/payment/BillingServices.xml" invoke="createBillingAccountRole">
+    <service name="createBillingAccountRole" default-entity-name="BillingAccountRole" engine="entity-auto" invoke="create" auth="true">
         <description>Create a Billing Account Role</description>
         <permission-service service-name="acctgBillingAcctCheck" main-action="CREATE"/>
-        <attribute name="billingAccountId" type="String" mode="IN" optional="false"/>
-        <attribute name="partyId" type="String" mode="IN" optional="false"/>
-        <attribute name="roleTypeId" type="String" mode="IN" optional="false"/>
-        <attribute name="fromDate" type="Timestamp" mode="IN" optional="true"/>
-        <attribute name="thruDate" type="Timestamp" mode="IN" optional="true"/>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <override name="fromDate" optional="true"/>
     </service>
-    <service name="updateBillingAccountRole" engine="simple"
-            location="component://accounting/script/org/ofbiz/accounting/payment/BillingServices.xml" invoke="updateBillingAccountRole">
+    <service name="updateBillingAccountRole" default-entity-name="BillingAccountRole" engine="entity-auto" invoke="update" auth="true">
         <description>Update a Billing Account Role</description>
         <permission-service service-name="acctgBillingAcctCheck" main-action="UPDATE"/>
-        <attribute name="billingAccountId" type="String" mode="IN" optional="false"/>
-        <attribute name="partyId" type="String" mode="IN" optional="false"/>
-        <attribute name="roleTypeId" type="String" mode="IN" optional="false"/>
-        <attribute name="fromDate" type="Timestamp" mode="IN" optional="false"/>
-        <attribute name="thruDate" type="Timestamp" mode="IN" optional="false"/>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="removeBillingAccountRole" engine="simple" default-entity-name="BillingAccountRole"
-            location="component://accounting/script/org/ofbiz/accounting/payment/BillingServices.xml" invoke="removeBillingAccountRole">
+    <service name="removeBillingAccountRole" default-entity-name="BillingAccountRole" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove a Billing Account Role</description>
         <permission-service service-name="acctgBillingAcctCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
-    <service name="createBillingAccountTerm" engine="simple"
-            location="component://accounting/script/org/ofbiz/accounting/payment/BillingServices.xml" invoke="createBillingAccountTerm">
+    <service name="createBillingAccountAndRole" engine="group" auth="true">
+        <group>
+            <invoke name="createBillingAccount" mode="sync" result-to-context="true"/>
+            <invoke name="createBillingAccountRole" mode="sync" parameters="optional"/>
+        </group>
+        <override name="billingAccountId" optional="true"/>
+    </service>
+    <service name="createBillingAccountTerm" default-entity-name="BillingAccountTerm" engine="entity-auto" invoke="create" auth="true">
         <description>Create a Billing Account Term</description>
         <permission-service service-name="acctgBillingAcctCheck" main-action="CREATE"/>
-        <attribute name="billingAccountId" type="String" mode="IN" optional="false"/>
-        <attribute name="termTypeId" type="String" mode="IN" optional="false"/>
-        <attribute name="termValue" type="BigDecimal" mode="IN" optional="false"/>
-        <attribute name="uomId" type="String" mode="IN" optional="true"/>
-        <attribute name="billingAccountTermId" type="String" mode="OUT" optional="false"/>
+        <auto-attributes include="pk" mode="OUT" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <override name="termTypeId" optional="false"/>
+        <override name="billingAccountId" optional="false"/>
     </service>
-    <service name="updateBillingAccountTerm" engine="simple"
-            location="component://accounting/script/org/ofbiz/accounting/payment/BillingServices.xml" invoke="updateBillingAccountTerm">
+    <service name="updateBillingAccountTerm" default-entity-name="BillingAccountTerm" engine="entity-auto" invoke="update" auth="true">
         <description>Update a Billing Account Term</description>
         <permission-service service-name="acctgBillingAcctCheck" main-action="UPDATE"/>
-        <attribute name="billingAccountTermId" type="String" mode="IN" optional="false"/>
-        <attribute name="billingAccountId" type="String" mode="IN" optional="true"/>
-        <attribute name="termTypeId" type="String" mode="IN" optional="true"/>
-        <attribute name="termValue" type="BigDecimal" mode="IN" optional="true"/>
-        <attribute name="uomId" type="String" mode="IN" optional="true"/>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+        <auto-attributes include="nonpk" mode="IN" optional="true"/>
+        <override name="termTypeId" optional="false"/>
+        <override name="billingAccountId" optional="false"/>
     </service>
-    <service name="removeBillingAccountTerm" engine="simple"
-            location="component://accounting/script/org/ofbiz/accounting/payment/BillingServices.xml" invoke="removeBillingAccountTerm">
+    <service name="removeBillingAccountTerm" default-entity-name="BillingAccountTerm" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove a Billing Account Term</description>
         <permission-service service-name="acctgBillingAcctCheck" main-action="DELETE"/>
-        <attribute name="billingAccountTermId" type="String" mode="IN" optional="false"/>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
     <service name="calcBillingAccountBalance" engine="java"
             location="org.ofbiz.accounting.payment.BillingAccountWorker" invoke="calcBillingAccountBalance">
diff --git a/applications/accounting/servicedef/services_cost.xml b/applications/accounting/servicedef/services_cost.xml
index dc8969a..fc3b4dd 100644
--- a/applications/accounting/servicedef/services_cost.xml
+++ b/applications/accounting/servicedef/services_cost.xml
@@ -24,32 +24,28 @@
     <vendor>OFBiz</vendor>
     <version>1.0</version>
 
-    <service name="createCostComponentCalc" default-entity-name="CostComponentCalc" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/cost/CostServices.xml" invoke="createCostComponentCalc" auth="true">
+    <service name="createCostComponentCalc" default-entity-name="CostComponentCalc" engine="entity-auto" invoke="create" auth="true">
         <description>Create a CostComponentCalc</description>
         <permission-service service-name="acctgCostPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <auto-attributes include="pk" mode="OUT" optional="true"/>
     </service>
 
-    <service name="updateCostComponentCalc" default-entity-name="CostComponentCalc" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/cost/CostServices.xml" invoke="updateCostComponentCalc" auth="true">
+    <service name="updateCostComponentCalc" default-entity-name="CostComponentCalc" engine="entity-auto" invoke="update" auth="true">
         <description>Update a CostComponentCalc</description>
         <permission-service service-name="acctgCostPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
 
-    <service name="removeCostComponentCalc" default-entity-name="CostComponentCalc" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/cost/CostServices.xml" invoke="removeCostComponentCalc" auth="true">
+    <service name="removeCostComponentCalc" default-entity-name="CostComponentCalc" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove a CostComponentCalc</description>
         <permission-service service-name="acctgCostPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
 
-    <service name="createWorkEffortCostCalc" default-entity-name="WorkEffortCostCalc" engine="simple"
-        location="component://accounting/script/org/ofbiz/accounting/cost/CostServices.xml" invoke="createWorkEffortCostCalc" auth="true">
+    <service name="createWorkEffortCostCalc" default-entity-name="WorkEffortCostCalc" engine="entity-auto" invoke="create" auth="true">
         <description>Create a WorkEffortCostCalc entry</description>
         <permission-service service-name="acctgCostPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -57,8 +53,7 @@
         <override name="fromDate" optional="true"/>
     </service>
 
-    <service name="removeWorkEffortCostCalc" default-entity-name="WorkEffortCostCalc" engine="simple"
-        location="component://accounting/script/org/ofbiz/accounting/cost/CostServices.xml" invoke="removeWorkEffortCostCalc" auth="true">
+    <service name="removeWorkEffortCostCalc" default-entity-name="WorkEffortCostCalc" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove a WorkEffortCostCalc entry</description>
         <permission-service service-name="acctgCostPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
diff --git a/applications/accounting/servicedef/services_fixedasset.xml b/applications/accounting/servicedef/services_fixedasset.xml
index 20c3da8..ca96044 100644
--- a/applications/accounting/servicedef/services_fixedasset.xml
+++ b/applications/accounting/servicedef/services_fixedasset.xml
@@ -25,16 +25,14 @@
     <version>1.0</version>
 
     <!-- Fixed Asset  -->
-    <service name="createFixedAsset" default-entity-name="FixedAsset" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="createFixedAsset" auth="true">
+    <service name="createFixedAsset" default-entity-name="FixedAsset" engine="entity-auto" invoke="create" auth="true">
         <description>Create a Fixed Asset</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="pk" mode="INOUT" optional="true"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <override name="fixedAssetTypeId" optional="false"/>
     </service>
-    <service name="updateFixedAsset" default-entity-name="FixedAsset" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="updateFixedAsset" auth="true">
+    <service name="updateFixedAsset" default-entity-name="FixedAsset" engine="entity-auto" invoke="update" auth="true">
         <description>Update a Fixed Asset</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -43,51 +41,34 @@
     </service>
 
     <!-- Product to Fixed Asset maintenance -->
-    <service name="addFixedAssetProduct" default-entity-name="FixedAssetProduct" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="addFixedAssetProduct" auth="true">
+    <service name="addFixedAssetProduct" default-entity-name="FixedAssetProduct" engine="entity-auto" invoke="create" auth="true">
         <description>Add Product To Fixed Asset</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <override name="fromDate" optional="true"/>
     </service>
-
-    <service name="updateFixedAssetProduct" default-entity-name="FixedAssetProduct" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="updateFixedAssetProduct" auth="true">
+    <service name="updateFixedAssetProduct" default-entity-name="FixedAssetProduct" engine="entity-auto" invoke="update" auth="true">
         <description>Update the Product to Fixed Asset information</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-
-    <service name="removeFixedAssetProduct" default-entity-name="FixedAssetProduct" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="removeFixedAssetProduct" auth="true">
+    <service name="removeFixedAssetProduct" default-entity-name="FixedAssetProduct" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove Product From Fixed Asset</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
 
-    <!-- TO BE REMOVED : Fixed Asset calendar
-    <service name="updateFixedAssetCalendar" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="updateFixedAssetCalendar" auth="true">
-        <description>Update the Capacity available of Calendar of a Fixed Asset information</description>
-        <attribute name="fixedAssetId" type="Id" mode="IN" optional="false"/>
-        <attribute name="exceptionDateStartTime" type="Timestamp" mode="IN" optional="false"/>
-        <attribute name="exceptionCapacity" type="Timestamp" mode="IN" optional="false"/>
-        <attribute name="capacity" type="BigDecimal" mode="IN" optional="true"/>
-    </service>
-    -->
-
     <!-- FixedAssetStdCost  -->
-    <service name="createFixedAssetStdCost" default-entity-name="FixedAssetStdCost" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="createFixedAssetStdCost" auth="true">
+    <!-- TODO: we should cancel the existing costs of the same type with seca -->
+    <service name="createFixedAssetStdCost" default-entity-name="FixedAssetStdCost" engine="entity-auto" invoke="create" auth="true">
         <description>Create a Fixed Asset Standard Cost</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="updateFixedAssetStdCost" default-entity-name="FixedAssetStdCost" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="updateFixedAssetStdCost" auth="true">
+    <service name="updateFixedAssetStdCost" default-entity-name="FixedAssetStdCost" engine="entity-auto" invoke="update" auth="true">
         <description>Update a Fixed Asset Standard Cost</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -102,44 +83,38 @@
     </service>
 
     <!-- FixedAssetIdent -->
-    <service name="createFixedAssetIdent" default-entity-name="FixedAssetIdent" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="createFixedAssetIdent" auth="true">
+    <service name="createFixedAssetIdent" default-entity-name="FixedAssetIdent" engine="entity-auto" invoke="create" auth="true">
         <description>Create a Fixed Asset Identification</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="updateFixedAssetIdent" default-entity-name="FixedAssetIdent" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="updateFixedAssetIdent" auth="true">
+    <service name="updateFixedAssetIdent" default-entity-name="FixedAssetIdent" engine="entity-auto" invoke="update" auth="true">
         <description>Update a Fixed Asset Identification</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="removeFixedAssetIdent" default-entity-name="FixedAssetIdent" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="removeFixedAssetIdent" auth="true">
+    <service name="removeFixedAssetIdent" default-entity-name="FixedAssetIdent" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove a Fixed Asset Identification</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
     <!-- Equipment Registration Create/Update/Delete-->
-    <service name="createFixedAssetRegistration" default-entity-name="FixedAssetRegistration" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="createFixedAssetRegistration" auth="true">
+    <service name="createFixedAssetRegistration" default-entity-name="FixedAssetRegistration" engine="entity-auto" invoke="create" auth="true">
         <description>Create a Fixed Asset Registration</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <override name="fromDate" optional="true"/>
     </service>
-    <service name="updateFixedAssetRegistration" default-entity-name="FixedAssetRegistration" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="updateFixedAssetRegistration" auth="true">
+    <service name="updateFixedAssetRegistration" default-entity-name="FixedAssetRegistration" engine="entity-auto" invoke="update" auth="true">
         <description>Update a Fixed Asset Registration</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="deleteFixedAssetRegistration" default-entity-name="FixedAssetRegistration" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="deleteFixedAssetRegistration" auth="true">
+    <service name="deleteFixedAssetRegistration" default-entity-name="FixedAssetRegistration" engine="entity-auto" invoke="delete" auth="true">
         <description>Delete a Fixed Asset Registration</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -164,8 +139,7 @@
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <attribute name="oldStatusId" type="String" mode="OUT" optional="false"/>
     </service>
-    <service name="deleteFixedAssetMaint" default-entity-name="FixedAssetMaint" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="deleteFixedAssetMaint" auth="true">
+    <service name="deleteFixedAssetMaint" default-entity-name="FixedAssetMaint" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove a Fixed Asset Maintenance</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -192,8 +166,7 @@
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="deleteFixedAssetMeter" default-entity-name="FixedAssetMeter" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="deleteFixedAssetMeter" auth="true">
+    <service name="deleteFixedAssetMeter" default-entity-name="FixedAssetMeter" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove a Fixed Asset Maintenance Meter</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -209,33 +182,27 @@
         <attribute name="orderItemSeqId" type="String" mode="IN" optional="true"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="deleteFixedAssetMaintOrder" default-entity-name="FixedAssetMaintOrder" engine="simple"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="deleteFixedAssetMaintOrder" auth="true">
+    <service name="deleteFixedAssetMaintOrder" default-entity-name="FixedAssetMaintOrder" engine="entity-auto" invoke="delete" auth="true">
         <description>Remove a Fixed Asset Maintenance Order</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
     </service>
 
     <!-- =========Party Fixed Asset Assignment Services========= -->
-    <service name="createPartyFixedAssetAssignment" engine="simple" default-entity-name="PartyFixedAssetAssignment"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="createPartyFixedAssetAssignment" auth="true">
+    <service name="createPartyFixedAssetAssignment" default-entity-name="PartyFixedAssetAssignment" engine="entity-auto" invoke="create" auth="true">
         <description>Add Party to a Fixed Asset</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
         <override name="fromDate" optional="true"/>
     </service>
-
-    <service name="updatePartyFixedAssetAssignment" engine="simple" default-entity-name="PartyFixedAssetAssignment"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="updatePartyFixedAssetAssignment" auth="true">
+    <service name="updatePartyFixedAssetAssignment" default-entity-name="PartyFixedAssetAssignment" engine="entity-auto" invoke="update" auth="true">
         <description>Update Party to Fixed Asset</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-
-    <service name="deletePartyFixedAssetAssignment" engine="simple" default-entity-name="PartyFixedAssetAssignment"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="deletePartyFixedAssetAssignment" auth="true">
+    <service name="deletePartyFixedAssetAssignment" default-entity-name="PartyFixedAssetAssignment" engine="entity-auto" invoke="delete" auth="true">
         <description>Delete Party to Fixed Asset</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -248,17 +215,17 @@
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="deleteFixedAssetDepMethod" default-entity-name="FixedAssetDepMethod" engine="entity-auto" invoke="delete" auth="true">
-        <description>Delete a Fixed Asset Depreciation Method</description>
-        <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
-        <auto-attributes include="pk" mode="IN" optional="false"/>
-    </service>
     <service name="updateFixedAssetDepMethod" default-entity-name="FixedAssetDepMethod" engine="entity-auto" invoke="update" auth="true">
         <description>Create a Fixed Asset Depreciation Method</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
+    <service name="deleteFixedAssetDepMethod" default-entity-name="FixedAssetDepMethod" engine="entity-auto" invoke="delete" auth="true">
+        <description>Delete a Fixed Asset Depreciation Method</description>
+        <permission-service service-name="fixedAssetPermissionCheck" main-action="DELETE"/>
+        <auto-attributes include="pk" mode="IN" optional="false"/>
+    </service>
     <service name="checkUpdateFixedAssetDepreciation" default-entity-name="AcctgTrans" engine="simple"
               location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="checkUpdateFixedAssetDepreciation" auth="true">
         <description>If the accounting transaction is a depreciation transaction for a fixed asset, update the depreciation amount in the FixedAsset entity.</description>
@@ -300,13 +267,13 @@
         <attribute name="nextDepreciationAmount" type="BigDecimal" mode="OUT" optional="true"/>
         <attribute name="plannedPastDepreciationTotal" type="BigDecimal" mode="OUT" optional="true"/>
     </service>
-    <service name="createFixedAssetTypeGlAccount" engine="simple" default-entity-name="FixedAssetTypeGlAccount"
-                location="component://accounting/script/org/ofbiz/accounting/fixedasset/FixedAssetServices.xml" invoke="createFixedAssetTypeGlAccount" auth="true">
+
+    <service name="createFixedAssetTypeGlAccount" default-entity-name="FixedAssetTypeGlAccount" engine="entity-auto" invoke="create" auth="true">
         <description>Create a Fixed Asset Type Gl Account Mapping</description>
         <permission-service service-name="fixedAssetPermissionCheck" main-action="CREATE"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
-        <attribute name="fixedAssetTypeId" type="String" mode="IN" optional="true"/>
-        <attribute name="fixedAssetId" type="String" mode="IN" optional="true"/>
+        <attribute name="fixedAssetTypeId" type="String" mode="IN" optional="true" default-value="_NA_"/>
+        <attribute name="fixedAssetId" type="String" mode="IN" optional="true" default-value="_NA_"/>
         <attribute name="organizationPartyId" type="String" mode="IN" optional="false"/>
     </service>
     <service name="deleteFixedAssetTypeGlAccount" default-entity-name="FixedAssetTypeGlAccount" engine="entity-auto" invoke="delete" auth="true">
diff --git a/applications/accounting/servicedef/services_invoice.xml b/applications/accounting/servicedef/services_invoice.xml
index a17ba9b..ffc53d0 100644
--- a/applications/accounting/servicedef/services_invoice.xml
+++ b/applications/accounting/servicedef/services_invoice.xml
@@ -298,8 +298,7 @@
         <attribute name="invoicedTotal" type="BigDecimal" mode="OUT" optional="false"/>
     </service>
 
-    <service name="updateInvoiceItemType" engine="simple" default-entity-name="InvoiceItemType"
-        location="component://accounting/script/org/ofbiz/accounting/invoice/InvoiceServices.xml" invoke="updateInvoiceItemType">
+    <service name="updateInvoiceItemType" default-entity-name="InvoiceItemType" engine="entity-auto" invoke="update">
         <description>Update Invoice Item Type Record</description>
         <auto-attributes mode="IN" include="pk" optional="false"/>
         <auto-attributes mode="IN" include="nonpk" optional="true"/>
@@ -309,14 +308,14 @@
         <description>Scheduled service to generate Invoice from an existing Invoice</description>
         <attribute name="recurrenceInfoId" mode="IN" type="String" optional="false"/>
     </service>
-    
+
     <service name="cancelInvoice" engine="simple"
             location="component://accounting/script/org/ofbiz/accounting/invoice/InvoiceServices.xml" invoke="cancelInvoice">
         <description>Cancel Invoice</description>
         <attribute name="invoiceId" type="String" mode="IN" optional="false"/>
         <attribute name="invoiceTypeId" type="String" mode="OUT" optional="false"/>
     </service>
-    
+
     <service name="getInvoiceRunningTotal" engine="simple"
             location="component://accounting/script/org/ofbiz/accounting/invoice/InvoiceServices.xml" invoke="getInvoiceRunningTotal" auth="true">
         <description>calculate running total for selected Invoices</description>
@@ -324,7 +323,7 @@
         <attribute name="organizationPartyId" type="String" mode="IN" optional="true"/>
         <attribute name="invoiceRunningTotal" type="String" mode="OUT" optional="false"/>
     </service>
-    
+
     <service name="addtax" engine="simple" 
         location="component://accounting/script/org/ofbiz/accounting/invoice/InvoiceServices.xml" invoke="addtax">
         <description>Call Tax Calculate Service</description>
diff --git a/applications/accounting/webapp/accounting/WEB-INF/controller.xml b/applications/accounting/webapp/accounting/WEB-INF/controller.xml
index 0586e9e..5c698b7 100644
--- a/applications/accounting/webapp/accounting/WEB-INF/controller.xml
+++ b/applications/accounting/webapp/accounting/WEB-INF/controller.xml
@@ -62,6 +62,12 @@
         <response name="success" type="view" value="EditBillingAccount"/>
         <response name="error" type="view" value="EditBillingAccount"/>
     </request-map>
+    <request-map uri="createBillingAccountAndRole">
+        <security https="true" auth="true"/>
+        <event type="service" invoke="createBillingAccountAndRole"/>
+        <response name="success" type="view" value="EditBillingAccount"/>
+        <response name="error" type="view" value="EditBillingAccount"/>
+    </request-map>
     <request-map uri="updateBillingAccount">
         <security https="true" auth="true"/>
         <event type="service" invoke="updateBillingAccount"/>
diff --git a/applications/accounting/widget/BillingAccountForms.xml b/applications/accounting/widget/BillingAccountForms.xml
index c67fd73..701a969 100644
--- a/applications/accounting/widget/BillingAccountForms.xml
+++ b/applications/accounting/widget/BillingAccountForms.xml
@@ -28,8 +28,6 @@
                 <field-map field-name="inputFields" from-field="parameters"/>
                 <field-map field-name="entityName" value="BillingAccount"/>
                 <field-map field-name="orderBy" value="billingAccountId"/>
-                <field-map field-name="viewIndex" from-field="viewIndex"/>
-                <field-map field-name="viewSize" from-field="viewSize"/>
             </service>
         </actions>
         <field name="billingAccountId" widget-style="buttontext">
@@ -87,10 +85,10 @@
             <set field="paidInvoice" value="${groovy: org.ofbiz.accounting.invoice.InvoiceWorker.getInvoiceNotApplied(delegator,invoiceId).compareTo(java.math.BigDecimal.ZERO)==0}" type="Boolean"/>
             <set field="amountToApply" value="${groovy:
                 import java.text.NumberFormat;
-                return(NumberFormat.getNumberInstance(context.get(&quot;locale&quot;)).format(org.ofbiz.accounting.invoice.InvoiceWorker.getInvoiceNotApplied(delegator,invoiceId)));}"/>
+                return(NumberFormat.getNumberInstance(locale).format(org.ofbiz.accounting.invoice.InvoiceWorker.getInvoiceNotApplied(delegator,invoiceId)));}"/>
             <set field="total" value="${groovy:
                 import java.text.NumberFormat;
-                return(NumberFormat.getNumberInstance(context.get(&quot;locale&quot;)).format(org.ofbiz.accounting.invoice.InvoiceWorker.getInvoiceTotal(delegator,invoiceId)));}"/>
+                return(NumberFormat.getNumberInstance(locale).format(org.ofbiz.accounting.invoice.InvoiceWorker.getInvoiceTotal(delegator,invoiceId)));}"/>
         </row-actions>
         <field name="billingAccountId"><hidden/></field>
         <field name="invoiceId" widget-style="buttontext">
@@ -121,27 +119,23 @@
         <actions>
             <set field="availableBalance" value="${groovy:billingAccount != null ? org.ofbiz.order.order.OrderReadHelper.getBillingAccountBalance(billingAccount) : 0}" type="BigDecimal"/>
         </actions>
-        <alt-target use-when="billingAccount==null" target="createBillingAccount"/>
+        <alt-target use-when="billingAccount==null" target="createBillingAccountAndRole"/>
         <auto-fields-service service-name="updateBillingAccount" map-name="billingAccount"/>
-
         <field name="description"><text size="60"/></field>
-
+        <field use-when="billingAccount==null" name="billingAccountId"><hidden/></field>
         <field use-when="billingAccount!=null" name="billingAccountId" tooltip="${uiLabelMap.CommonNotModifRecreat}"><display/></field>
-
-        <field use-when="partyId != null" name="partyId"><hidden/></field>
-        <field use-when="roleTypeId != null" name="roleTypeId"><hidden/></field>
-        <field name="partyId"  use-when="partyId == null" title="${uiLabelMap.AccountingPartyBilledTo}"><lookup target-form-name="LookupPartyName"/></field>
-        <field use-when="roleTypeId == null" name="roleTypeId"><hidden value="BILL_TO_CUSTOMER"/></field>
-
+        <field name="partyId" use-when="billingAccount != null" ><display/></field>
+        <field name="partyId" use-when="billingAccount == null" title="${uiLabelMap.AccountingPartyBilledTo}" required-field="true"><lookup target-form-name="LookupPartyName"/></field>
+        <field name="roleTypeId"><hidden/></field>
         <field name="accountCurrencyUomId">
             <drop-down allow-empty="false" no-current-selected-key="${defaultOrganizationPartyCurrencyUomId}">
-                <entity-options key-field-name="uomId" description="${description} - ${abbreviation}" entity-name="Uom">
+                <entity-options key-field-name="uomId" description="${abbreviation} - ${description}" entity-name="Uom">
                     <entity-constraint name="uomTypeId" operator="equals" value="CURRENCY_MEASURE"/>
                     <entity-order-by field-name="description"/>
                 </entity-options>
             </drop-down>
         </field>
-        <field name="contactMechId" tooltip="${uiLabelMap.AccountingBillingContactMechIdMessage}">
+        <field name="contactMechId" tooltip="${uiLabelMap.AccountingBillingContactMechIdMessage}" use-when="billingAccount != null">
             <drop-down>
                 <entity-options entity-name="BillingAccountRoleAndAddress" description="[${partyId}][${contactMechId}] ${toName}, ${attnName}, ${address1}, ${stateProvinceGeoId} ${postalCode}" key-field-name="contactMechId" filter-by-date="true">
                     <entity-constraint name="billingAccountId" env-name="billingAccountId"/>
diff --git a/applications/accounting/widget/BillingAccountScreens.xml b/applications/accounting/widget/BillingAccountScreens.xml
index e9f4f73..29b86bc 100644
--- a/applications/accounting/widget/BillingAccountScreens.xml
+++ b/applications/accounting/widget/BillingAccountScreens.xml
@@ -126,8 +126,12 @@
                 <property-to-field field="defaultCurrencyUomId" resource="general" property="currency.uom.id.default" default="USD"/>
                 <set field="billingAccountId" from-field="parameters.billingAccountId"/>
                 <entity-one entity-name="BillingAccount" value-field="billingAccount"/>
-                <set field="partyId" from-field="parameters.partyId"/>
-                <set field="roleTypeId" from-field="parameters.roleTypeId"/>
+                <entity-and entity-name="BillingAccountRole" list="billingAccountRolesCustomer" filter-by-date="true">
+                    <field-map field-name="billingAccountId" from-field="billingAccount.billingAccountId"/>
+                    <field-map field-name="roleTypeId" value="BILL_TO_CUSTOMER"/>
+                </entity-and>
+                <set field="partyId" from-field="parameters.partyId" default-value="${billingAccountRolesCustomer[0].partyId}"/>
+                <set field="roleTypeId" from-field="parameters.roleTypeId" default-value="BILL_TO_CUSTOMER"/>
             </actions>
             <widgets>
                 <decorator-screen name="CommonBillingAccountDecorator" location="${parameters.billingAccountDecoratorLocation}">
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/src/org/ofbiz/order/order/OrderLookupServices.java b/applications/order/src/org/ofbiz/order/order/OrderLookupServices.java
index 669145e..c8614be 100644
--- a/applications/order/src/org/ofbiz/order/order/OrderLookupServices.java
+++ b/applications/order/src/org/ofbiz/order/order/OrderLookupServices.java
@@ -591,6 +591,7 @@
                 eli = EntityQuery.use(delegator)
                         .select(fieldsToSelect)
                         .from(dve)
+                        .where(cond)
                         .orderBy(orderBy)
                         .distinct() // set distinct on so we only get one row per order
                         .maxRows(highIndex)
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/order/webapp/ordermgr/entry/checkoutshippingaddress.ftl b/applications/order/webapp/ordermgr/entry/checkoutshippingaddress.ftl
index a29d2d7..ba324f6 100644
--- a/applications/order/webapp/ordermgr/entry/checkoutshippingaddress.ftl
+++ b/applications/order/webapp/ordermgr/entry/checkoutshippingaddress.ftl
@@ -55,6 +55,7 @@
 </script>
 <#assign cart = shoppingCart!/>
 <form method="post" name="checkoutInfoForm" style="margin:0;">
+  <fieldset>
     <input type="hidden" name="checkoutpage" value="shippingaddress"/>
     <div class="screenlet" style="height: 100%;">
         <div class="screenlet-title-bar">
@@ -133,6 +134,7 @@
             ${screens.render("component://order/widget/ordermgr/OrderEntryOrderScreens.xml#customertaxinfo")}
         </div>
     </div>
+  </fieldset>
 </form>
 
 <table width="100%">
diff --git a/applications/order/webapp/ordermgr/order/findOrders.ftl b/applications/order/webapp/ordermgr/order/findOrders.ftl
index 0fd0515..eef3215 100644
--- a/applications/order/webapp/ordermgr/order/findOrders.ftl
+++ b/applications/order/webapp/ordermgr/order/findOrders.ftl
@@ -148,6 +148,11 @@
                 <td width='5%'>&nbsp;</td>
                 <td align='left'><input type='text' name='orderId'/></td>
               </tr>
+              <tr>
+                <td width='25%' align='right' class='label'>${uiLabelMap.OrderOrderName}</td>
+                <td width='5%'>&nbsp;</td>
+                <td align='left'><input type='text' name='orderName'/></td>
+              </tr>
              <tr>
                 <td width='25%' align='right' class='label'>${uiLabelMap.OrderExternalId}</td>
                 <td width='5%'>&nbsp;</td>
@@ -589,6 +594,7 @@
           </td>
           <td width="5%">${uiLabelMap.OrderOrderType}</td>
           <td width="5%">${uiLabelMap.OrderOrderId}</td>
+          <td width="10 %">${uiLabelMap.OrderOrderName}</td>
           <td width="20%">${uiLabelMap.PartyName}</td>
           <td width="5%" align="right">${uiLabelMap.OrderSurvey}</td>
           <td width="5%" align="right">${uiLabelMap.OrderItemsOrdered}</td>
@@ -625,6 +631,11 @@
               </td>
               <td>${orderType.get("description",locale)?default(orderType.orderTypeId?default(""))}</td>
               <td><a href="<@ofbizUrl>orderview?orderId=${orderHeader.orderId}</@ofbizUrl>" class='buttontext'>${orderHeader.orderId}</a></td>
+              <#if orderHeader.orderName?has_content>
+                <td><a href="<@ofbizUrl>orderview?orderId=${orderHeader.orderId}</@ofbizUrl>" class='buttontext'>${orderHeader.orderName}</a></td>
+              <#else>  
+                <td></td>
+              </#if>  
               <td>
                 <div>
                   <#if displayParty?has_content>
diff --git a/applications/party/data/PartyTypeData.xml b/applications/party/data/PartyTypeData.xml
index 3d287e3..9ee804e 100644
--- a/applications/party/data/PartyTypeData.xml
+++ b/applications/party/data/PartyTypeData.xml
@@ -303,7 +303,7 @@
     <PartyRelationshipType description="" hasTable="N" parentTypeId="" partyRelationshipName="Partner" partyRelationshipTypeId="PARTNERSHIP" roleTypeIdValidFrom="" roleTypeIdValidTo=""/>
     <PartyRelationshipType description="" hasTable="N" parentTypeId="" partyRelationshipName="Sales Affiliate" partyRelationshipTypeId="SALES_AFFILIATE" roleTypeIdValidFrom="" roleTypeIdValidTo=""/>
     <PartyRelationshipType description="" hasTable="N" parentTypeId="" partyRelationshipName="Spouse" partyRelationshipTypeId="SPOUSE" roleTypeIdValidFrom="" roleTypeIdValidTo=""/>
-    <PartyRelationshipType description="" hasTable="N" parentTypeId="" partyRelationshipName="Supplier" partyRelationshipTypeId="SUPPLIER_REL" roleTypeIdValidFrom="" roleTypeIdValidTo=""/>
+    <PartyRelationshipType description="" hasTable="Y" parentTypeId="" partyRelationshipName="Supplier" partyRelationshipTypeId="SUPPLIER_REL" roleTypeIdValidFrom="" roleTypeIdValidTo=""/>
     <PartyRelationshipType description="" hasTable="N" parentTypeId="" partyRelationshipName="Web Master" partyRelationshipTypeId="WEB_MASTER_ASSIGNMEN" roleTypeIdValidFrom="" roleTypeIdValidTo=""/>
     <PartyRelationshipType description="" hasTable="N" parentTypeId="" partyRelationshipName="Account owned by" partyRelationshipTypeId="ACCOUNT" roleTypeIdValidFrom="" roleTypeIdValidTo=""/>
     <PartyRelationshipType description="" hasTable="N" parentTypeId="" partyRelationshipName="Assistant" partyRelationshipTypeId="ASSISTANT" roleTypeIdValidFrom="" roleTypeIdValidTo=""/>
@@ -372,7 +372,10 @@
     <StatusValidChange condition="" statusId="COM_ROLE_READ" statusIdTo="COM_ROLE_COMPLETED" transitionName="Completed"/>
 
     <StatusType description="Party Relationship" hasTable="N" parentTypeId="" statusTypeId="PARTY_REL_STATUS"/>
-
+    <StatusItem description="Created" sequenceId="01" statusCode="CREATED" statusId="PARTYREL_CREATED" statusTypeId="PARTY_REL_STATUS"/>
+    <StatusItem description="Expired" sequenceId="02" statusCode="EXPIRED" statusId="PARTYREL_EXPIRED" statusTypeId="PARTY_REL_STATUS"/>
+    <StatusValidChange condition="" statusId="PARTYREL_CREATED" statusIdTo="PARTYREL_EXPIRED" transitionName="Expired"/>
+    
     <StatusType description="Party Invitation" hasTable="N" parentTypeId="" statusTypeId="PARTY_INV_STATUS"/>
     <StatusItem description="Invitation Sent" sequenceId="01" statusCode="SENT" statusId="PARTYINV_SENT" statusTypeId="PARTY_INV_STATUS"/>
     <StatusItem description="Invitation Pending" sequenceId="02" statusCode="PENDING" statusId="PARTYINV_PENDING" statusTypeId="PARTY_INV_STATUS"/>
diff --git a/applications/product/src/org/ofbiz/product/category/CatalogUrlServlet.java b/applications/product/src/org/ofbiz/product/category/CatalogUrlServlet.java
index 691e184..4ad28bf 100644
--- a/applications/product/src/org/ofbiz/product/category/CatalogUrlServlet.java
+++ b/applications/product/src/org/ofbiz/product/category/CatalogUrlServlet.java
@@ -36,6 +36,7 @@
 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.util.EntityQuery;
 
 /**
@@ -81,24 +82,26 @@
         String pathInfo = request.getPathInfo();
         List<String> pathElements = StringUtil.split(pathInfo, "/");
 
-        // look for productId
         String productId = null;
+        String categoryId = null;
         try {
             String lastPathElement = pathElements.get(pathElements.size() - 1);
-            if (lastPathElement.startsWith("p_") || EntityQuery.use(delegator).from("Product").where("productId", lastPathElement).cache(true).queryOne() != null) {
-                if (lastPathElement.startsWith("p_")) {
-                    productId = lastPathElement.substring(2);
+            if (lastPathElement.startsWith("p_")) {
+                productId = lastPathElement.substring(2);
+            } else {
+                GenericValue productCategory =  EntityQuery.use(delegator).from("ProductCategory").where("productCategoryId", lastPathElement).cache(true).queryOne();
+                if (UtilValidate.isNotEmpty(productCategory)) {
+                    categoryId = lastPathElement;
                 } else {
                     productId = lastPathElement;
                 }
-                pathElements.remove(pathElements.size() - 1);
             }
+            pathElements.remove(pathElements.size() - 1);
         } catch (GenericEntityException e) {
-            Debug.logError(e, "Error looking up product info for ProductUrl with path info [" + pathInfo + "]: " + e.toString(), module);
+            Debug.logError(e, "Error in looking up ProductUrl or CategoryUrl with path info [" + pathInfo + "]: " + e.toString(), module);
         }
 
         // get category info going with the IDs that remain
-        String categoryId = null;
         if (pathElements.size() == 1) {
             CategoryWorker.setTrail(request, pathElements.get(0), null);
             categoryId = pathElements.get(0);
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/catalog/promo/EditProductPromoRules.ftl b/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
index f98d6ad..570a278 100644
--- a/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
+++ b/applications/product/webapp/catalog/promo/EditProductPromoRules.ftl
@@ -204,12 +204,12 @@
         <div>${uiLabelMap.ProductNoConditionProducts}</div>
       </#if>
                 <div>
-                  <form method="post" action="<@ofbizUrl>createProductPromoProduct</@ofbizUrl>">
+                  <form method="post" action="<@ofbizUrl>createProductPromoProduct</@ofbizUrl>" name="createProductPromoProductConditions">
                     <input type="hidden" name="productPromoId" value="${productPromoId}" />
                     <input type="hidden" name="productPromoRuleId" value="${productPromoCond.productPromoRuleId}" />
                     <input type="hidden" name="productPromoActionSeqId" value="_NA_" />
                     <input type="hidden" name="productPromoCondSeqId" value="${productPromoCond.productPromoCondSeqId}" />
-                    ${uiLabelMap.ProductProductId}: <input type="text" size="20" maxlength="20" name="productId" value=""/>
+                    <@htmlTemplate.lookupField formName="createProductPromoProductConditions" name="productId" id="productId" fieldFormName="LookupProduct"/>
                     <select name="productPromoApplEnumId">
       <#list productPromoApplEnums as productPromoApplEnum>
                       <option value="${productPromoApplEnum.enumId}">${productPromoApplEnum.get("description",locale)}</option>
@@ -388,12 +388,12 @@
         <div>${uiLabelMap.ProductNoActionProducts}</div>
       </#if>
                 <div>
-                  <form method="post" action="<@ofbizUrl>createProductPromoProduct</@ofbizUrl>">
+                  <form method="post" action="<@ofbizUrl>createProductPromoProduct</@ofbizUrl>" name="createProductPromoProductActions">>
                     <input type="hidden" name="productPromoId" value="${productPromoId}" />
                     <input type="hidden" name="productPromoRuleId" value="${productPromoAction.productPromoRuleId}" />
                     <input type="hidden" name="productPromoActionSeqId" value="${productPromoAction.productPromoActionSeqId}" />
                     <input type="hidden" name="productPromoCondSeqId" value="_NA_" />
-                    ${uiLabelMap.ProductProductId}: <input type="text" size="20" maxlength="20" name="productId" value=""/>
+                    <@htmlTemplate.lookupField formName="createProductPromoProductActions" name="productId" id="productId" fieldFormName="LookupProduct"/>
                     <select name="productPromoApplEnumId">
       <#list productPromoApplEnums as productPromoApplEnum>
                       <option value="${productPromoApplEnum.enumId}">${productPromoApplEnum.get("description",locale)}</option>
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/applications/product/widget/catalog/ProductForms.xml b/applications/product/widget/catalog/ProductForms.xml
index f444dde..62f2568 100644
--- a/applications/product/widget/catalog/ProductForms.xml
+++ b/applications/product/widget/catalog/ProductForms.xml
@@ -1235,8 +1235,9 @@
     <form name="ListCostComponents" type="list" title="" list-name="listIt"
         odd-row-style="alternate-row" default-table-style="basic-table" paginate-target="EditProductCosts">
         <actions>
+        	<set field="InParam.productId" from-field="requestParameters.productId"/>
             <service service-name="performFind" result-map="result" result-map-list="listIt">
-                <field-map field-name="inputFields" from-field="requestParameters"/>
+                <field-map field-name="inputFields" from-field="InParam"/>
                 <field-map field-name="entityName" value="CostComponent"/>
                 <field-map field-name="viewIndex" from-field="viewIndex"/>
                 <field-map field-name="viewSize" from-field="viewSize"/>
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/entity/src/org/ofbiz/entity/GenericDelegator.java b/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
index 4566e48..d1c633b 100644
--- a/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
+++ b/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
@@ -1805,10 +1805,18 @@
                 beganTransaction = TransactionUtil.begin();
             }
 
-            EntityListIterator eli = this.find(entityName, entityCondition, null, fieldsToSelect, orderBy, findOptions);
-            eli.setDelegator(this);
-            List<GenericValue> list = eli.getCompleteList();
-            eli.close();
+            EntityListIterator eli = null;
+            List<GenericValue> list = null;
+            try {
+                eli = this.find(entityName, entityCondition, null, fieldsToSelect, orderBy, findOptions);
+                list = eli.getCompleteList();
+            } finally {
+                if (eli != null) {
+                    try {
+                        eli.close();
+                    } catch (Exception exc) {}
+                }
+            }
 
             if (useCache) {
                 ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_PUT, EntityEcaHandler.OP_FIND, dummyValue, false);
diff --git a/framework/images/webapp/images/ecommain.css b/framework/images/webapp/images/ecommain.css
index e85430c..51b36821 100644
--- a/framework/images/webapp/images/ecommain.css
+++ b/framework/images/webapp/images/ecommain.css
@@ -286,14 +286,14 @@
 #ecom-mainarea .left {
 background:#fff;
 float:left;
-width:180px;
+width:250px;
 margin:0 0 0 10px;
 }
 
 #ecom-mainarea .right {
 background:#fff;
 float:right;
-width:240px;
+width:250px;
 margin:0 10px 0 0;
 }
 
diff --git a/framework/images/webapp/images/fieldlookup.js b/framework/images/webapp/images/fieldlookup.js
index f81ae8b..ddeb880 100644
--- a/framework/images/webapp/images/fieldlookup.js
+++ b/framework/images/webapp/images/fieldlookup.js
@@ -28,424 +28,424 @@
 var lookups = [];
 
 function getViewNameWithSeparator(view_name) {
-	var sep = "?";
-	if (view_name.indexOf("?") >= 0) {
-		sep = "&";
-	}
-	return view_name + sep;
+    var sep = "?";
+    if (view_name.indexOf("?") >= 0) {
+        sep = "&";
+    }
+    return view_name + sep;
 }
 
 function lookup_error(str_message) {
-	var CommonErrorMessage2 = getJSONuiLabel("CommonUiLabels", "CommonErrorMessage2");
-	showErrorAlert(CommonErrorMessage2, str_message);
+    var CommonErrorMessage2 = getJSONuiLabel("CommonUiLabels", "CommonErrorMessage2");
+    showErrorAlert(CommonErrorMessage2, str_message);
 }
 
 function lookup_popup1(view_name, form_name, viewWidth, viewheight) {
-	var obj_lookupwindow = window.open(getViewNameWithSeparator(view_name) + 'formName=' + form_name + '&presentation=' + this.presentation
-			+ '&id=' + this.id, '_blank', 'width=' + viewWidth + ',height=' + viewheight + ',scrollbars=yes,status=no,resizable=yes,top='
-			+ my + ',left=' + mx + ',dependent=yes,alwaysRaised=yes');
-	obj_lookupwindow.opener = window;
-	obj_lookupwindow.focus();
+    var obj_lookupwindow = window.open(getViewNameWithSeparator(view_name) + 'formName=' + form_name + '&presentation=' + this.presentation
+            + '&id=' + this.id, '_blank', 'width=' + viewWidth + ',height=' + viewheight + ',scrollbars=yes,status=no,resizable=yes,top='
+            + my + ',left=' + mx + ',dependent=yes,alwaysRaised=yes');
+    obj_lookupwindow.opener = window;
+    obj_lookupwindow.focus();
 }
 
 function lookup_popup2(view_name) {
-	var argString = "";
-	if (this.args !== null) {
-		if (this.args.length > 2) {
-			var i;
-			for (i = 2; i < this.args.length; i++) {
-				argString += "&parm" + (i - 3) + "=" + this.args[i];
-			}
-		}
-	}
+    var argString = "";
+    if (this.args !== null) {
+        if (this.args.length > 2) {
+            var i;
+            for (i = 2; i < this.args.length; i++) {
+                argString += "&parm" + (i - 3) + "=" + this.args[i];
+            }
+        }
+    }
 
-	var obj_lookupwindow = window.open(getViewNameWithSeparator(view_name) + 'presentation=' + this.presentation + '&id=' + this.id
-			+ argString, '_blank', 'width=900,height=700,scrollbars=yes,status=no,resizable=yes,top=' + my + ',left=' + mx
-			+ ',dependent=yes,alwaysRaised=yes');
-	obj_lookupwindow.opener = window;
-	obj_lookupwindow.focus();
+    var obj_lookupwindow = window.open(getViewNameWithSeparator(view_name) + 'presentation=' + this.presentation + '&id=' + this.id
+            + argString, '_blank', 'width=900,height=700,scrollbars=yes,status=no,resizable=yes,top=' + my + ',left=' + mx
+            + ',dependent=yes,alwaysRaised=yes');
+    obj_lookupwindow.opener = window;
+    obj_lookupwindow.focus();
 }
 
 function fieldLookup1(obj_target, args, presentation) {
-	this.args = args;
-	this.presentation = presentation;
-	// passing methods
-	this.popup = lookup_popup1;
-	this.popup2 = lookup_popup2;
+    this.args = args;
+    this.presentation = presentation;
+    // passing methods
+    this.popup = lookup_popup1;
+    this.popup2 = lookup_popup2;
 
-	// validate input parameters
-	if (!obj_target) {
-		return lookup_error("Error calling the field lookup: no target control specified");
-	}
-	if (obj_target.value === null) {
-		return lookup_error("Error calling the field lookup: parameter specified is not valid target control");
-	}
-	targetW = obj_target;
+    // validate input parameters
+    if (!obj_target) {
+        return lookup_error("Error calling the field lookup: no target control specified");
+    }
+    if (obj_target.value === null) {
+        return lookup_error("Error calling the field lookup: parameter specified is not valid target control");
+    }
+    targetW = obj_target;
 }
 
 function fieldLookup2(obj_target, obj_target2, args, presentation) {
-	this.args = args;
-	this.presentation = presentation;
-	// passing methods
-	this.popup = lookup_popup1;
-	this.popup2 = lookup_popup2;
-	// validate input parameters
-	if (!obj_target) {
-		return lookup_error("Error calling the field lookup: no target control specified");
-	}
-	if (obj_target.value === null) {
-		return lookup_error("Error calling the field lookup: parameter specified is not valid target control");
-	}
-	targetW = obj_target;
-	// validate input parameters
-	if (!obj_target2) {
-		return lookup_error("Error calling the field lookup: no target2 control specified");
-	}
-	if (obj_target2.value === null) {
-		return lookup_error("Error calling the field lookup: parameter specified is not valid target2 control");
-	}
-	target2 = obj_target2;
+    this.args = args;
+    this.presentation = presentation;
+    // passing methods
+    this.popup = lookup_popup1;
+    this.popup2 = lookup_popup2;
+    // validate input parameters
+    if (!obj_target) {
+        return lookup_error("Error calling the field lookup: no target control specified");
+    }
+    if (obj_target.value === null) {
+        return lookup_error("Error calling the field lookup: parameter specified is not valid target control");
+    }
+    targetW = obj_target;
+    // validate input parameters
+    if (!obj_target2) {
+        return lookup_error("Error calling the field lookup: no target2 control specified");
+    }
+    if (obj_target2.value === null) {
+        return lookup_error("Error calling the field lookup: parameter specified is not valid target2 control");
+    }
+    target2 = obj_target2;
 }
 
 function call_fieldlookup3(target, target2, viewName, presentation) {
-	var fieldLookup = new fieldLookup2(target, target2, arguments, presentation);
-	fieldLookup.popup2(viewName);
+    var fieldLookup = new fieldLookup2(target, target2, arguments, presentation);
+    fieldLookup.popup2(viewName);
 }
 
 function call_fieldlookup(target, viewName, formName, viewWidth, viewheight) {
-	var fieldLookup = new fieldLookup1(target);
-	if (!viewWidth) {
-		viewWidth = 350;
-	}
-	if (!viewheight) {
-		viewheight = 200;
-	}
-	fieldLookup.popup(viewName, formName, viewWidth, viewheight);
+    var fieldLookup = new fieldLookup1(target);
+    if (!viewWidth) {
+        viewWidth = 350;
+    }
+    if (!viewheight) {
+        viewheight = 200;
+    }
+    fieldLookup.popup(viewName, formName, viewWidth, viewheight);
 }
 
 function call_fieldlookup2(target, viewName, presentation) {
-	var fieldLookup = new fieldLookup1(target, arguments, presentation);
-	fieldLookup.popup2(viewName);
+    var fieldLookup = new fieldLookup1(target, arguments, presentation);
+    fieldLookup.popup2(viewName);
 }
 
 function CollapsePanel(link, areaId) {
-	var container, liElement;
+    var container, liElement;
 
-	container = jQuery(areaId);
-	liElement = jQuery(link).up('li');
+    container = jQuery(areaId);
+    liElement = jQuery(link).up('li');
 
-	liElement.removeClassName('expanded');
-	liElement.addClassName('collapsed');
-	Effect.toggle(container, 'appear');
+    liElement.removeClassName('expanded');
+    liElement.addClassName('collapsed');
+    Effect.toggle(container, 'appear');
 }
 
 function initiallyCollapse() {
-	if ((!LOOKUP_DIV) || (INITIALLY_COLLAPSED != "true")) {
-		return;
-	}
+    if ((!LOOKUP_DIV) || (INITIALLY_COLLAPSED != "true")) {
+        return;
+    }
 
-	var i, j, childEle, childElements, ul, slTitleBar, slTitleBars = LOOKUP_DIV.getElementsByClassName('screenlet-title-bar');
-	for (i in slTitleBars) {
-		slTitleBar = slTitleBars[i];
-		ul = slTitleBar.firstChild;
-		if ((typeof ul) != 'object') {
-			continue;
-		}
+    var i, j, childEle, childElements, ul, slTitleBar, slTitleBars = LOOKUP_DIV.getElementsByClassName('screenlet-title-bar');
+    for (i in slTitleBars) {
+        slTitleBar = slTitleBars[i];
+        ul = slTitleBar.firstChild;
+        if ((typeof ul) != 'object') {
+            continue;
+        }
 
-		childElements = ul.childNodes;
-		for (j in childElements) {
-			if (childElements[j].className === 'expanded' || childElements[j].className === 'collapsed') {
-				break;
-			}
-		}
+        childElements = ul.childNodes;
+        for (j in childElements) {
+            if (childElements[j].className === 'expanded' || childElements[j].className === 'collapsed') {
+                break;
+            }
+        }
 
-		childEle = childElements[j].firstChild;
-		new CollapsePanel(childEle, 'lec' + COLLAPSE_SEQUENCE_NUMBER);
-		break;
-	}
+        childEle = childElements[j].firstChild;
+        new CollapsePanel(childEle, 'lec' + COLLAPSE_SEQUENCE_NUMBER);
+        break;
+    }
 }
 
 function initiallyCollapseDelayed() {
-	setTimeout("initiallyCollapse()", 400);
+    setTimeout("initiallyCollapse()", 400);
 }
 
 /*******************************************************************************
  * Lookup Object
  ******************************************************************************/
 var Lookup = function(options) {
-	var _newInputBoxId, _lookupId, _inputBox, _lookupContainer, _backgroundCloseClickEvent;
+    var _newInputBoxId, _lookupId, _inputBox, _lookupContainer, _backgroundCloseClickEvent;
 
-	options = {
-		requestUrl : options.requestUrl || "",
-		inputFieldId : options.inputFieldId || "",
-		dialogTarget : options.dialogTarget || "",
-		dialogOptionalTarget : options.dialogOptionalTarget || "",
-		formName : options.formName || "",
-		width : options.width || "620",
-		height : options.height || "500",
-		position : options.position || "topleft",
-		modal : options.modal || "true",
-		ajaxUrl : options.ajaxUrl || "",
-		showDescription : options.showDescription || "",
-		presentation : options.presentation || "layer",
-		defaultMinLength : options.defaultMinLength || "",
-		defaultDelay : options.defaultDelay || "",
-		args : options.args || ""
-	}
+    options = {
+        requestUrl : options.requestUrl || "",
+        inputFieldId : options.inputFieldId || "",
+        dialogTarget : options.dialogTarget || "",
+        dialogOptionalTarget : options.dialogOptionalTarget || "",
+        formName : options.formName || "",
+        width : options.width || "620",
+        height : options.height || "500",
+        position : options.position || "topleft",
+        modal : options.modal || "true",
+        ajaxUrl : options.ajaxUrl || "",
+        showDescription : options.showDescription || "",
+        presentation : options.presentation || "layer",
+        defaultMinLength : options.defaultMinLength || "",
+        defaultDelay : options.defaultDelay || "",
+        args : options.args || ""
+    }
 
-	function _init() {
-		_lookupId = GLOBAL_LOOKUP_REF.createNextKey();
-		_modifyContainer();
-		_createAjaxAutoComplete();
+    function _init() {
+        _lookupId = GLOBAL_LOOKUP_REF.createNextKey();
+        _modifyContainer();
+        _createAjaxAutoComplete();
 
-		_lookupContainer = jQuery("#" + _lookupId);
-		var dialogOpts = _createDialogOptions(_lookupContainer);
+        _lookupContainer = jQuery("#" + _lookupId);
+        var dialogOpts = _createDialogOptions(_lookupContainer);
 
-		// init Dialog and register
-		// create an object with all Lookup Informationes that are needed
-		var dialogRef = _lookupContainer.dialog(dialogOpts);
+        // init Dialog and register
+        // create an object with all Lookup Informationes that are needed
+        var dialogRef = _lookupContainer.dialog(dialogOpts);
 
-		// setting up global variabels, for external access
-		this.inputBoxId = _inputBox.id;
-		this.lookupId = _lookupId;
-		this.formName = options.formName;
-		this.target = null;
-		this.presentation = options.presentation;
-		this.showDescription = (options.showDescription == "true") ? true : false;
-		if (options.dialogOptionalTarget != null) {
-			this.target2 = null;
-		}
-		this.prevLookup = null;
-		this.dialogRef = dialogRef;
+        // setting up global variabels, for external access
+        this.inputBoxId = _inputBox.id;
+        this.lookupId = _lookupId;
+        this.formName = options.formName;
+        this.target = null;
+        this.presentation = options.presentation;
+        this.showDescription = (options.showDescription == "true") ? true : false;
+        if (options.dialogOptionalTarget != null) {
+            this.target2 = null;
+        }
+        this.prevLookup = null;
+        this.dialogRef = dialogRef;
 
-		// write external settings in global window manager
-		GLOBAL_LOOKUP_REF.setReference(_lookupId, this);
+        // write external settings in global window manager
+        GLOBAL_LOOKUP_REF.setReference(_lookupId, this);
 
-		_addOpenEvent(dialogRef);
-	}
+        _addOpenEvent(dialogRef);
+    }
 
-	function _modifyContainer() {
-		_inputBox = document.getElementById(options.inputFieldId);
-		_newInputBoxId = _lookupId + "_" + options.inputFieldId;
-		_inputBox.id = _newInputBoxId;
-		var parent = _inputBox.parentNode;
+    function _modifyContainer() {
+        _inputBox = document.getElementById(options.inputFieldId);
+        _newInputBoxId = _lookupId + "_" + options.inputFieldId;
+        _inputBox.id = _newInputBoxId;
+        var parent = _inputBox.parentNode;
 
-		var link = document.createElement('A');
-		link.href = "javascript:void(0);";
-		link.id = _lookupId + "_button";
+        var link = document.createElement('A');
+        link.href = "javascript:void(0);";
+        link.id = _lookupId + "_button";
 
-		parent.appendChild(link);
+        parent.appendChild(link);
 
-		var hiddenDiv = document.createElement("DIV");
-		hiddenDiv.id = _lookupId;
-		hiddenDiv.css = "{display: none;}";
-		hiddenDiv.title = "";
+        var hiddenDiv = document.createElement("DIV");
+        hiddenDiv.id = _lookupId;
+        hiddenDiv.css = "{display: none;}";
+        hiddenDiv.title = "";
 
-		parent.appendChild(hiddenDiv);
-	}
+        parent.appendChild(hiddenDiv);
+    }
 
-	function _createAjaxAutoComplete() {
-		if (options.ajaxUrl != "") {
-			// write the new input box id in the ajaxUrl Array
-			options.ajaxUrl = options.ajaxUrl.replace(options.ajaxUrl.substring(0, options.ajaxUrl.indexOf(",")), _newInputBoxId);
-			new ajaxAutoCompleter(options.ajaxUrl, (options.showDescription == "true") ? true : false, options.defaultMinLength, options.defaultDelay,
-					options.formName);
-		}
-	}
+    function _createAjaxAutoComplete() {
+        if (options.ajaxUrl != "") {
+            // write the new input box id in the ajaxUrl Array
+            options.ajaxUrl = options.ajaxUrl.replace(options.ajaxUrl.substring(0, options.ajaxUrl.indexOf(",")), _newInputBoxId);
+            new ajaxAutoCompleter(options.ajaxUrl, (options.showDescription == "true") ? true : false, options.defaultMinLength, options.defaultDelay,
+                    options.formName);
+        }
+    }
 
-	function _createDialogOptions(_lookupContainer) {
-		var positioning = _positioning();
+    function _createDialogOptions(_lookupContainer) {
+        var positioning = _positioning();
 
-		var dialogOpts = {
-			modal : (options.modal == "true") ? true : false,
-			bgiframe : true,
-			autoOpen : false,
-			height : parseInt(options.height),
-			width : parseInt(options.width),
-			position : positioning,
-			draggable : true,
-			resizeable : true,
-			open : _dialogOpen,
-			close : _dialogClose
-		};
+        var dialogOpts = {
+            modal : (options.modal == "true") ? true : false,
+            bgiframe : true,
+            autoOpen : false,
+            height : parseInt(options.height),
+            width : parseInt(options.width),
+            position : positioning,
+            draggable : true,
+            resizeable : true,
+            open : _dialogOpen,
+            close : _dialogClose
+        };
 
-		return dialogOpts;
-	}
+        return dialogOpts;
+    }
 
-	function _positioning() {
-		var positioning = null;
-		if (options.position == "topleft") {
-			positioning = [ 'left', 'top' ];
-		} else if (options.position == "topcenter") {
-			positioning = [ 'center', 'top' ];
-		} else if (options.position == "topright") {
-			positioning = [ 'right', 'top' ];
-		} else if (options.position == "center") {
-			positioning = 'center';
-		} else if (options.position == "left") {
-			positioning = 'left';
-		} else if (options.position == "right") {
-			positioning = 'right';
-		} else {
-			positioning = [ 'left', 'top' ];
-		}
+    function _positioning() {
+        var positioning = null;
+        if (options.position == "topleft") {
+            positioning = [ 'left', 'top' ];
+        } else if (options.position == "topcenter") {
+            positioning = [ 'center', 'top' ];
+        } else if (options.position == "topright") {
+            positioning = [ 'right', 'top' ];
+        } else if (options.position == "center") {
+            positioning = 'center';
+        } else if (options.position == "left") {
+            positioning = 'left';
+        } else if (options.position == "right") {
+            positioning = 'right';
+        } else {
+            positioning = [ 'left', 'top' ];
+        }
 
-		return positioning;
-	}
+        return positioning;
+    }
 
-	function _dialogOpen(event, ui) {
-		waitSpinnerShow();
-		_lookupContainer.empty();
+    function _dialogOpen(event, ui) {
+        waitSpinnerShow();
+        _lookupContainer.empty();
 
-		var queryArgs = "presentation=" + options.presentation;
-		if (typeof options.args == "object" && jQuery.isArray(options.args)) {
-			for ( var i = 0; i < options.args.length; i++) {
-				queryArgs += "&parm" + i + "=" + jQuery(options.args[i]).val();
-			}
-		}
+        var queryArgs = "presentation=" + options.presentation;
+        if (typeof options.args == "object" && jQuery.isArray(options.args)) {
+            for ( var i = 0; i < options.args.length; i++) {
+                queryArgs += "&parm" + i + "=" + jQuery(options.args[i]).val();
+            }
+        }
 
-		_lookupChaining();
-		_addCloseEventForClickingOnBackgroundLayer();
+        _lookupChaining();
+        _addCloseEventForClickingOnBackgroundLayer();
 
-		// load lookup data from server
-		jQuery.ajax({
-			type : "POST",
-			url : options.requestUrl,
-			data : queryArgs,
-			timeout : AJAX_REQUEST_TIMEOUT,
-			cache : false,
-			dataFilter : function(data, dataType) {
-				waitSpinnerHide();
-				return data;
-			},
+        // load lookup data from server
+        jQuery.ajax({
+            type : "POST",
+            url : options.requestUrl,
+            data : queryArgs,
+            timeout : AJAX_REQUEST_TIMEOUT,
+            cache : false,
+            dataFilter : function(data, dataType) {
+                waitSpinnerHide();
+                return data;
+            },
 
-			success : function(data) {
-				_lookupContainer.html(data);
-				new ButtonModifier(_lookupId).modifyLookupLinks();
-			},
+            success : function(data) {
+                _lookupContainer.html(data);
+                new ButtonModifier(_lookupId).modifyLookupLinks();
+            },
 
-			error : function(xhr, reason, exception) {
-				if (exception != 'abort') {
-					alert("An error occurred while communicating with the server:\n\n\nreason=" + reason + "\n\nexception=" + exception);
-				}
-				location.reload(true);
-			}
-		});
-	}
+            error : function(xhr, reason, exception) {
+                if (exception != 'abort') {
+                    alert("An error occurred while communicating with the server:\n\n\nreason=" + reason + "\n\nexception=" + exception);
+                }
+                location.reload(true);
+            }
+        });
+    }
 
-	function _lookupChaining() {
-		/*
-		 * set up the window chaining if the ACTIVATED_LOOKUP var is set there
-		 * have to be more than one lookup, before registrating the new lookup
-		 * we store the id of the old lookup in the preLookup variable of the
-		 * new lookup object. I.e. lookup_1 calls lookup_8, the lookup_8 object
-		 * need a reference to lookup_1, this reference is set here
-		 */
+    function _lookupChaining() {
+        /*
+         * set up the window chaining if the ACTIVATED_LOOKUP var is set there
+         * have to be more than one lookup, before registrating the new lookup
+         * we store the id of the old lookup in the preLookup variable of the
+         * new lookup object. I.e. lookup_1 calls lookup_8, the lookup_8 object
+         * need a reference to lookup_1, this reference is set here
+         */
 
-		var prevLookup = null
-		if (ACTIVATED_LOOKUP) {
-			prevLookup = ACTIVATED_LOOKUP;
-		}
+        var prevLookup = null
+        if (ACTIVATED_LOOKUP) {
+            prevLookup = ACTIVATED_LOOKUP;
+        }
 
-		_activateLookup(_lookupId);
+        _activateLookup(_lookupId);
 
-		GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).prevLookup = prevLookup;
-	}
+        GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).prevLookup = prevLookup;
+    }
 
-	function _activateLookup(newAl) {
-		if (ACTIVATED_LOOKUP != newAl) {
-			ACTIVATED_LOOKUP = newAl;
-		}
-	}
+    function _activateLookup(newAl) {
+        if (ACTIVATED_LOOKUP != newAl) {
+            ACTIVATED_LOOKUP = newAl;
+        }
+    }
 
-	function _addCloseEventForClickingOnBackgroundLayer() {
-		_backgroundCloseClickEvent = function() {
-			if (ACTIVATED_LOOKUP && ACTIVATED_LOOKUP == _lookupId) {
-				GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).dialogRef.dialog("close");
-			}
-		}
+    function _addCloseEventForClickingOnBackgroundLayer() {
+        _backgroundCloseClickEvent = function() {
+            if (ACTIVATED_LOOKUP && ACTIVATED_LOOKUP == _lookupId) {
+                GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).dialogRef.dialog("close");
+            }
+        }
 
-		jQuery(".ui-widget-overlay").click(_backgroundCloseClickEvent);
-	}
+        jQuery(".ui-widget-overlay").click(_backgroundCloseClickEvent);
+    }
 
-	function _dialogClose() {
-		jQuery(".ui-widget-overlay").unbind("click", _backgroundCloseClickEvent)
+    function _dialogClose() {
+        jQuery(".ui-widget-overlay").unbind("click", _backgroundCloseClickEvent)
 
-		var prevLookup = null;
-		if (ACTIVATED_LOOKUP) {
-			prevLookup = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).prevLookup;
-		}
+        var prevLookup = null;
+        if (ACTIVATED_LOOKUP) {
+            prevLookup = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).prevLookup;
+        }
 
-		if (prevLookup) {
-			_activateLookup(prevLookup);
-		} else {
-			ACTIVATED_LOOKUP = null;
-		}
-	}
+        if (prevLookup) {
+            _activateLookup(prevLookup);
+        } else {
+            ACTIVATED_LOOKUP = null;
+        }
+    }
 
-	function _addOpenEvent(dialogReference) {
-		jQuery("#" + _lookupId + "_button").click(function() {
-			dialogReference.dialog("open");
+    function _addOpenEvent(dialogReference) {
+        jQuery("#" + _lookupId + "_button").click(function() {
+            dialogReference.dialog("open");
 
-			GLOBAL_LOOKUP_REF.getReference(_lookupId).target = jQuery(options.dialogTarget);
-			if (options.dialogOptionalTarget != null) {
-				GLOBAL_LOOKUP_REF.getReference(_lookupId).target2 = jQuery(options.dialogOptionalTarget);
-			}
-		});
+            GLOBAL_LOOKUP_REF.getReference(_lookupId).target = jQuery(options.dialogTarget);
+            if (options.dialogOptionalTarget != null) {
+                GLOBAL_LOOKUP_REF.getReference(_lookupId).target2 = jQuery(options.dialogOptionalTarget);
+            }
+        });
 
-	}
+    }
 
-	return {
-		init : _init
-	}
+    return {
+        init : _init
+    }
 };
 
 /*******************************************************************************
  * Lookup Counter Object
  ******************************************************************************/
 var FieldLookupCounter = function() {
-	this.refArr = {};
+    this.refArr = {};
 
-	this.setReference = function(key, ref) {
-		// if key doesn't exist in the array and
-		var itm;
-		for (itm in this.refArr) {
-			if (itm == key) {
-				prefix = key.substring(0, key.indexOf("_"));
-				key = prefix + "_" + key;
-				this.refArr["" + key + ""] = ref;
-				return this.refArr[key];
-			}
-		}
-		this.refArr["" + key + ""] = ref;
-		return this.refArr[key];
-	};
+    this.setReference = function(key, ref) {
+        // if key doesn't exist in the array and
+        var itm;
+        for (itm in this.refArr) {
+            if (itm == key) {
+                prefix = key.substring(0, key.indexOf("_"));
+                key = prefix + "_" + key;
+                this.refArr["" + key + ""] = ref;
+                return this.refArr[key];
+            }
+        }
+        this.refArr["" + key + ""] = ref;
+        return this.refArr[key];
+    };
 
-	this.getReference = function(key) {
-		// when key does not exist return null?
-		return this.refArr[key] != null ? this.refArr[key] : null;
-	};
+    this.getReference = function(key) {
+        // when key does not exist return null?
+        return this.refArr[key] != null ? this.refArr[key] : null;
+    };
 
-	this.getLastReference = function() {
-		return (this.countFields() - 1) + "_lookupId";
-	}
+    this.getLastReference = function() {
+        return (this.countFields() - 1) + "_lookupId";
+    }
 
-	this.createNextKey = function() {
-		return this.countFields() + "_lookupId";
-	};
+    this.createNextKey = function() {
+        return this.countFields() + "_lookupId";
+    };
 
-	this.countFields = function() {
-		var count = 0;
-		jQuery.each(this.refArr, function(itm) {
-			count++;
-		});
-		return count;
-	};
+    this.countFields = function() {
+        var count = 0;
+        jQuery.each(this.refArr, function(itm) {
+            count++;
+        });
+        return count;
+    };
 
-	this.removeReference = function(key) {
-		// deletes the Array entry (doesn't effect the array length)
-		delete this.refArr[key];
-	};
+    this.removeReference = function(key) {
+        // deletes the Array entry (doesn't effect the array length)
+        delete this.refArr[key];
+    };
 
 };
 var GLOBAL_LOOKUP_REF = new FieldLookupCounter();
@@ -455,227 +455,227 @@
  ******************************************************************************/
 var ButtonModifier = function(lookupDiv) {
 
-	function _modifyLookupLinks() {
-		if (!lookupDiv) {
-			return;
-		}
+    function _modifyLookupLinks() {
+        if (!lookupDiv) {
+            return;
+        }
 
-		_modifyCollapseable();
+        _modifyCollapseable();
 
-		_modifySubmitButton();
+        _modifySubmitButton();
 
-		_modifyPagination();
+        _modifyPagination();
 
-		_modifyResultTable();
-	}
+        _modifyResultTable();
+    }
 
-	function _modifyCollapseable() {
+    function _modifyCollapseable() {
 
-		var slTitleBars = jQuery("#" + lookupDiv + " .screenlet-title-bar");
+        var slTitleBars = jQuery("#" + lookupDiv + " .screenlet-title-bar");
 
-		jQuery.each(slTitleBars, function(index) {
-			var slTitleBar = slTitleBars[index];
-			var ul = slTitleBar.firstChild;
-			if ((typeof ul) != 'object') {
-				return true;
-			}
-			var childElements = ul.childNodes;
+        jQuery.each(slTitleBars, function(index) {
+            var slTitleBar = slTitleBars[index];
+            var ul = slTitleBar.firstChild;
+            if ((typeof ul) != 'object') {
+                return true;
+            }
+            var childElements = ul.childNodes;
 
-			for (j in childElements) {
-				if (childElements[j].className == 'expanded' || childElements[j].className == 'collapsed') {
-					break;
-				}
-			}
+            for (j in childElements) {
+                if (childElements[j].className == 'expanded' || childElements[j].className == 'collapsed') {
+                    break;
+                }
+            }
 
-			_getNextCollapseSeq();
-			var childEle = childElements[j].firstChild;
+            _getNextCollapseSeq();
+            var childEle = childElements[j].firstChild;
 
-			childEle.setAttribute('onclick', "javascript:toggleScreenlet(this, 'lec" + COLLAPSE_SEQUENCE_NUMBER
-					+ "', 'true', 'Expand', 'Collapse');");
-			childEle.href = "javascript:void(0);"
-			jQuery(slTitleBar).next('div').attr('id', 'lec' + COLLAPSE_SEQUENCE_NUMBER);
+            childEle.setAttribute('onclick', "javascript:toggleScreenlet(this, 'lec" + COLLAPSE_SEQUENCE_NUMBER
+                    + "', 'true', 'Expand', 'Collapse');");
+            childEle.href = "javascript:void(0);"
+            jQuery(slTitleBar).next('div').attr('id', 'lec' + COLLAPSE_SEQUENCE_NUMBER);
 
-		});
-	}
+        });
+    }
 
-	function _getNextCollapseSeq() {
-		COLLAPSE_SEQUENCE_NUMBER++;
-		return COLLAPSE_SEQUENCE_NUMBER;
-	}
+    function _getNextCollapseSeq() {
+        COLLAPSE_SEQUENCE_NUMBER++;
+        return COLLAPSE_SEQUENCE_NUMBER;
+    }
 
-	function _modifySubmitButton() {
-		var lookupForm = jQuery("#" + lookupDiv + " form:first");
+    function _modifySubmitButton() {
+        var lookupForm = jQuery("#" + lookupDiv + " form:first");
 
-		// set new form name and id
-		var oldFormName = lookupForm.attr("name");
-		lookupForm.attr("name", "form_" + lookupDiv);
-		lookupForm.attr("id", "form_" + lookupDiv);
-		lookupForm = jQuery("#form_" + lookupDiv);
+        // set new form name and id
+        var oldFormName = lookupForm.attr("name");
+        lookupForm.attr("name", "form_" + lookupDiv);
+        lookupForm.attr("id", "form_" + lookupDiv);
+        lookupForm = jQuery("#form_" + lookupDiv);
 
-		// set new links for lookups
-		var newLookups = jQuery("#" + lookupDiv + " .field-lookup");
+        // set new links for lookups
+        var newLookups = jQuery("#" + lookupDiv + " .field-lookup");
 
-		var formAction = lookupForm.attr("action");
+        var formAction = lookupForm.attr("action");
 
-		// remove the form action
-		lookupForm.attr("action", "");
-		var input = jQuery("#" + lookupDiv + " input[type=submit]").css({
-			display : "block"
-		});
+        // remove the form action
+        lookupForm.attr("action", "");
+        var input = jQuery("#" + lookupDiv + " input[type=submit]").css({
+            display : "block"
+        });
 
-		// remove the original input button and replace with a new one
-		var txt = input.attr("value");
-		(input.parent()).append(jQuery("<button/>", {
-			id : "lookupSubmitButton",
-			href : "javascript:void(0);",
-			click : function() {
-				lookupFormAjaxRequest(formAction, lookupForm.attr("id"));
-				return false;
-			},
-			text : txt
-		}));
+        // remove the original input button and replace with a new one
+        var txt = input.attr("value");
+        (input.parent()).append(jQuery("<button/>", {
+            id : "lookupSubmitButton",
+            href : "javascript:void(0);",
+            click : function() {
+                lookupFormAjaxRequest(formAction, lookupForm.attr("id"));
+                return false;
+            },
+            text : txt
+        }));
 
-		input.remove();
-	}
+        input.remove();
+    }
 
-	function _modifyPagination() {
-		// modify nav-pager
-		var navPagers = jQuery("#" + lookupDiv + " .nav-pager a");
-		jQuery.each(navPagers, function(navPager) {
-		    var onClickEvent = navPagers[navPager].onclick;
-		    navPagers[navPager].onclick = function(){
-		        this.setAttribute("data-lookupajax", "true");
-		        onClickEvent.apply(this);
-		    }
-		});
+    function _modifyPagination() {
+        // modify nav-pager
+        var navPagers = jQuery("#" + lookupDiv + " .nav-pager a");
+        jQuery.each(navPagers, function(navPager) {
+            var onClickEvent = navPagers[navPager].onclick;
+            navPagers[navPager].onclick = function(){
+                this.setAttribute("data-lookupajax", "true");
+                onClickEvent.apply(this);
+            }
+        });
 
-		var navPagersSelect = jQuery("#" + lookupDiv + " .nav-pager select");
-		jQuery.each(navPagersSelect, function(navPager) {
-			var onChangeEvent = navPagersSelect[navPager].onchange;
-			navPagersSelect[navPager].onchange = function(){
-			    this.setAttribute("data-lookupajax", "true");
-			    onChangeEvent.apply(this);
-			}
-		});
-	}
+        var navPagersSelect = jQuery("#" + lookupDiv + " .nav-pager select");
+        jQuery.each(navPagersSelect, function(navPager) {
+            var onChangeEvent = navPagersSelect[navPager].onchange;
+            navPagersSelect[navPager].onchange = function(){
+                this.setAttribute("data-lookupajax", "true");
+                onChangeEvent.apply(this);
+            }
+        });
+    }
 
-	function _modifyResultTable() {
-		var resultTable = jQuery("#" + lookupDiv + " #search-results table:first tbody");
-		var tableChilds = resultTable.children();
+    function _modifyResultTable() {
+        var resultTable = jQuery("#" + lookupDiv + " #search-results table:first tbody");
+        var tableChilds = resultTable.children();
 
-		jQuery.each(tableChilds, function(tableChild) {
-			var childElements = jQuery(tableChilds[tableChild]);
-			var tableRows = childElements.children();
+        jQuery.each(tableChilds, function(tableChild) {
+            var childElements = jQuery(tableChilds[tableChild]);
+            var tableRows = childElements.children();
 
-			jQuery.each(tableRows, function(cell) {
-				var cellChilds = jQuery(tableRows[cell]).children();
+            jQuery.each(tableRows, function(cell) {
+                var cellChilds = jQuery(tableRows[cell]).children();
 
-				jQuery.each(cellChilds, function(child) {
-					if (cellChilds[child].tagName == "A") {
-						var link = cellChilds[child].href;
-						if (link.indexOf("javascript:set_") != -1) {
-							cellChilds[child].href = link;
-						} else {
-							var liSub = link.substring(link.lastIndexOf('/') + 1, (link.length));
-							cellChilds[child].href = "javascript:lookupAjaxRequest('" + liSub + "&presentation=layer')";
-						}
-					}
-				});
+                jQuery.each(cellChilds, function(child) {
+                    if (cellChilds[child].tagName == "A") {
+                        var link = cellChilds[child].href;
+                        if (link.indexOf("javascript:set_") != -1) {
+                            cellChilds[child].href = link;
+                        } else {
+                            var liSub = link.substring(link.lastIndexOf('/') + 1, (link.length));
+                            cellChilds[child].href = "javascript:lookupAjaxRequest('" + liSub + "&presentation=layer')";
+                        }
+                    }
+                });
 
-			});
+            });
 
-		});
-	}
+        });
+    }
 
-	return {
-		modifyLookupLinks : _modifyLookupLinks
-	}
+    return {
+        modifyLookupLinks : _modifyLookupLinks
+    }
 }
 
 /*******************************************************************************
  * Ajax Request Helper
  ******************************************************************************/
 function lookupAjaxRequest(request) {
-	// get request arguments
-	var arg = request.substring(request.indexOf('?') + 1, (request.length));
-	request = request.substring(0, request.indexOf('?'));
-	lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
-	jQuery("#" + lookupId).load(request, arg, function(data) {
-		new ButtonModifier(lookupId).modifyLookupLinks();
-	});
+    // get request arguments
+    var arg = request.substring(request.indexOf('?') + 1, (request.length));
+    request = request.substring(0, request.indexOf('?'));
+    lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
+    jQuery("#" + lookupId).load(request, arg, function(data) {
+        new ButtonModifier(lookupId).modifyLookupLinks();
+    });
 }
 
 function lookupFormAjaxRequest(formAction, form) {
-	var lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
-	var data = jQuery("#" + form).serialize();
-	data = data + "&presentation=" + GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).presentation;
+    var lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
+    var data = jQuery("#" + form).serialize();
+    data = data + "&presentation=" + GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).presentation;
 
-	var screenletTitleBar = jQuery("#" + lookupId + " .screenlet-title-bar :visible:first");
-	jQuery.ajax({
-		url : formAction,
-		type: "POST",
-		data : data,
-		beforeSend : function(jqXHR, settings) {
-			// Here we append the spinner to the lookup screenlet and it will
-			// shown till the ajax request is processed.
-			var indicator = screenletTitleBar.find("span.indicator");
-			// Check that if spinner is already in execution then don't add new
-			// spinner
-			if (indicator.length == 0) {
-				jQuery("<span class='indicator'><img src='/images/ajax-loader.gif' alt='' /></span>").appendTo(screenletTitleBar);
-			}
-		},
-		success : function(result) {
-			if (result.search(/loginform/) != -1) {
-				window.location.href = window.location.href;
-				return;
-			}
-			// Here we are removing the spinner.
-			var indicator = screenletTitleBar.find("span.indicator");
-			if (indicator != undefined) {
-				jQuery("span.indicator").remove();
-			}
-			jQuery("#" + lookupId).html(result);
-			new ButtonModifier(lookupId).modifyLookupLinks();
-		}
-	});
+    var screenletTitleBar = jQuery("#" + lookupId + " .screenlet-title-bar :visible:first");
+    jQuery.ajax({
+        url : formAction,
+        type: "POST",
+        data : data,
+        beforeSend : function(jqXHR, settings) {
+            // Here we append the spinner to the lookup screenlet and it will
+            // shown till the ajax request is processed.
+            var indicator = screenletTitleBar.find("span.indicator");
+            // Check that if spinner is already in execution then don't add new
+            // spinner
+            if (indicator.length == 0) {
+                jQuery("<span class='indicator'><img src='/images/ajax-loader.gif' alt='' /></span>").appendTo(screenletTitleBar);
+            }
+        },
+        success : function(result) {
+            if (result.search(/loginform/) != -1) {
+                window.location.href = window.location.href;
+                return;
+            }
+            // Here we are removing the spinner.
+            var indicator = screenletTitleBar.find("span.indicator");
+            if (indicator != undefined) {
+                jQuery("span.indicator").remove();
+            }
+            jQuery("#" + lookupId).html(result);
+            new ButtonModifier(lookupId).modifyLookupLinks();
+        }
+    });
 }
 
 function lookupPaginationAjaxRequest(navAction, type) {
-	var lookupDiv = (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).divRef);
-	var lookupContent = (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).contentRef);
+    var lookupDiv = (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).divRef);
+    var lookupContent = (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).contentRef);
 
-	var lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
-	var screenletTitleBar = jQuery("#" + lookupId + " .screenlet-title-bar :visible:first");
+    var lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
+    var screenletTitleBar = jQuery("#" + lookupId + " .screenlet-title-bar :visible:first");
 
-	jQuery.ajax({
-		url : navAction.substring(0, navAction.indexOf("?")),
-		type : "POST",
-		data : navAction.substring(navAction.indexOf("?")+1, navAction.length),
-		beforeSend : function(jqXHR, settings) {
-			// Here we append the spinner to the lookup screenlet and it will
-			// shown till the ajax request is processed.
-			var indicator = screenletTitleBar.find("span.indicator");
-			// Check that if spinner is already in execution then don't add new
-			// spinner
-			if (indicator.length == 0) {
-				jQuery("<span class='indicator'><img src='/images/ajax-loader.gif' alt='' /></span>").appendTo(screenletTitleBar);
-			}
-		},
-		success : function(result) {
-			if (result.search(/loginform/) != -1) {
-				window.location.href = window.location.href;
-				return;
-			}
-			// Here we are removing the spinner.
-			var indicator = screenletTitleBar.find("span.indicator");
-			if (indicator != undefined) {
-				jQuery("span.indicator").remove();
-			}
-			jQuery("#" + lookupId).html(result);
-			new ButtonModifier(lookupId).modifyLookupLinks();
-		}
-	});
+    jQuery.ajax({
+        url : navAction.substring(0, navAction.indexOf("?")),
+        type : "POST",
+        data : navAction.substring(navAction.indexOf("?")+1, navAction.length),
+        beforeSend : function(jqXHR, settings) {
+            // Here we append the spinner to the lookup screenlet and it will
+            // shown till the ajax request is processed.
+            var indicator = screenletTitleBar.find("span.indicator");
+            // Check that if spinner is already in execution then don't add new
+            // spinner
+            if (indicator.length == 0) {
+                jQuery("<span class='indicator'><img src='/images/ajax-loader.gif' alt='' /></span>").appendTo(screenletTitleBar);
+            }
+        },
+        success : function(result) {
+            if (result.search(/loginform/) != -1) {
+                window.location.href = window.location.href;
+                return;
+            }
+            // Here we are removing the spinner.
+            var indicator = screenletTitleBar.find("span.indicator");
+            if (indicator != undefined) {
+                jQuery("span.indicator").remove();
+            }
+            jQuery("#" + lookupId).html(result);
+            new ButtonModifier(lookupId).modifyLookupLinks();
+        }
+    });
 }
 
 /*******************************************************************************
@@ -684,106 +684,115 @@
  ******************************************************************************/
 var re_id = new RegExp('id=(\\d+)');
 var num_id = (re_id.exec(String(window.location)) ? new Number(RegExp.$1) : 0);
-var obj_caller = (window.opener && window.opener.lookups? window.opener.lookups[num_id]: null);
-if (obj_caller == null && window.opener != null) {
-	obj_caller = window.opener;
-} else if (obj_caller == null && window.opener == null) {
-	obj_caller = parent;
+var obj_caller;
+try {
+    obj_caller = (window.opener && window.opener.lookups? window.opener.lookups[num_id]: null);
+    if (obj_caller == null && window.opener != null) {
+        obj_caller = window.opener;
+    } else if (obj_caller == null && window.opener == null) {
+        obj_caller = parent;
+    }
+}
+catch (err) {
+    obj_caller = parent;
+    if (console) {
+        console.log(err);
+    }
 }
 
 function setSourceColor(src) {
-	if (src && src != null) {
-		src.css("background-color", "yellow");
-	}
+    if (src && src != null) {
+        src.css("background-color", "yellow");
+    }
 }
 // function passing selected value to calling window, using only in the
 // TimeDuration case
 function set_duration_value(value) {
-	if (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP)) {
-		obj_caller.target = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).target;
-	} else {
-		obj_caller.target = jQuery(obj_caller.targetW);
-	}
-	var target = obj_caller.target;
+    if (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP)) {
+        obj_caller.target = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).target;
+    } else {
+        obj_caller.target = jQuery(obj_caller.targetW);
+    }
+    var target = obj_caller.target;
 
-	write_value(value, target);
-	closeLookup();
+    write_value(value, target);
+    closeLookup();
 }
 // function passing selected value to calling window
 function set_value(value) {
-	if (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP)) {
-		obj_caller.target = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).target;
-	} else {
-		obj_caller.target = jQuery(obj_caller.targetW);
-	}
+    if (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP)) {
+        obj_caller.target = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).target;
+    } else {
+        obj_caller.target = jQuery(obj_caller.targetW);
+    }
 
-	var target = obj_caller.target;
-	write_value(value, target);
+    var target = obj_caller.target;
+    write_value(value, target);
 
-	closeLookup();
+    closeLookup();
 }
 // function passing selected value to calling window
 function set_values(value, value2) {
-	if (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP)) {
-		obj_caller.target = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).target;
-		obj_caller.target2 = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).target2;
-	} else {
-		obj_caller.target = jQuery(obj_caller.targetW);
-	}
-	var target = obj_caller.target;
-	var target2 = obj_caller.target2;
-	write_value(value, target);
-	write_value(value2, target2)
-	var showDescription = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP) ? GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).showDescription : false;
-	if (showDescription) {
-		setLookDescription(target.attr("id"), value + " " + value2, "", "", showDescription);
-	}
+    if (GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP)) {
+        obj_caller.target = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).target;
+        obj_caller.target2 = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).target2;
+    } else {
+        obj_caller.target = jQuery(obj_caller.targetW);
+    }
+    var target = obj_caller.target;
+    var target2 = obj_caller.target2;
+    write_value(value, target);
+    write_value(value2, target2)
+    var showDescription = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP) ? GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).showDescription : false;
+    if (showDescription) {
+        setLookDescription(target.attr("id"), value + " " + value2, "", "", showDescription);
+    }
 
-	closeLookup();
+    closeLookup();
 }
 
 function write_value(value, target) {
-	if (target && target != null) {
-		setSourceColor(target);
-		target.val(value);
-		target.trigger("lookup:changed");
-	}
+    if (target && target != null) {
+        setSourceColor(target);
+        target.val(value);
+        target.trigger("lookup:changed");
+    }
 }
 
 function set_multivalues(value) {
-	obj_caller.target.value = value;
-	field = jQuery("#" + target.attr('id'));
-	field.trigger("lookup:changed");
-	/*
-	 * If we decide to keep it (only used in Example, though it's needed also
-	 * for Themes and Languages but not the same way)
-	 */
-	if (field.change != null) {
-		field.click().change()
-	}
+    obj_caller.target.value = value;
+    field = jQuery("#" + target.attr('id'));
+    field.trigger("lookup:changed");
+    /*
+     * If we decide to keep it (only used in Example, though it's needed also
+     * for Themes and Languages but not the same way)
+     */
+    if (field.change != null) {
+        field.click().change()
+    }
 
-	var thisForm = obj_caller.target.form;
-	var evalString = "";
+    var thisForm = obj_caller.target.form;
+    var evalString = "";
 
-	if (arguments.length > 2) {
-		for ( var i = 1; i < arguments.length; i = i + 2) {
-			evalString = "setSourceColor(thisForm." + arguments[i] + ")";
-			eval(evalString);
-			evalString = "thisForm." + arguments[i] + ".value='" + arguments[i + 1] + "'";
-			eval(evalString);
-		}
-	}
-	closeLookup();
+    if (arguments.length > 2) {
+        for ( var i = 1; i < arguments.length; i = i + 2) {
+            evalString = "setSourceColor(thisForm." + arguments[i] + ")";
+            eval(evalString);
+            evalString = "thisForm." + arguments[i] + ".value='" + arguments[i + 1] + "'";
+            eval(evalString);
+        }
+    }
+    closeLookup();
 }
 
 // close the window after passing the value
 function closeLookup() {
-	if (window.opener != null && GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP) == null) {
-		window.close();
-	} else {
-		var lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
-		jQuery("#" + lookupId).dialog("close");
-	}
+    if (window.opener != null && GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP) == null) {
+        window.close();
+    } else {
+        var lookupId = GLOBAL_LOOKUP_REF.getReference(ACTIVATED_LOOKUP).lookupId;
+        jQuery("#" + lookupId).dialog("close");
+    }
 }
 
 /*******************************************************************************
@@ -791,55 +800,55 @@
  ******************************************************************************/
 // load description for lookup fields
 var lookupDescriptionLoaded = function(fieldId, url, params, formName) {
-	this.init(fieldId, url, params, formName);
+    this.init(fieldId, url, params, formName);
 }
 lookupDescriptionLoaded.prototype.init = function(fieldId, url, params, formName) {
-	this.fieldId = fieldId;
-	this.url = url;
-	this.params = params;
-	this.formName = formName;
+    this.fieldId = fieldId;
+    this.url = url;
+    this.params = params;
+    this.formName = formName;
 }
 lookupDescriptionLoaded.prototype.update = function() {
-	var tooltipElement = jQuery("#" + this.fieldId + '_lookupDescription');
-	if (tooltipElement.length) {// first remove current description
-		tooltipElement.remove();
-	}
+    var tooltipElement = jQuery("#" + this.fieldId + '_lookupDescription');
+    if (tooltipElement.length) {// first remove current description
+        tooltipElement.remove();
+    }
 
-	var indexOf = this.params.indexOf("searchValueFieldName");
-	if (indexOf == -1) {
-		return;
-	}
+    var indexOf = this.params.indexOf("searchValueFieldName");
+    if (indexOf == -1) {
+        return;
+    }
 
-	// actual server call
-	var fieldName = this.params.substring(indexOf);
-	fieldName = fieldName.substring(fieldName.indexOf("=") + 1);
-	fieldObj = jQuery("input[name=" + fieldName + "]", jQuery("form[name=" + this.formName + "]"));
-	if (fieldObj.val()) {
-		var fieldSerialized = fieldObj.serialize();
-		this.allParams = this.params + '&' + fieldSerialized + '&' + 'searchType=EQUALS';
-		var _fieldId = this.fieldId;
+    // actual server call
+    var fieldName = this.params.substring(indexOf);
+    fieldName = fieldName.substring(fieldName.indexOf("=") + 1);
+    fieldObj = jQuery("input[name=" + fieldName + "]", jQuery("form[name=" + this.formName + "]"));
+    if (fieldObj.val()) {
+        var fieldSerialized = fieldObj.serialize();
+        this.allParams = this.params + '&' + fieldSerialized + '&' + 'searchType=EQUALS';
+        var _fieldId = this.fieldId;
 
-		jQuery.ajax({
-			url : this.url,
-			type : "POST",
-			data : this.allParams,
-			async : false,
-			success : function(result) {
-				// This would be far more reliable if we were removing
-				// the widget boundaries in LookupDecorator using
-				// widgetVerbose in context :/
-				if (result.split("ajaxAutocompleteOptions.ftl -->")[1]) {
-					setLookDescription(_fieldId, result.split("ajaxAutocompleteOptions.ftl -->")[1].trim().split("<!--")[0].trim(),
-							"", "");
-				}
-			}
-		});
-	}
+        jQuery.ajax({
+            url : this.url,
+            type : "POST",
+            data : this.allParams,
+            async : false,
+            success : function(result) {
+                // This would be far more reliable if we were removing
+                // the widget boundaries in LookupDecorator using
+                // widgetVerbose in context :/
+                if (result.split("ajaxAutocompleteOptions.ftl -->")[1]) {
+                    setLookDescription(_fieldId, result.split("ajaxAutocompleteOptions.ftl -->")[1].trim().split("<!--")[0].trim(),
+                            "", "");
+                }
+            }
+        });
+    }
 }
 
 // Needed because IE8 does not implement trim yet
 if (typeof String.prototype.trim !== 'function') {
-	String.prototype.trim = function() {
-		return this.replace(/^\s+|\s+$/g, '');
-	}
+    String.prototype.trim = function() {
+        return this.replace(/^\s+|\s+$/g, '');
+    }
 }
\ No newline at end of file
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/service/src/org/ofbiz/service/eca/ServiceEcaSetField.java b/framework/service/src/org/ofbiz/service/eca/ServiceEcaSetField.java
index 8bef3f1..b5c6c56 100644
--- a/framework/service/src/org/ofbiz/service/eca/ServiceEcaSetField.java
+++ b/framework/service/src/org/ofbiz/service/eca/ServiceEcaSetField.java
@@ -56,15 +56,13 @@
     public void eval(Map<String, Object> context) {
         if (fieldName != null) {
             // try to expand the envName
-            if (UtilValidate.isEmpty(this.value)) {
-                if (UtilValidate.isNotEmpty(this.envName) && this.envName.startsWith("${")) {
-                    FlexibleStringExpander exp = FlexibleStringExpander.getInstance(this.envName);
-                    String s = exp.expandString(context);
-                    if (UtilValidate.isNotEmpty(s)) {
-                        value = s;
-                    }
-                    Debug.logInfo("Expanded String: " + s, module);
+            if (UtilValidate.isNotEmpty(this.envName) && this.envName.startsWith("${")) {
+                FlexibleStringExpander exp = FlexibleStringExpander.getInstance(this.envName);
+                String s = exp.expandString(context);
+                if (UtilValidate.isNotEmpty(s)) {
+                    value = s;
                 }
+                Debug.logInfo("Expanded String: " + s, module);
             }
             // TODO: rewrite using the ContextAccessor.java see hack below to be able to use maps for email notifications
             // check if target is a map and create/get from contaxt
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/webtools/webapp/webtools/WEB-INF/actions/entity/EntityMaint.groovy b/framework/webtools/webapp/webtools/WEB-INF/actions/entity/EntityMaint.groovy
index 40b6c16..f508454 100644
--- a/framework/webtools/webapp/webtools/WEB-INF/actions/entity/EntityMaint.groovy
+++ b/framework/webtools/webapp/webtools/WEB-INF/actions/entity/EntityMaint.groovy
@@ -60,7 +60,7 @@
     if (filterByGroupName && !filterByGroupName.equals(entityGroupName)) {
         return;
     }
-    if (filterByEntityName && !((String)entity.getEntityName()).toUpperCase().contains(filterByEntityName.toUpperCase())) {
+    if (filterByEntityName && !((String)entity.getEntityName()).toUpperCase().contains(filterByEntityName.toUpperCase().replace(" ", ""))) {
         return;
     }
     viewEntity = "N";
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/dtd/widget-common.xsd b/framework/widget/dtd/widget-common.xsd
index 1f14f5b..e5c55d3 100644
--- a/framework/widget/dtd/widget-common.xsd
+++ b/framework/widget/dtd/widget-common.xsd
@@ -516,4 +516,154 @@
             <xs:attribute type="xs:string" name="value" />
         </xs:complexType>
     </xs:element>
+    <xs:element name="parameter">
+        <xs:complexType>
+            <xs:attribute type="xs:string" name="param-name" use="required" />
+            <xs:attribute type="xs:string" name="from-field" />
+            <xs:attribute type="xs:string" name="value" />
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="auto-parameters-service">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude" />
+            </xs:sequence>
+            <xs:attribute name="service-name" type="xs:string">
+                <xs:annotation>
+                    <xs:documentation>The service name used to resolve parameters. If empty, use form defaultServiceName. Flexible string allowed.</xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="send-if-empty" default="true">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="auto-parameters-entity">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude" />
+            </xs:sequence>
+            <xs:attribute name="entity-name" type="xs:string">
+                <xs:annotation>
+                    <xs:documentation>The entity name used to resolve parameters. If empty use form defaultEntityName attribute. Flexible string allowed.</xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="include" default="pk">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="pk" />
+                        <xs:enumeration value="nonpk" />
+                        <xs:enumeration value="all" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+            <xs:attribute name="send-if-empty" default="true">
+                <xs:simpleType>
+                    <xs:restriction base="xs:token">
+                        <xs:enumeration value="true" />
+                        <xs:enumeration value="false" />
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:attribute>
+        </xs:complexType>
+    </xs:element>
+    <xs:element name="exclude">
+        <xs:complexType>
+            <xs:attribute name="field-name" type="xs:string" use="required" />
+        </xs:complexType>
+    </xs:element>
+    <xs:complexType name="link">
+        <xs:sequence>
+            <xs:element minOccurs="0" maxOccurs="unbounded" ref="parameter" />
+            <xs:element minOccurs="0" name="image" type="image" />
+        </xs:sequence>
+        <xs:attribute type="xs:string" name="text" />
+        <xs:attribute type="xs:string" name="id" />
+        <xs:attribute type="xs:string" name="style" />
+        <xs:attribute type="xs:string" name="name" />
+        <xs:attribute type="xs:string" name="title" />
+        <xs:attribute type="xs:nonNegativeInteger" name="size" /><!-- Text size limit -->
+        <xs:attribute type="xs:string" name="target" />
+        <xs:attribute type="xs:string" name="target-window" />
+        <xs:attribute type="xs:string" name="prefix" />
+        <xs:attribute type="xs:string" name="width" />
+        <xs:attribute type="xs:string" name="height" />
+        <xs:attribute name="link-type" default="auto">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <xs:enumeration value="auto">
+                        <xs:annotation>
+                            <xs:documentation>
+                                If selected the hidden-form type will be used if the url-mode is intra-app
+                                and the request specified has an event, otherwise the anchor type will be used,
+                                except if the ajax-window mode is specified.
+                            </xs:documentation>
+                        </xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="anchor" />
+                    <xs:enumeration value="hidden-form" />
+                        <!-- FIXME: This is not a link type. It indicates the target window should be a popup dialog. -->
+                    <xs:enumeration value="ajax-window" />
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute name="url-mode" default="intra-app">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <xs:enumeration value="intra-app" />
+                    <xs:enumeration value="inter-app" />
+                    <xs:enumeration value="content" />
+                    <xs:enumeration value="plain" />
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute name="full-path" default="false">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <xs:enumeration value="true" />
+                    <xs:enumeration value="false" />
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute name="secure" default="false">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <xs:enumeration value="true" />
+                    <xs:enumeration value="false" />
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+        <xs:attribute name="encode" default="false">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <xs:enumeration value="true" />
+                    <xs:enumeration value="false" />
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+    </xs:complexType>
+    <xs:complexType name="image" mixed="true">
+        <xs:attribute type="xs:string" name="src" />
+        <xs:attribute type="xs:string" name="id" />
+        <xs:attribute type="xs:string" name="style" />
+        <xs:attribute type="xs:string" name="width" />
+        <xs:attribute type="xs:string" name="height" />
+        <xs:attribute type="xs:string" name="border" />
+        <xs:attribute type="xs:string" name="alt" />
+        <xs:attribute type="xs:string" name="title" />
+        <xs:attribute name="url-mode" default="content">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <xs:enumeration value="ofbiz" />
+                    <xs:enumeration value="content" />
+                    <xs:enumeration value="raw" />
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
+    </xs:complexType>
 </xs:schema>
diff --git a/framework/widget/dtd/widget-form.xsd b/framework/widget/dtd/widget-form.xsd
index 09889ac..671f352 100644
--- a/framework/widget/dtd/widget-form.xsd
+++ b/framework/widget/dtd/widget-form.xsd
@@ -967,158 +967,61 @@
             <xs:attribute type="xs:string" name="value" />
         </xs:complexType>
     </xs:element>
-    <xs:element name="hyperlink" substitutionGroup="AllFields">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" ref="auto-parameters-service"/>
-                <xs:element minOccurs="0" ref="auto-parameters-entity"/>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="parameter" />
-            </xs:sequence>
-            <xs:attribute name="also-hidden" default="true">
-                <xs:annotation>
-                    <xs:documentation>If set to true, an hidden form field is also rendered, with the name of the field and its content.</xs:documentation>
-                </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="link-type" default="auto">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="auto">
-                            <xs:annotation>
-                                <xs:documentation>If selected the hidden-form type will be used if the url-mode is intra-app and the request specified has an event, otherwise the anchor type will be used.</xs:documentation>
-                            </xs:annotation>
-                        </xs:enumeration>
-                        <xs:enumeration value="anchor" />
-                        <xs:enumeration value="hidden-form" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="target-type" default="intra-app">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="intra-app" />
-                        <xs:enumeration value="inter-app" />
-                        <xs:enumeration value="content" />
-                        <xs:enumeration value="plain" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="target" use="required">
-                <xs:annotation>
-                    <xs:documentation>The target location of the hyperlink; can use the ${} syntax to substitute values from the context.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="description">
-                <xs:annotation>
-                    <xs:documentation>Specifies the string to display, can use the ${} syntax to insert context values; if empty the value of the field will be printed for a default.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="target-window" />
-            <xs:attribute type="xs:string" name="alternate">
-                <xs:annotation>
-                    <xs:documentation>Alternate text if the image is not found at image-location</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="image-title">
-                <xs:annotation>
-                    <xs:documentation>Use as a title for the HTML img tag</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="image-location" />
-            <xs:attribute name="request-confirmation" default="false">
-                <xs:annotation>
-                    <xs:documentation>If true then the user is presented with a dialog box, if confirmation-message is empty, use default</xs:documentation>
-                </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="confirmation-message" type="xs:string">
-                <xs:annotation>
-                    <xs:documentation>The message displayed in confirmation box</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="parameters-map" type="xs:string">
-                <xs:annotation>
-                    <xs:documentation>A Map in the context that will be used as additional name/value pairs.</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute type="xs:integer" name="size">
-                <xs:annotation>
-                    <xs:documentation>Specifies the size of the field (as a number of characters), when the text to display exceed the given size it is truncated and add the complete text as a hint</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="parameter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="param-name" use="required" />
-            <xs:attribute type="xs:string" name="from-field" />
-            <xs:attribute type="xs:string" name="value" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="auto-parameters-service">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude"/>
-            </xs:sequence>
-            <xs:attribute name="service-name" type="xs:string">
-                 <xs:annotation>
-                     <xs:documentation>The service name used to resolve parameters. If empty, use form defaultServiceName. Flexible string allowed.</xs:documentation>
-                 </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="send-if-empty" default="true">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true"/>
-                        <xs:enumeration value="false"/>
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="auto-parameters-entity">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude"/>
-            </xs:sequence>
-            <xs:attribute name="entity-name" type="xs:string">
-                 <xs:annotation>
-                     <xs:documentation>The entity name used to resolve parameters. If empty use form defaultEntityName attribute. Flexible string allowed.</xs:documentation>
-                 </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="include" default="pk">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="pk"/>
-                        <xs:enumeration value="nonpk"/>
-                        <xs:enumeration value="all"/>
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="send-if-empty" default="true">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true"/>
-                        <xs:enumeration value="false"/>
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="exclude">
-        <xs:complexType>
-            <xs:attribute name="field-name" type="xs:string" use="required"/>
-        </xs:complexType>
-    </xs:element>
+    <xs:complexType name="hyperlink">
+        <xs:complexContent>
+            <xs:extension base="link">
+                <xs:attribute type="xs:string" name="description">
+                    <xs:annotation>
+                        <xs:documentation>Specifies the string to display, can use the ${} syntax to insert context values; if empty the value of the field will be printed for a default.</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+                <xs:attribute name="request-confirmation" default="false">
+                    <xs:annotation>
+                        <xs:documentation>If true then the user is presented with a dialog box, if confirmation-message is empty, use default</xs:documentation>
+                    </xs:annotation>
+                    <xs:simpleType>
+                        <xs:restriction base="xs:token">
+                            <xs:enumeration value="true" />
+                            <xs:enumeration value="false" />
+                        </xs:restriction>
+                    </xs:simpleType>
+                </xs:attribute>
+                <xs:attribute name="confirmation-message" type="xs:string">
+                    <xs:annotation>
+                        <xs:documentation>The message displayed in confirmation box</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+                <xs:attribute name="also-hidden" default="true">
+                    <xs:annotation>
+                        <xs:documentation>If set to true, an hidden form field is also rendered, with the name of the field and its content.</xs:documentation>
+                    </xs:annotation>
+                    <xs:simpleType>
+                        <xs:restriction base="xs:token">
+                            <xs:enumeration value="true" />
+                            <xs:enumeration value="false" />
+                        </xs:restriction>
+                    </xs:simpleType>
+                </xs:attribute>
+                <!-- These attributes have been replaced by the image element -->
+                <xs:attribute type="xs:string" name="alternate">
+                    <xs:annotation>
+                        <xs:documentation>Deprecated - use the image element.</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+                <xs:attribute type="xs:string" name="image-title">
+                    <xs:annotation>
+                        <xs:documentation>Deprecated - use the image element.</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+                <xs:attribute type="xs:string" name="image-location">
+                    <xs:annotation>
+                        <xs:documentation>Deprecated - use the image element.</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="hyperlink" type="hyperlink" substitutionGroup="AllFields"/>
     <xs:element name="ignored" substitutionGroup="AllFields">
         <xs:complexType/>
     </xs:element>
@@ -1760,43 +1663,19 @@
             <xs:attribute name="cols" type="xs:positiveInteger" default="40" />
         </xs:complexType>
     </xs:element>
-    <xs:element name="sub-hyperlink">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" ref="auto-parameters-service"/>
-                <xs:element minOccurs="0" ref="auto-parameters-entity"/>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="parameter" />
-            </xs:sequence>
+    <xs:complexType name="sub-hyperlink">
+        <xs:complexContent>
+            <xs:extension base="link">
+                <xs:attribute type="xs:string" name="description">
+                    <xs:annotation>
+                        <xs:documentation>Specifies the string to display, can use the ${} syntax to insert context values; if empty the value of the field will be printed for a default.</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
             <xs:attribute type="xs:string" name="use-when" />
-            <xs:attribute type="xs:string" name="link-style" />
-            <xs:attribute name="link-type" default="auto">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="auto">
-                            <xs:annotation>
-                                <xs:documentation>If selected the hidden-form type will be used if the url-mode is intra-app and the request specified has an event, otherwise the anchor type will be used.</xs:documentation>
-                            </xs:annotation>
-                        </xs:enumeration>
-                        <xs:enumeration value="anchor" />
-                        <xs:enumeration value="hidden-form" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="target-type" default="intra-app">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="intra-app" />
-                        <xs:enumeration value="inter-app" />
-                        <xs:enumeration value="content" />
-                        <xs:enumeration value="plain" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute type="xs:string" name="target" use="required" />
-            <xs:attribute type="xs:string" name="description" />
-            <xs:attribute type="xs:string" name="target-window" />
-        </xs:complexType>
-    </xs:element>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
+    <xs:element name="sub-hyperlink" type="sub-hyperlink"/>
 
   <!-- ================== ACTIONS ==================== -->
     <xs:element name="actions">
diff --git a/framework/widget/dtd/widget-menu.xsd b/framework/widget/dtd/widget-menu.xsd
index 2b66e58..6eb146b 100644
--- a/framework/widget/dtd/widget-menu.xsd
+++ b/framework/widget/dtd/widget-menu.xsd
@@ -158,167 +158,7 @@
             </xs:attribute>
         </xs:complexType>
     </xs:element>
-    <xs:element name="image">
-        <xs:complexType mixed="true">
-            <xs:attribute type="xs:string" name="src" />
-            <xs:attribute type="xs:string" name="id" />
-            <xs:attribute type="xs:string" name="style" />
-            <xs:attribute type="xs:string" name="width" />
-            <xs:attribute type="xs:string" name="height" />
-            <xs:attribute type="xs:string" name="border" />
-            <xs:attribute name="url-mode" default="content">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="ofbiz" />
-                        <xs:enumeration value="content" />
-                        <xs:enumeration value="raw" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="link">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" ref="auto-parameters-service"/>
-                <xs:element minOccurs="0" ref="auto-parameters-entity"/>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="parameter" />
-                <xs:element minOccurs="0" ref="image" />
-            </xs:sequence>
-            <xs:attribute type="xs:string" name="text" />
-            <xs:attribute type="xs:string" name="id" />
-            <xs:attribute type="xs:string" name="style" />
-            <xs:attribute type="xs:string" name="name" />
-            <xs:attribute type="xs:string" name="target" />
-            <xs:attribute type="xs:string" name="target-window" />
-            <xs:attribute type="xs:string" name="prefix" />
-            <xs:attribute name="link-type" default="auto">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="auto">
-                            <xs:annotation>
-                                <xs:documentation>If selected the hidden-form type will be used if the url-mode is intra-app and the request specified has an event, otherwise the anchor type will be used.</xs:documentation>
-                            </xs:annotation>
-                        </xs:enumeration>
-                        <xs:enumeration value="anchor" />
-                        <xs:enumeration value="hidden-form" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="url-mode" default="intra-app">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="intra-app" />
-                        <xs:enumeration value="inter-app" />
-                        <xs:enumeration value="content" />
-                        <xs:enumeration value="plain" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="full-path" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="secure" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="encode" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="request-confirmation" default="false">
-                <xs:annotation>
-                    <xs:documentation>If true then the user is presented with a dialog box requesting confirmation prior to proceeding</xs:documentation>
-                </xs:annotation>
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="confirmation-message" type="xs:string">
-                <xs:annotation>
-                    <xs:documentation>The message displayed when request-confirm is set to true</xs:documentation>
-                </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="parameters-map" type="xs:string" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="parameter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="param-name" use="required" />
-            <xs:attribute type="xs:string" name="from-field" />
-            <xs:attribute type="xs:string" name="value" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="auto-parameters-service">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude"/>
-            </xs:sequence>
-            <xs:attribute name="service-name" type="xs:string" use="required">
-                 <xs:annotation>
-                     <xs:documentation>The service name used to resolve parameters. Flexible string allowed.</xs:documentation>
-                 </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="send-if-empty" default="true">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true"/>
-                        <xs:enumeration value="false"/>
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="auto-parameters-entity">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="exclude"/>
-            </xs:sequence>
-            <xs:attribute name="entity-name" type="xs:string">
-                 <xs:annotation>
-                     <xs:documentation>The entity name used to resolve parameters. If empty try use menu defaultEntityName attribute. Flexible string allowed.</xs:documentation>
-                 </xs:annotation>
-            </xs:attribute>
-            <xs:attribute name="include" default="pk">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="pk"/>
-                        <xs:enumeration value="nonpk"/>
-                        <xs:enumeration value="all"/>
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="send-if-empty" default="true">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true"/>
-                        <xs:enumeration value="false"/>
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="exclude">
-        <xs:complexType>
-            <xs:attribute name="field-name" type="xs:string" use="required"/>
-        </xs:complexType>
-    </xs:element>
+    <xs:element name="link" type="link"/>
 
     <xs:element name="actions">
         <xs:complexType>
diff --git a/framework/widget/dtd/widget-screen.xsd b/framework/widget/dtd/widget-screen.xsd
index 080d2ac..9821852 100644
--- a/framework/widget/dtd/widget-screen.xsd
+++ b/framework/widget/dtd/widget-screen.xsd
@@ -304,78 +304,7 @@
             <xs:attribute type="xs:string" name="style" />
         </xs:complexType>
     </xs:element>
-    <xs:element name="link" substitutionGroup="AllWidgets">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" ref="auto-parameters-service" />
-                <xs:element minOccurs="0" ref="auto-parameters-entity" />
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="parameter" />
-                <xs:element minOccurs="0" ref="image" />
-            </xs:sequence>
-            <xs:attribute type="xs:string" name="text" />
-            <xs:attribute type="xs:string" name="id" />
-            <xs:attribute type="xs:string" name="style" />
-            <xs:attribute type="xs:string" name="target" />
-            <xs:attribute type="xs:string" name="name" />
-            <xs:attribute type="xs:string" name="target-window" />
-            <xs:attribute type="xs:string" name="prefix" />
-            <xs:attribute type="xs:string" name="width" />
-            <xs:attribute type="xs:string" name="height" />
-            <xs:attribute name="link-type" default="auto">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="auto">
-                            <xs:annotation>
-                                <xs:documentation>
-                                    If selected the hidden-form type will be used if the url-mode is intra-app
-                                    and the request specified has an event, otherwise the anchor type will be used,
-                                    except if the ajax-window mode is specified.
-                                </xs:documentation>
-                            </xs:annotation>
-                        </xs:enumeration>
-                        <xs:enumeration value="anchor" />
-                        <xs:enumeration value="hidden-form" />
-                        <!-- FIXME: This is not a link type. It indicates the target window should be a popup dialog. -->
-                        <xs:enumeration value="ajax-window" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="url-mode" default="intra-app">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="intra-app" />
-                        <xs:enumeration value="inter-app" />
-                        <xs:enumeration value="content" />
-                        <xs:enumeration value="plain" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="full-path" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="secure" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="encode" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
+    <xs:element name="link" type="link" substitutionGroup="AllWidgets"/>
 
     <xs:element name="screenlet" substitutionGroup="AllWidgets">
         <xs:complexType>
diff --git a/framework/widget/dtd/widget-tree.xsd b/framework/widget/dtd/widget-tree.xsd
index 1c59863..e09c88d 100644
--- a/framework/widget/dtd/widget-tree.xsd
+++ b/framework/widget/dtd/widget-tree.xsd
@@ -127,82 +127,7 @@
             <xs:attribute type="xs:string" name="style" />
         </xs:complexType>
     </xs:element>
-    <xs:element name="link">
-        <xs:complexType>
-            <xs:sequence>
-                <xs:element minOccurs="0" maxOccurs="unbounded" ref="parameter" />
-                <xs:element minOccurs="0" ref="image" />
-            </xs:sequence>
-            <xs:attribute type="xs:string" name="text" />
-            <xs:attribute type="xs:string" name="id" />
-            <xs:attribute type="xs:string" name="style" />
-            <xs:attribute type="xs:string" name="name" />
-            <xs:attribute type="xs:string" name="title" />
-            <xs:attribute type="xs:string" name="target" />
-            <xs:attribute type="xs:string" name="target-window" />
-            <xs:attribute type="xs:string" name="prefix" />
-            <xs:attribute name="url-mode" default="intra-app">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="intra-app" />
-                        <xs:enumeration value="inter-app" />
-                        <xs:enumeration value="content" />
-                        <xs:enumeration value="plain" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="full-path" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="secure" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-            <xs:attribute name="encode" default="false">
-                <xs:simpleType>
-                    <xs:restriction base="xs:token">
-                        <xs:enumeration value="true" />
-                        <xs:enumeration value="false" />
-                    </xs:restriction>
-                </xs:simpleType>
-            </xs:attribute>
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="parameter">
-        <xs:complexType>
-            <xs:attribute type="xs:string" name="param-name" use="required" />
-            <xs:attribute type="xs:string" name="from-field" />
-            <xs:attribute type="xs:string" name="value" />
-        </xs:complexType>
-    </xs:element>
-    <xs:element name="image">
-        <xs:complexType mixed="true">
-        <xs:attribute type="xs:string" name="src"/>
-        <xs:attribute type="xs:string" name="id"/>
-        <xs:attribute type="xs:string" name="style"/>
-        <xs:attribute type="xs:string" name="width"/>
-        <xs:attribute type="xs:string" name="height"/>
-        <xs:attribute type="xs:string" name="border"/>
-        <xs:attribute name="url-mode" default="content">
-            <xs:simpleType>
-                <xs:restriction base="xs:token">
-                    <xs:enumeration value="ofbiz"/>
-                    <xs:enumeration value="content"/>
-                    <xs:enumeration value="raw"/>
-                </xs:restriction>
-            </xs:simpleType>
-        </xs:attribute>
-        </xs:complexType>
-    </xs:element>
+    <xs:element name="link" type="link"/>
     <xs:element name="actions">
         <xs:complexType>
             <xs:sequence>
diff --git a/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java b/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java
deleted file mode 100644
index a0bb5e0..0000000
--- a/framework/widget/src/org/ofbiz/widget/ModelActionVisitor.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*******************************************************************************
- * 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.widget.form.ModelFormAction;
-import org.ofbiz.widget.menu.ModelMenuAction;
-import org.ofbiz.widget.tree.ModelTreeAction;
-
-/**
- *  A <code>ModelWidgetAction</code> visitor.
- */
-public interface ModelActionVisitor {
-
-    void visit(ModelFormAction.CallParentActions callParentActions);
-
-    void visit(ModelWidgetAction.EntityAnd entityAnd);
-
-    void visit(ModelWidgetAction.EntityCondition entityCondition);
-
-    void visit(ModelWidgetAction.EntityOne entityOne);
-
-    void visit(ModelWidgetAction.GetRelated getRelated);
-
-    void visit(ModelWidgetAction.GetRelatedOne getRelatedOne);
-
-    void visit(ModelWidgetAction.PropertyMap propertyMap);
-
-    void visit(ModelWidgetAction.PropertyToField propertyToField);
-
-    void visit(ModelWidgetAction.Script script);
-
-    void visit(ModelWidgetAction.Service service);
-
-    void visit(ModelWidgetAction.SetField setField);
-
-    void visit(ModelFormAction.Service service);
-
-    void visit(ModelMenuAction.SetField setField);
-
-    void visit(ModelTreeAction.Script script);
-
-    void visit(ModelTreeAction.Service service);
-
-    void visit(ModelTreeAction.EntityAnd entityAnd);
-
-    void visit(ModelTreeAction.EntityCondition entityCondition);
-}
diff --git a/framework/widget/src/org/ofbiz/widget/ModelFieldVisitor.java b/framework/widget/src/org/ofbiz/widget/ModelFieldVisitor.java
deleted file mode 100644
index 216f195..0000000
--- a/framework/widget/src/org/ofbiz/widget/ModelFieldVisitor.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************************
- * 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.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;
-
-/**
- *  A <code>ModelFormField</code> visitor.
- */
-public interface ModelFieldVisitor {
-
-    void visit(CheckField checkField);
-
-    void visit(ContainerField containerField);
-
-    void visit(DateFindField dateTimeField);
-
-    void visit(DateTimeField dateTimeField);
-
-    void visit(DisplayEntityField displayField);
-
-    void visit(DisplayField displayField);
-
-    void visit(DropDownField dropDownField);
-
-    void visit(FileField textField);
-
-    void visit(HiddenField hiddenField);
-
-    void visit(HyperlinkField hyperlinkField);
-
-    void visit(IgnoredField ignoredField);
-
-    void visit(ImageField imageField);
-
-    void visit(LookupField textField);
-
-    void visit(PasswordField textField);
-
-    void visit(RadioField radioField);
-
-    void visit(RangeFindField textField);
-
-    void visit(ResetField resetField);
-
-    void visit(SubmitField submitField);
-
-    void visit(TextareaField textareaField);
-
-    void visit(TextField textField);
-
-    void visit(TextFindField textField);
-}
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 c4a7fc3..18a7be3 100644
--- a/framework/widget/src/org/ofbiz/widget/WidgetWorker.java
+++ b/framework/widget/src/org/ofbiz/widget/WidgetWorker.java
@@ -20,16 +20,9 @@
 
 import java.io.IOException;
 import java.io.StringWriter;
-import java.math.BigDecimal;
 import java.net.URLEncoder;
 import java.nio.charset.Charset;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
-import java.util.TimeZone;
 
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -37,33 +30,23 @@
 
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilCodec;
-import org.ofbiz.base.util.UtilDateTime;
 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.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.model.ModelEntity;
-import org.ofbiz.entity.model.ModelField;
-import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.service.ModelParam;
-import org.ofbiz.service.ModelService;
 import org.ofbiz.webapp.control.ConfigXMLReader;
 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.w3c.dom.Element;
+import org.ofbiz.widget.model.ModelForm;
+import org.ofbiz.widget.model.ModelFormField;
 
-public class WidgetWorker {
+public final class WidgetWorker {
 
     public static final String module = WidgetWorker.class.getName();
 
-    public WidgetWorker () {}
+    private WidgetWorker () {}
 
     public static void buildHyperlinkUrl(Appendable externalWriter, String target, String targetType, Map<String, String> parameterMap,
             String prefix, boolean fullPath, boolean secure, boolean encode, HttpServletRequest request, HttpServletResponse response, Map<String, Object> context) throws IOException {
@@ -329,202 +312,6 @@
             return formName + modelForm.getItemIndexSeparator() + modelFormField.getName();
         }
     }
-
-    /**
-     * Models the &lt;parameter&gt; element.
-     * 
-     * @see <code>widget-form.xsd</code>
-     */
-    public static class Parameter {
-        protected String name;
-        protected FlexibleStringExpander value;
-        protected FlexibleMapAccessor<Object> fromField;
-
-        public Parameter(Element element) {
-            this.name = element.getAttribute("param-name");
-            this.value = UtilValidate.isNotEmpty(element.getAttribute("value")) ? FlexibleStringExpander.getInstance(element.getAttribute("value")) : null;
-            this.fromField = UtilValidate.isNotEmpty(element.getAttribute("from-field")) ? FlexibleMapAccessor.getInstance(element.getAttribute("from-field")) : null;
-        }
-
-        public Parameter(String paramName, String paramValue, boolean isField) {
-            this.name = paramName;
-            if (isField) {
-                this.fromField = FlexibleMapAccessor.getInstance(paramValue);
-            } else {
-                this.value = FlexibleStringExpander.getInstance(paramValue);
-            }
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public String getValue(Map<String, Object> context) {
-            if (this.value != null) {
-                return this.value.expandString(context);
-            }
-
-            Object retVal = null;
-            if (this.fromField != null && this.fromField.get(context) != null) {
-                retVal = this.fromField.get(context);
-            } else {
-                retVal = context.get(this.name);
-            }
-
-            if (retVal != null) {
-                TimeZone timeZone = (TimeZone) context.get("timeZone");
-                if (timeZone == null) timeZone = TimeZone.getDefault();
-
-                String returnValue = null;
-                // format string based on the user's time zone (not locale because these are parameters)
-                if (retVal instanceof Double || retVal instanceof Float || retVal instanceof BigDecimal) {
-                    returnValue = retVal.toString();
-                } else if (retVal instanceof java.sql.Date) {
-                    DateFormat df = UtilDateTime.toDateFormat(UtilDateTime.DATE_FORMAT, timeZone, null);
-                    returnValue = df.format((java.util.Date) retVal);
-                } else if (retVal instanceof java.sql.Time) {
-                    DateFormat df = UtilDateTime.toTimeFormat(UtilDateTime.TIME_FORMAT, timeZone, null);
-                    returnValue = df.format((java.util.Date) retVal);
-                } else if (retVal instanceof java.sql.Timestamp) {
-                    DateFormat df = UtilDateTime.toDateTimeFormat(UtilDateTime.DATE_TIME_FORMAT, timeZone, null);
-                    returnValue = 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);
-                    returnValue = df.format((java.util.Date) retVal);
-                } else {
-                    returnValue = retVal.toString();
-                }
-                return returnValue;
-            } else {
-                return null;
-            }
-        }
-    }
-
-    public static class AutoServiceParameters {
-        private String serviceName;
-        List<String> excludeList = new ArrayList<String>();
-        boolean includePk;
-        boolean includeNonPk;
-        boolean sendIfEmpty;
-        public AutoServiceParameters(Element autoElement){
-            serviceName = UtilXml.checkEmpty(autoElement.getAttribute("service-name"));
-            sendIfEmpty = "true".equals(autoElement.getAttribute("send-if-empty"));
-            List<? extends Element> excludes = UtilXml.childElementList(autoElement, "exclude");
-            if (excludes != null) {
-                for (Element exclude: excludes) {
-                    if (UtilValidate.isNotEmpty(exclude.getAttribute("field-name"))) {
-                        excludeList.add(exclude.getAttribute("field-name"));
-                    }
-                }
-            }
-        }
-
-        @SuppressWarnings("unchecked")
-        public Map<String, String> getParametersMap(Map<String, Object> context, String defaultServiceName) {
-            Map<String, String> autServiceParams = new HashMap<String, String>();
-            LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
-            if (dispatcher == null) {
-                Debug.logError("We can not append auto service Parameters since we could not find dispatcher in the current context", module);
-                return autServiceParams;
-            }
-            if (UtilValidate.isEmpty(serviceName)) serviceName = defaultServiceName;
-            FlexibleStringExpander toExpand = FlexibleStringExpander.getInstance(serviceName);
-            ModelService service = null;
-            try {
-                service = dispatcher.getDispatchContext().getModelService(toExpand.toString());
-            } catch (GenericServiceException e) {
-                Debug.logError("Resolve service throw an error : " + e, module);
-            }
-            if (service == null) {
-                Debug.logError("We can not append auto service Parameters since we could not find service with name [" + serviceName + "]", module);
-                return autServiceParams;
-            }
-
-            Iterator<ModelParam> paramsIter = service.getInModelParamList().iterator();
-            if (paramsIter != null) {
-                while (paramsIter.hasNext()) {
-                    ModelParam param = paramsIter.next();
-                    if (param.getInternal()) continue;
-                    String paramName = param.getName();
-                    FlexibleMapAccessor<Object> fma = FlexibleMapAccessor.getInstance(paramName);
-                    if (!excludeList.contains(paramName)) {
-                        Object flexibleValue = fma.get(context);
-                        if (UtilValidate.isEmpty(flexibleValue) && context.containsKey("parameters")) {
-                            flexibleValue = fma.get((Map<String, ? extends Object>) context.get("parameters"));
-                        }
-                        if (UtilValidate.isNotEmpty(flexibleValue) || sendIfEmpty) {
-                            autServiceParams.put(paramName, String.valueOf(flexibleValue));
-                        }
-                    }
-                }
-            }
-            return autServiceParams;
-        }
-    }
-
-    public static class AutoEntityParameters {
-        private String entityName;
-        private String includeType;
-        List<String> excludeList = new ArrayList<String>();
-        boolean includePk;
-        boolean includeNonPk;
-        boolean sendIfEmpty;
-        public AutoEntityParameters(Element autoElement){
-            entityName = UtilXml.checkEmpty(autoElement.getAttribute("entity-name"));
-            sendIfEmpty = "true".equals(autoElement.getAttribute("send-if-empty"));
-            includeType = UtilXml.checkEmpty(autoElement.getAttribute("include"));
-            includePk = "pk".equals(includeType) || "all".equals(includeType);
-            includeNonPk = "nonpk".equals(includeType) || "all".equals(includeType);
-            List<? extends Element> excludes = UtilXml.childElementList(autoElement, "exclude");
-            if (excludes != null) {
-                for (Element exclude: excludes) {
-                    if (UtilValidate.isNotEmpty(exclude.getAttribute("field-name"))) {
-                        excludeList.add(exclude.getAttribute("field-name"));
-                    }
-                }
-            }
-        }
-
-        @SuppressWarnings("unchecked")
-        public Map<String, String> getParametersMap(Map<String, Object> context, String defaultEntityName) {
-            Map<String, String> autEntityParams = new HashMap<String, String>();
-            Delegator delegator = (Delegator) context.get("delegator");
-            if (delegator == null) {
-                Debug.logError("We can not append auto entity Parameters since we could not find delegator in the current context", module);
-                return autEntityParams;
-            }
-            if (UtilValidate.isEmpty(entityName)) entityName = defaultEntityName;
-            FlexibleStringExpander toExpand = FlexibleStringExpander.getInstance(entityName);
-            ModelEntity entity = delegator.getModelEntity(toExpand.expandString(context));
-            if (entity == null) {
-                Debug.logError("We can not append auto entity Parameters since we could not find entity with name [" + entityName + "]", module);
-                return autEntityParams;
-            }
-
-            Iterator<ModelField> fieldsIter = entity.getFieldsIterator();
-            if (fieldsIter != null) {
-                while (fieldsIter.hasNext()) {
-                    ModelField field = fieldsIter.next();
-                    String fieldName = field.getName();
-                    FlexibleMapAccessor<Object> fma = FlexibleMapAccessor.getInstance(fieldName);
-                    boolean shouldExclude = excludeList.contains(fieldName);
-                    if ((!shouldExclude) && (!field.getIsAutoCreatedInternal())
-                            && ((field.getIsPk() && includePk) || (!field.getIsPk() && includeNonPk))) {
-                        Object flexibleValue = fma.get(context);
-                        if (UtilValidate.isEmpty(flexibleValue) && context.containsKey("parameters")) {
-                            flexibleValue = fma.get((Map<String, Object>) context.get("parameters"));
-                        }
-                        if (UtilValidate.isNotEmpty(flexibleValue) || sendIfEmpty) {
-                            autEntityParams.put(fieldName, String.valueOf(flexibleValue));
-                        }
-                    }
-                }
-            }
-            return autEntityParams;
-        }
-    }
-
     public static String determineAutoLinkType(String linkType, String target, String targetType, HttpServletRequest request) {
         if ("auto".equals(linkType)) {
             if ("intra-app".equals(targetType)) {
diff --git a/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java b/framework/widget/src/org/ofbiz/widget/artifact/ArtifactInfoGatherer.java
index 4eb506d..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.ModelActionVisitor;
-import org.ofbiz.widget.ModelFieldVisitor;
-import org.ofbiz.widget.ModelWidgetAction;
-import org.ofbiz.widget.ModelWidgetAction.EntityAnd;
-import org.ofbiz.widget.ModelWidgetAction.EntityCondition;
-import org.ofbiz.widget.ModelWidgetAction.EntityOne;
-import org.ofbiz.widget.ModelWidgetAction.GetRelated;
-import org.ofbiz.widget.ModelWidgetAction.GetRelatedOne;
-import org.ofbiz.widget.ModelWidgetAction.PropertyMap;
-import org.ofbiz.widget.ModelWidgetAction.PropertyToField;
-import org.ofbiz.widget.ModelWidgetAction.Script;
-import org.ofbiz.widget.ModelWidgetAction.Service;
-import org.ofbiz.widget.ModelWidgetAction.SetField;
-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.Image;
-import org.ofbiz.widget.screen.ModelScreenWidget.IncludeScreen;
-import org.ofbiz.widget.screen.ModelScreenWidget.Label;
-import org.ofbiz.widget.screen.ModelScreenWidget.Link;
-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.
@@ -113,58 +113,88 @@
     }
 
     @Override
-    public void visit(CallParentActions callParentActions) {
+    public void visit(CallParentActions callParentActions) throws Exception {
     }
 
     @Override
-    public void visit(EntityAnd entityAnd) {
+    public void visit(Column column) throws Exception {
+    }
+
+    @Override
+    public void visit(ColumnContainer columnContainer) throws Exception {
+        for (Column column : columnContainer.getColumns()) {
+            for (ModelScreenWidget widget : column.getSubWidgets()) {
+                widget.accept(this);
+            }
+        }
+    }
+
+    @Override
+    public void visit(Container container) throws Exception {
+        for (ModelScreenWidget widget : container.getSubWidgets()) {
+            widget.accept(this);
+        }
+    }
+
+    @Override
+    public void visit(Content content) throws Exception {
+        infoContext.addEntityName("Content");
+        if (!content.getDataResourceId().isEmpty()) {
+            infoContext.addEntityName("DataResource");
+        }
+    }
+
+    @Override
+    public void visit(DecoratorScreen decoratorScreen) throws Exception {
+        for (ModelScreenWidget section : decoratorScreen.getSectionMap().values()) {
+            section.accept(this);
+        }
+    }
+
+    @Override
+    public void visit(DecoratorSection decoratorSection) throws Exception {
+        for (ModelScreenWidget widget : decoratorSection.getSubWidgets()) {
+            widget.accept(this);
+        }
+    }
+
+    @Override
+    public void visit(DecoratorSectionInclude decoratorSectionInclude) throws Exception {
+    }
+
+    @Override
+    public void visit(EntityAnd entityAnd) throws Exception {
         infoContext.addEntityName(entityAnd.getFinder().getEntityName());
     }
 
     @Override
-    public void visit(EntityCondition entityCondition) {
+    public void visit(EntityCondition entityCondition) throws Exception {
         infoContext.addEntityName(entityCondition.getFinder().getEntityName());
     }
 
     @Override
-    public void visit(EntityOne entityOne) {
+    public void visit(EntityOne entityOne) throws Exception {
         infoContext.addEntityName(entityOne.getFinder().getEntityName());
     }
 
     @Override
-    public void visit(GetRelated getRelated) {
+    public void visit(Form form) throws Exception {
+        String formLocation = form.getLocation().concat("#").concat(form.getName());
+        infoContext.addFormLocation(formLocation);
+    }
+
+    @Override
+    public void visit(GetRelated getRelated) throws Exception {
         infoContext.addEntityName(getRelated.getRelationName());
     }
 
     @Override
-    public void visit(GetRelatedOne getRelatedOne) {
+    public void visit(GetRelatedOne getRelatedOne) throws Exception {
         infoContext.addEntityName(getRelatedOne.getRelationName());
     }
 
     @Override
-    public void visit(PropertyMap propertyMap) {
-    }
-
-    @Override
-    public void visit(PropertyToField propertyToField) {
-    }
-
-    @Override
-    public void visit(Script script) {
-    }
-
-    @Override
-    public void visit(Service service) {
-        infoContext.addServiceName(service.getServiceNameExdr().getOriginal());
-        // TODO: Look for entityName in performFind service call
-    }
-
-    @Override
-    public void visit(SetField setField) {
-    }
-
-    @Override
-    public void visit(HtmlWidget htmlWidget) throws Exception {
+    public void visit(HorizontalSeparator horizontalSeparator) throws Exception {
     }
 
     @Override
@@ -180,6 +210,14 @@
     }
 
     @Override
+    public void visit(HtmlWidget htmlWidget) throws Exception {
+    }
+
+    @Override
+    public void visit(IncludeScreen includeScreen) throws Exception {
+    }
+
+    @Override
     public void visit(IterateSectionWidget iterateSectionWidget) throws Exception {
         for (Section section : iterateSectionWidget.getSectionList()) {
             section.accept(this);
@@ -187,14 +225,22 @@
     }
 
     @Override
+    public void visit(Label label) throws Exception {
+    }
+
+    @Override
+    public void visit(Menu menu) throws Exception {
+    }
+
+    @Override
     public void visit(ModelForm modelForm) throws Exception {
         if (modelForm.getActions() != null) {
-            for (ModelWidgetAction action : modelForm.getActions()) {
+            for (ModelAction action : modelForm.getActions()) {
                 action.accept(this);
             }
         }
         if (modelForm.getRowActions() != null) {
-            for (ModelWidgetAction action : modelForm.getRowActions()) {
+            for (ModelAction action : modelForm.getRowActions()) {
                 action.accept(this);
             }
         }
@@ -265,7 +311,7 @@
     }
 
     @Override
-    public void visit(ModelFormAction.Service service) {
+    public void visit(ModelFormAction.Service service) throws Exception {
         infoContext.addServiceName(service.getServiceName());
         // TODO: Look for entityName in performFind service call
     }
@@ -275,7 +321,7 @@
     }
 
     @Override
-    public void visit(ModelMenuAction.SetField setField) {
+    public void visit(ModelMenuAction.SetField setField) throws Exception {
     }
 
     @Override
@@ -283,6 +329,10 @@
     }
 
     @Override
+    public void visit(ModelNode modelNode) throws Exception {
+    }
+
+    @Override
     public void visit(ModelScreen modelScreen) throws Exception {
         String screenLocation = modelScreen.getSourceLocation().concat("#").concat(modelScreen.getName());
         infoContext.addScreenLocation(screenLocation);
@@ -290,71 +340,58 @@
     }
 
     @Override
-    public void visit(ColumnContainer columnContainer) throws Exception {
-        for (Column column : columnContainer.getColumns()) {
-            for (ModelScreenWidget widget : column.getSubWidgets()) {
-                widget.accept(this);
-            }
-        }
+    public void visit(ModelSubNode modelSubNode) throws Exception {
     }
 
     @Override
-    public void visit(Container container) throws Exception {
-        for (ModelScreenWidget widget : container.getSubWidgets()) {
+    public void visit(ModelTree modelTree) throws Exception {
+    }
+
+    @Override
+    public void visit(ModelTreeAction.EntityAnd entityAnd) throws Exception {
+    }
+
+    @Override
+    public void visit(ModelTreeAction.EntityCondition entityCondition) throws Exception {
+    }
+
+    @Override
+    public void visit(ModelTreeAction.Script script) throws Exception {
+    }
+
+    @Override
+    public void visit(ModelTreeAction.Service service) throws Exception {
+    }
+
+    @Override
+    public void visit(PlatformSpecific platformSpecific) throws Exception {
+    }
+
+    @Override
+    public void visit(PortalPage portalPage) throws Exception {
+    }
+
+    @Override
+    public void visit(PropertyMap propertyMap) throws Exception {
+    }
+
+    @Override
+    public void visit(PropertyToField propertyToField) throws Exception {
+    }
+
+    @Override
+    public void visit(ScreenImage image) throws Exception {
+    }
+
+    @Override
+    public void visit(Screenlet screenlet) throws Exception {
+        for (ModelScreenWidget widget : screenlet.getSubWidgets()) {
             widget.accept(this);
         }
     }
 
     @Override
-    public void visit(Content content) throws Exception {
-        infoContext.addEntityName("Content");
-        if (!content.getDataResourceId().isEmpty()) {
-            infoContext.addEntityName("DataResource");
-        }
-    }
-
-    @Override
-    public void visit(DecoratorScreen decoratorScreen) throws Exception {
-        for (ModelScreenWidget section : decoratorScreen.getSectionMap().values()) {
-            section.accept(this);
-        }
-    }
-
-    @Override
-    public void visit(DecoratorSection decoratorSection) throws Exception {
-        for (ModelScreenWidget widget : decoratorSection.getSubWidgets()) {
-            widget.accept(this);
-        }
-    }
-
-    @Override
-    public void visit(DecoratorSectionInclude decoratorSectionInclude) throws Exception {
-    }
-
-    @Override
-    public void visit(Form form) throws Exception {
-        String formLocation = form.getLocation().concat("#").concat(form.getName());
-        infoContext.addFormLocation(formLocation);
-    }
-
-    @Override
-    public void visit(HorizontalSeparator horizontalSeparator) throws Exception {
-    }
-
-    @Override
-    public void visit(Image image) throws Exception {
-    }
-
-    @Override
-    public void visit(IncludeScreen includeScreen) throws Exception {
-    }
-
-    @Override
-    public void visit(Label label) throws Exception {
-    }
-
-    @Override
-    public void visit(Link link) throws Exception {
+    public void visit(ScreenLink link) throws Exception {
         String target = link.getTarget(null);
         String urlMode = link.getUrlMode();
         try {
@@ -370,27 +407,12 @@
     }
 
     @Override
-    public void visit(Menu menu) throws Exception {
-    }
-
-    @Override
-    public void visit(PlatformSpecific platformSpecific) throws Exception {
-    }
-
-    @Override
-    public void visit(PortalPage portalPage) throws Exception {
-    }
-
-    @Override
-    public void visit(Screenlet screenlet) throws Exception {
-        for (ModelScreenWidget widget : screenlet.getSubWidgets()) {
-            widget.accept(this);
-        }
+    public void visit(Script script) throws Exception {
     }
 
     @Override
     public void visit(Section section) throws Exception {
-        for (ModelWidgetAction action : section.getActions()) {
+        for (ModelAction action : section.getActions()) {
             action.accept(this);
         }
         for (ModelScreenWidget subWidget : section.getSubWidgets()) {
@@ -402,37 +424,19 @@
     }
 
     @Override
+    public void visit(Service service) throws Exception {
+        infoContext.addServiceName(service.getServiceNameExdr().getOriginal());
+        // TODO: Look for entityName in performFind service call
+    }
+
+    @Override
+    public void visit(SetField setField) throws Exception {
+    }
+
+    @Override
     public void visit(Tree tree) throws Exception {
     }
 
-    @Override
-    public void visit(ModelTree modelTree) throws Exception {
-    }
-
-    @Override
-    public void visit(ModelNode modelNode) throws Exception {
-    }
-
-    @Override
-    public void visit(ModelSubNode modelSubNode) throws Exception {
-    }
-
-    @Override
-    public void visit(ModelTreeAction.EntityAnd entityAnd) {
-    }
-
-    @Override
-    public void visit(ModelTreeAction.EntityCondition entityCondition) {
-    }
-
-    @Override
-    public void visit(ModelTreeAction.Script script) {
-    }
-
-    @Override
-    public void visit(ModelTreeAction.Service service) {
-    }
-
     private class FieldInfoGatherer implements ModelFieldVisitor {
 
         private void addRequestLocations(String target, String urlMode) {
@@ -469,7 +473,7 @@
         public void visit(DisplayEntityField displayField) {
             if (displayField.getSubHyperlink() != null) {
                 String target = displayField.getSubHyperlink().getTarget(null);
-                String urlMode = displayField.getSubHyperlink().getTargetType();
+                String urlMode = displayField.getSubHyperlink().getUrlMode();
                 addRequestLocations(target, urlMode);
             }
         }
@@ -482,7 +486,7 @@
         public void visit(DropDownField dropDownField) {
             if (dropDownField.getSubHyperlink() != null) {
                 String target = dropDownField.getSubHyperlink().getTarget(null);
-                String urlMode = dropDownField.getSubHyperlink().getTargetType();
+                String urlMode = dropDownField.getSubHyperlink().getUrlMode();
                 addRequestLocations(target, urlMode);
             }
         }
@@ -491,7 +495,7 @@
         public void visit(FileField textField) {
             if (textField.getSubHyperlink() != null) {
                 String target = textField.getSubHyperlink().getTarget(null);
-                String urlMode = textField.getSubHyperlink().getTargetType();
+                String urlMode = textField.getSubHyperlink().getUrlMode();
                 addRequestLocations(target, urlMode);
             }
         }
@@ -503,7 +507,7 @@
         @Override
         public void visit(HyperlinkField hyperlinkField) {
             String target = hyperlinkField.getTarget(null);
-            String urlMode = hyperlinkField.getTargetType();
+            String urlMode = hyperlinkField.getUrlMode();
             addRequestLocations(target, urlMode);
         }
 
@@ -515,7 +519,7 @@
         public void visit(ImageField imageField) {
             if (imageField.getSubHyperlink() != null) {
                 String target = imageField.getSubHyperlink().getTarget(null);
-                String urlMode = imageField.getSubHyperlink().getTargetType();
+                String urlMode = imageField.getSubHyperlink().getUrlMode();
                 addRequestLocations(target, urlMode);
             }
         }
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/ModelWidgetAction.java b/framework/widget/src/org/ofbiz/widget/model/AbstractModelAction.java
similarity index 85%
rename from framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
rename to framework/widget/src/org/ofbiz/widget/model/AbstractModelAction.java
index e12f3ca..7ec655b 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelWidgetAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/AbstractModelAction.java
@@ -1,824 +1,951 @@
-/*******************************************************************************
- * 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.text.MessageFormat;
-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 java.util.regex.PatternSyntaxException;
-
-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.ScriptUtil;
-import org.ofbiz.base.util.StringUtil;
-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.collections.ResourceBundleMapWrapper;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.finder.ByAndFinder;
-import org.ofbiz.entity.finder.ByConditionFinder;
-import org.ofbiz.entity.finder.EntityFinderUtil;
-import org.ofbiz.entity.finder.PrimaryKeyFinder;
-import org.ofbiz.entity.util.EntityUtilProperties;
-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.w3c.dom.Element;
-
-/**
- * Abstract widget action.
- */
-@SuppressWarnings("serial")
-public abstract class ModelWidgetAction implements Serializable {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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 = ModelWidgetAction.class.getName();
-
-    /**
-     * Returns a new <code>ModelWidgetAction</code> instance, built from <code>actionElement</code>.
-     * 
-     * @param modelWidget The <code>ModelWidget</code> that contains the &lt;actions&gt; element
-     * @param actionElement
-     * @return A new <code>ModelWidgetAction</code> instance
-     */
-    public static ModelWidgetAction newInstance(ModelWidget modelWidget, Element actionElement) {
-        if ("set".equals(actionElement.getNodeName())) {
-            return new SetField(modelWidget, actionElement);
-        } else if ("property-map".equals(actionElement.getNodeName())) {
-            return new PropertyMap(modelWidget, actionElement);
-        } else if ("property-to-field".equals(actionElement.getNodeName())) {
-            return new PropertyToField(modelWidget, actionElement);
-        } else if ("script".equals(actionElement.getNodeName())) {
-            return new Script(modelWidget, actionElement);
-        } else if ("service".equals(actionElement.getNodeName())) {
-            return new Service(modelWidget, actionElement);
-        } else if ("entity-one".equals(actionElement.getNodeName())) {
-            return new EntityOne(modelWidget, actionElement);
-        } else if ("entity-and".equals(actionElement.getNodeName())) {
-            return new EntityAnd(modelWidget, actionElement);
-        } else if ("entity-condition".equals(actionElement.getNodeName())) {
-            return new EntityCondition(modelWidget, actionElement);
-        } else if ("get-related-one".equals(actionElement.getNodeName())) {
-            return new GetRelatedOne(modelWidget, actionElement);
-        } else if ("get-related".equals(actionElement.getNodeName())) {
-            return new GetRelated(modelWidget, actionElement);
-        } else {
-            throw new IllegalArgumentException("Action element not supported with name: " + actionElement.getNodeName());
-        }
-    }
-
-    public static List<ModelWidgetAction> readSubActions(ModelWidget modelWidget, Element parentElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
-        List<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>(actionElementList.size());
-        for (Element actionElement : actionElementList) {
-            actions.add(newInstance(modelWidget, actionElement));
-        }
-        return Collections.unmodifiableList(actions);
-    }
-
-    /**
-     * Executes the actions contained in <code>actions</code>.
-     * 
-     * @param actions
-     * @param context
-     */
-    public static void runSubActions(List<ModelWidgetAction> actions, Map<String, Object> context) {
-        if (actions == null)
-            return;
-        for (ModelWidgetAction action : actions) {
-            if (Debug.verboseOn())
-                Debug.logVerbose("Running action " + action.getClass().getName(), module);
-            try {
-                action.runAction(context);
-            } catch (GeneralException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    private final ModelWidget modelWidget;
-
-    protected ModelWidgetAction() {
-        // FIXME: This should not be null.
-        this.modelWidget = null;
-    }
-
-    protected ModelWidgetAction(ModelWidget modelWidget, Element actionElement) {
-        this.modelWidget = modelWidget;
-        if (Debug.verboseOn())
-            Debug.logVerbose("Reading widget action with name: " + actionElement.getNodeName(), module);
-    }
-
-    public abstract void accept(ModelActionVisitor visitor);
-
-    /**
-     * Returns the <code>ModelWidget</code> that contains the &lt;actions&gt; element.
-     * 
-     * @return The <code>ModelWidget</code> that contains the &lt;actions&gt; element
-     */
-    public ModelWidget getModelWidget() {
-        return modelWidget;
-    }
-
-    /**
-     * Executes this action.
-     * 
-     * @param context
-     * @throws GeneralException
-     */
-    public abstract void runAction(Map<String, Object> context) throws GeneralException;
-
-    /**
-     * Models the &lt;entity-and&gt; element.
-     * 
-     * @see <code>widget-screen.xsd</code>
-     */
-    public static class EntityAnd extends ModelWidgetAction {
-        private final ByAndFinder finder;
-
-        public EntityAnd(ModelWidget modelWidget, Element entityAndElement) {
-            super(modelWidget, entityAndElement);
-            finder = new ByAndFinder(entityAndElement);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public ByAndFinder getFinder() {
-            return this.finder;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                finder.runFind(context, WidgetWorker.getDelegator(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-screen.xsd</code>
-     */
-    public static class EntityCondition extends ModelWidgetAction {
-        private final ByConditionFinder finder;
-
-        public EntityCondition(ModelWidget modelWidget, Element entityConditionElement) {
-            super(modelWidget, entityConditionElement);
-            finder = new ByConditionFinder(entityConditionElement);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public ByConditionFinder getFinder() {
-            return this.finder;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                finder.runFind(context, WidgetWorker.getDelegator(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-one&gt; element.
-     * 
-     * @see <code>widget-common.xsd</code>
-     */
-    public static class EntityOne extends ModelWidgetAction {
-        private final PrimaryKeyFinder finder;
-
-        public EntityOne(ModelWidget modelWidget, Element entityOneElement) {
-            super(modelWidget, entityOneElement);
-            finder = new PrimaryKeyFinder(entityOneElement);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public PrimaryKeyFinder getFinder() {
-            return this.finder;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            try {
-                finder.runFind(context, WidgetWorker.getDelegator(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;get-related&gt; element.
-     * 
-     * @see <code>widget-common.xsd</code>
-     */
-    public static class GetRelated extends ModelWidgetAction {
-        private final FlexibleMapAccessor<List<GenericValue>> listNameAcsr;
-        private final FlexibleMapAccessor<Map<String, Object>> mapAcsr;
-        private final FlexibleMapAccessor<List<String>> orderByListAcsr;
-        private final String relationName;
-        private final boolean useCache;
-        private final FlexibleMapAccessor<Object> valueNameAcsr;
-
-        public GetRelated(ModelWidget modelWidget, Element getRelatedElement) {
-            super(modelWidget, getRelatedElement);
-            this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
-            this.listNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
-            this.relationName = getRelatedElement.getAttribute("relation-name");
-            this.mapAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
-            this.orderByListAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
-            this.useCache = "true".equals(getRelatedElement.getAttribute("use-cache"));
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public String getRelationName() {
-            return this.relationName;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            Object valueObject = valueNameAcsr.get(context);
-            if (valueObject == null) {
-                Debug.logVerbose("Value not found with name: " + valueNameAcsr + ", not getting related...", module);
-                return;
-            }
-            if (!(valueObject instanceof GenericValue)) {
-                String errMsg = "Env variable for value-name " + valueNameAcsr.toString()
-                        + " is not a GenericValue object; for the relation-name: " + relationName + "]";
-                Debug.logError(errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-            GenericValue value = (GenericValue) valueObject;
-            List<String> orderByNames = null;
-            if (!orderByListAcsr.isEmpty()) {
-                orderByNames = orderByListAcsr.get(context);
-            }
-            Map<String, Object> constraintMap = null;
-            if (!mapAcsr.isEmpty()) {
-                constraintMap = mapAcsr.get(context);
-            }
-            try {
-                listNameAcsr.put(context, value.getRelated(relationName, constraintMap, orderByNames, useCache));
-            } catch (GenericEntityException e) {
-                String errMsg = "Problem getting related from entity with name " + value.getEntityName()
-                        + " for the relation-name: " + relationName + ": " + e.getMessage();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-
-    /**
-     * Models the &lt;get-related-one&gt; element.
-     * 
-     * @see <code>widget-common.xsd</code>
-     */
-    public static class GetRelatedOne extends ModelWidgetAction {
-        private final String relationName;
-        private final FlexibleMapAccessor<Object> toValueNameAcsr;
-        private final boolean useCache;
-        private final FlexibleMapAccessor<Object> valueNameAcsr;
-
-        public GetRelatedOne(ModelWidget modelWidget, Element getRelatedOneElement) {
-            super(modelWidget, getRelatedOneElement);
-            this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
-            this.toValueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
-            this.relationName = getRelatedOneElement.getAttribute("relation-name");
-            this.useCache = "true".equals(getRelatedOneElement.getAttribute("use-cache"));
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public String getRelationName() {
-            return this.relationName;
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            Object valueObject = valueNameAcsr.get(context);
-            if (valueObject == null) {
-                Debug.logVerbose("Value not found with name: " + valueNameAcsr + ", not getting related...", module);
-                return;
-            }
-            if (!(valueObject instanceof GenericValue)) {
-                String errMsg = "Env variable for value-name " + valueNameAcsr.toString()
-                        + " is not a GenericValue object; for the relation-name: " + relationName + "]";
-                Debug.logError(errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-            GenericValue value = (GenericValue) valueObject;
-            try {
-                toValueNameAcsr.put(context, value.getRelatedOne(relationName, useCache));
-            } catch (GenericEntityException e) {
-                String errMsg = "Problem getting related one from entity with name " + value.getEntityName()
-                        + " for the relation-name: " + relationName + ": " + e.getMessage();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-
-    /**
-     * Models the &lt;property-map&gt; element.
-     * 
-     * @see <code>widget-common.xsd</code>
-     */
-    public static class PropertyMap extends ModelWidgetAction {
-        private final FlexibleStringExpander globalExdr;
-        private final FlexibleMapAccessor<ResourceBundleMapWrapper> mapNameAcsr;
-        private final FlexibleStringExpander resourceExdr;
-
-        public PropertyMap(ModelWidget modelWidget, Element setElement) {
-            super(modelWidget, setElement);
-            this.resourceExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
-            this.mapNameAcsr = FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
-            this.globalExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            String globalStr = this.globalExdr.expandString(context);
-            // default to false
-            boolean global = "true".equals(globalStr);
-            Locale locale = (Locale) context.get("locale");
-            String resource = this.resourceExdr.expandString(context, locale);
-            ResourceBundleMapWrapper existingPropMap = this.mapNameAcsr.get(context);
-            if (existingPropMap == null) {
-                this.mapNameAcsr.put(context, UtilProperties.getResourceBundleMap(resource, locale, context));
-            } else {
-                try {
-                    existingPropMap.addBottomResourceBundle(resource);
-                } catch (IllegalArgumentException e) {
-                    // log the error, but don't let it kill everything just for a typo or bad char in an l10n file
-                    Debug.logError(e, "Error adding resource bundle [" + resource + "]: " + e.toString(), module);
-                }
-            }
-            if (global) {
-                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
-                if (globalCtx != null) {
-                    ResourceBundleMapWrapper globalExistingPropMap = this.mapNameAcsr.get(globalCtx);
-                    if (globalExistingPropMap == null) {
-                        this.mapNameAcsr.put(globalCtx, UtilProperties.getResourceBundleMap(resource, locale, context));
-                    } else {
-                        // is it the same object? if not add it in here too...
-                        if (existingPropMap != globalExistingPropMap) {
-                            try {
-                                globalExistingPropMap.addBottomResourceBundle(resource);
-                            } catch (IllegalArgumentException e) {
-                                // log the error, but don't let it kill everything just for a typo or bad char in an l10n file
-                                Debug.logError(e, "Error adding resource bundle [" + resource + "]: " + e.toString(), module);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Models the &lt;property-to-field&gt; element.
-     * 
-     * @see <code>widget-common.xsd</code>
-     */
-    public static class PropertyToField extends ModelWidgetAction {
-        private final FlexibleMapAccessor<List<? extends Object>> argListAcsr;
-        private final FlexibleStringExpander defaultExdr;
-        private final FlexibleMapAccessor<Object> fieldAcsr;
-        private final FlexibleStringExpander globalExdr;
-        private final boolean noLocale;
-        private final FlexibleStringExpander propertyExdr;
-        private final FlexibleStringExpander resourceExdr;
-
-        public PropertyToField(ModelWidget modelWidget, Element setElement) {
-            super(modelWidget, setElement);
-            this.resourceExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
-            this.propertyExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
-            this.fieldAcsr = FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
-            this.defaultExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
-            this.noLocale = "true".equals(setElement.getAttribute("no-locale"));
-            this.argListAcsr = FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
-            this.globalExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) {
-            //String globalStr = this.globalExdr.expandString(context);
-            // default to false
-            //boolean global = "true".equals(globalStr);
-            Locale locale = (Locale) context.get("locale");
-            String resource = this.resourceExdr.expandString(context, locale);
-            String property = this.propertyExdr.expandString(context, locale);
-            String value = null;
-            if (noLocale) {
-                value = EntityUtilProperties.getPropertyValue(resource, property, WidgetWorker.getDelegator(context));
-            } else {
-                value = EntityUtilProperties.getMessage(resource, property, locale, WidgetWorker.getDelegator(context));
-            }
-            if (UtilValidate.isEmpty(value)) {
-                value = this.defaultExdr.expandString(context);
-            }
-            // note that expanding the value string here will handle defaultValue and the string from
-            //  the properties file; if we decide later that we don't want the string from the properties
-            //  file to be expanded we should just expand the defaultValue at the beginning of this method.
-            value = FlexibleStringExpander.expandString(value, context);
-            if (!argListAcsr.isEmpty()) {
-                List<? extends Object> argList = argListAcsr.get(context);
-                if (UtilValidate.isNotEmpty(argList)) {
-                    value = MessageFormat.format(value, argList.toArray());
-                }
-            }
-            fieldAcsr.put(context, value);
-        }
-    }
-
-    /**
-     * Models the &lt;script&gt; element.
-     * 
-     * @see <code>widget-common.xsd</code>
-     */
-    public static class Script extends ModelWidgetAction {
-        private final String location;
-        private final String method;
-
-        public Script(ModelWidget modelWidget, Element scriptElement) {
-            super(modelWidget, scriptElement);
-            String scriptLocation = scriptElement.getAttribute("location");
-            this.location = WidgetWorker.getScriptLocation(scriptLocation);
-            this.method = WidgetWorker.getScriptMethodName(scriptLocation);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public void runAction(Map<String, Object> context) throws GeneralException {
-            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 GeneralException("Error running simple method at location [" + location + "]", e);
-                }
-            } else {
-                ScriptUtil.executeScript(this.location, this.method, context);
-            }
-        }
-    }
-
-    /**
-     * Models the &lt;service&gt; element.
-     * 
-     * @see <code>widget-screen.xsd</code>
-     */
-    public static class Service extends ModelWidgetAction {
-        private final FlexibleStringExpander autoFieldMapExdr;
-        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
-        private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
-        private final FlexibleStringExpander serviceNameExdr;
-
-        public Service(ModelWidget modelWidget, Element serviceElement) {
-            super(modelWidget, 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.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public FlexibleStringExpander getServiceNameExdr() {
-            return this.serviceNameExdr;
-        }
-
-        @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);
-            try {
-                Map<String, Object> serviceContext = null;
-                if ("true".equals(autoFieldMapString)) {
-                    DispatchContext dc = WidgetWorker.getDispatcher(context).getDispatchContext();
-                    // try a map called "parameters", try it first so values from here are overriden by values in the main context
-                    Map<String, Object> combinedMap = new HashMap<String, Object>();
-                    Map<String, Object> parametersObj = UtilGenerics.toMap(context.get("parameters"));
-                    if (parametersObj != null) {
-                        combinedMap.putAll(parametersObj);
-                    }
-                    combinedMap.putAll(context);
-                    serviceContext = dc.makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, combinedMap);
-                } else if (UtilValidate.isNotEmpty(autoFieldMapString) && !"false".equals(autoFieldMapString)) {
-                    FlexibleMapAccessor<Object> fieldFma = FlexibleMapAccessor.getInstance(autoFieldMapString);
-                    Map<String, Object> autoFieldMap = UtilGenerics.toMap(fieldFma.get(context));
-                    if (autoFieldMap != null) {
-                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
-                                .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, autoFieldMap);
-                    }
-                }
-                if (serviceContext == null) {
-                    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);
-                }
-            } catch (GenericServiceException e) {
-                String errMsg = "Error calling service with name " + serviceNameExpanded + ": " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new IllegalArgumentException(errMsg);
-            }
-        }
-    }
-
-    /**
-     * Models the &lt;set&gt; element.
-     * 
-     * @see <code>widget-common.xsd</code>
-     */
-    public static class SetField extends ModelWidgetAction {
-        private final FlexibleStringExpander defaultExdr;
-        private final FlexibleMapAccessor<Object> field;
-        private final FlexibleMapAccessor<Object> fromField;
-        private final String fromScope;
-        private final FlexibleStringExpander globalExdr;
-        private final String toScope;
-        private final String type;
-        private final FlexibleStringExpander valueExdr;
-
-        public SetField(ModelWidget modelWidget, Element setElement) {
-            super(modelWidget, 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 = FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
-            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 widget");
-            }
-        }
-
-        @Override
-        public void accept(ModelActionVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        public Object getInMemoryPersistedFromField(Object storeAgent, Map<String, Object> context) {
-            Object newValue = null;
-            String originalName = this.fromField.getOriginalName();
-            List<String> currentWidgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
-            List<String> trailList = new ArrayList<String>();
-            if (currentWidgetTrail != null) {
-                trailList.addAll(currentWidgetTrail);
-            }
-            for (int i = trailList.size(); i >= 0; i--) {
-                List<String> subTrail = trailList.subList(0, i);
-                String newKey = null;
-                if (subTrail.size() > 0)
-                    newKey = StringUtil.join(subTrail, "|") + "|" + originalName;
-                else
-                    newKey = originalName;
-                if (storeAgent instanceof ServletContext) {
-                    newValue = ((ServletContext) storeAgent).getAttribute(newKey);
-                } else if (storeAgent instanceof HttpSession) {
-                    newValue = ((HttpSession) storeAgent).getAttribute(newKey);
-                }
-                if (newValue != null) {
-                    break;
-                }
-            }
-            return newValue;
-        }
-
-        @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()) {
-                    HttpSession session = (HttpSession) context.get("session");
-                    newValue = getInMemoryPersistedFromField(session, context);
-                    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.expand(context);
-                }
-            } else if (this.fromScope != null && this.fromScope.equals("application")) {
-                if (!this.fromField.isEmpty()) {
-                    ServletContext servletContext = (ServletContext) context.get("application");
-                    newValue = getInMemoryPersistedFromField(servletContext, context);
-                    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("Getting value for field from [" + this.fromField.getOriginalName() + "]: " + newValue,
-                                module);
-                } else if (!this.valueExdr.isEmpty()) {
-                    newValue = this.valueExdr.expand(context);
-                }
-            }
-            // If newValue is still empty, use the default value
-            if (ObjectType.isEmpty(newValue) && !this.defaultExdr.isEmpty()) {
-                newValue = this.defaultExdr.expand(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();
-                List<String> currentWidgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
-                String newKey = "";
-                if (currentWidgetTrail != null) {
-                    newKey = StringUtil.join(currentWidgetTrail, "|");
-                }
-                if (UtilValidate.isNotEmpty(newKey)) {
-                    newKey += "|";
-                }
-                newKey += 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();
-                List<String> currentWidgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
-                String newKey = "";
-                if (currentWidgetTrail != null) {
-                    newKey = StringUtil.join(currentWidgetTrail, "|");
-                }
-                if (UtilValidate.isNotEmpty(newKey)) {
-                    newKey += "|";
-                }
-                newKey += 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 {
-                // only do this if it is not global, if global ONLY put it in the global context
-                if (!global) {
-                    if (Debug.verboseOn())
-                        Debug.logVerbose("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);
-                } else {
-                    this.field.put(context, 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);
-            }
-        }
-    }
-}
+/*******************************************************************************
+ * 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.text.MessageFormat;
+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 java.util.regex.PatternSyntaxException;
+
+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.ScriptUtil;
+import org.ofbiz.base.util.StringUtil;
+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.collections.ResourceBundleMapWrapper;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.finder.ByAndFinder;
+import org.ofbiz.entity.finder.ByConditionFinder;
+import org.ofbiz.entity.finder.EntityFinderUtil;
+import org.ofbiz.entity.finder.PrimaryKeyFinder;
+import org.ofbiz.entity.util.EntityUtilProperties;
+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.w3c.dom.Element;
+
+/**
+ * Abstract base class for the action models.
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractModelAction implements Serializable, ModelAction {
+
+    /*
+     * ----------------------------------------------------------------------- *
+     *                     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 = AbstractModelAction.class.getName();
+
+    /**
+     * Returns a new <code>ModelAction</code> instance, built from <code>actionElement</code>.
+     * 
+     * @param modelWidget The <code>ModelWidget</code> that contains the &lt;actions&gt; element
+     * @param actionElement
+     * @return A new <code>ModelAction</code> instance
+     */
+    public static ModelAction newInstance(ModelWidget modelWidget, Element actionElement) {
+        if ("set".equals(actionElement.getNodeName())) {
+            return new SetField(modelWidget, actionElement);
+        } else if ("property-map".equals(actionElement.getNodeName())) {
+            return new PropertyMap(modelWidget, actionElement);
+        } else if ("property-to-field".equals(actionElement.getNodeName())) {
+            return new PropertyToField(modelWidget, actionElement);
+        } else if ("script".equals(actionElement.getNodeName())) {
+            return new Script(modelWidget, actionElement);
+        } else if ("service".equals(actionElement.getNodeName())) {
+            return new Service(modelWidget, actionElement);
+        } else if ("entity-one".equals(actionElement.getNodeName())) {
+            return new EntityOne(modelWidget, actionElement);
+        } else if ("entity-and".equals(actionElement.getNodeName())) {
+            return new EntityAnd(modelWidget, actionElement);
+        } else if ("entity-condition".equals(actionElement.getNodeName())) {
+            return new EntityCondition(modelWidget, actionElement);
+        } else if ("get-related-one".equals(actionElement.getNodeName())) {
+            return new GetRelatedOne(modelWidget, actionElement);
+        } else if ("get-related".equals(actionElement.getNodeName())) {
+            return new GetRelated(modelWidget, actionElement);
+        } else {
+            throw new IllegalArgumentException("Action element not supported with name: " + actionElement.getNodeName());
+        }
+    }
+
+    public static List<ModelAction> readSubActions(ModelWidget modelWidget, Element parentElement) {
+        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
+        List<ModelAction> actions = new ArrayList<ModelAction>(actionElementList.size());
+        for (Element actionElement : actionElementList) {
+            actions.add(newInstance(modelWidget, actionElement));
+        }
+        return Collections.unmodifiableList(actions);
+    }
+
+    /**
+     * Executes the actions contained in <code>actions</code>.
+     * 
+     * @param actions
+     * @param context
+     */
+    public static void runSubActions(List<ModelAction> actions, Map<String, Object> context) {
+        if (actions == null)
+            return;
+        for (ModelAction action : actions) {
+            if (Debug.verboseOn())
+                Debug.logVerbose("Running action " + action.getClass().getName(), module);
+            try {
+                action.runAction(context);
+            } catch (GeneralException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private final ModelWidget modelWidget;
+
+    protected AbstractModelAction() {
+        // FIXME: This should not be null.
+        this.modelWidget = null;
+    }
+
+    protected AbstractModelAction(ModelWidget modelWidget, Element actionElement) {
+        this.modelWidget = modelWidget;
+        if (Debug.verboseOn())
+            Debug.logVerbose("Reading widget action with name: " + actionElement.getNodeName(), module);
+    }
+
+    /**
+     * Returns the <code>ModelWidget</code> that contains the &lt;actions&gt; element.
+     * 
+     * @return The <code>ModelWidget</code> that contains the &lt;actions&gt; element
+     */
+    public ModelWidget getModelWidget() {
+        return modelWidget;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        ModelActionVisitor visitor = new XmlWidgetActionVisitor(sb);
+        try {
+            accept(visitor);
+        } catch (Exception e) {
+            Debug.logWarning(e, "Exception thrown in XmlWidgetActionVisitor: ", module);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Models the &lt;entity-and&gt; element.
+     * 
+     * @see <code>widget-screen.xsd</code>
+     */
+    public static class EntityAnd extends AbstractModelAction {
+        private final ByAndFinder finder;
+
+        public EntityAnd(ModelWidget modelWidget, Element entityAndElement) {
+            super(modelWidget, entityAndElement);
+            finder = new ByAndFinder(entityAndElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public ByAndFinder getFinder() {
+            return this.finder;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            try {
+                finder.runFind(context, WidgetWorker.getDelegator(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-screen.xsd</code>
+     */
+    public static class EntityCondition extends AbstractModelAction {
+        private final ByConditionFinder finder;
+
+        public EntityCondition(ModelWidget modelWidget, Element entityConditionElement) {
+            super(modelWidget, entityConditionElement);
+            finder = new ByConditionFinder(entityConditionElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public ByConditionFinder getFinder() {
+            return this.finder;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            try {
+                finder.runFind(context, WidgetWorker.getDelegator(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-one&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class EntityOne extends AbstractModelAction {
+        private final PrimaryKeyFinder finder;
+
+        public EntityOne(ModelWidget modelWidget, Element entityOneElement) {
+            super(modelWidget, entityOneElement);
+            finder = new PrimaryKeyFinder(entityOneElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public PrimaryKeyFinder getFinder() {
+            return this.finder;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            try {
+                finder.runFind(context, WidgetWorker.getDelegator(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;get-related&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class GetRelated extends AbstractModelAction {
+        private final FlexibleMapAccessor<List<GenericValue>> listNameAcsr;
+        private final FlexibleMapAccessor<Map<String, Object>> mapAcsr;
+        private final FlexibleMapAccessor<List<String>> orderByListAcsr;
+        private final String relationName;
+        private final boolean useCache;
+        private final FlexibleMapAccessor<Object> valueNameAcsr;
+
+        public GetRelated(ModelWidget modelWidget, Element getRelatedElement) {
+            super(modelWidget, getRelatedElement);
+            this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("value-field"));
+            this.listNameAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("list"));
+            this.relationName = getRelatedElement.getAttribute("relation-name");
+            this.mapAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("map"));
+            this.orderByListAcsr = FlexibleMapAccessor.getInstance(getRelatedElement.getAttribute("order-by-list"));
+            this.useCache = "true".equals(getRelatedElement.getAttribute("use-cache"));
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public String getRelationName() {
+            return this.relationName;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            Object valueObject = valueNameAcsr.get(context);
+            if (valueObject == null) {
+                Debug.logVerbose("Value not found with name: " + valueNameAcsr + ", not getting related...", module);
+                return;
+            }
+            if (!(valueObject instanceof GenericValue)) {
+                String errMsg = "Env variable for value-name " + valueNameAcsr.toString()
+                        + " is not a GenericValue object; for the relation-name: " + relationName + "]";
+                Debug.logError(errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+            GenericValue value = (GenericValue) valueObject;
+            List<String> orderByNames = null;
+            if (!orderByListAcsr.isEmpty()) {
+                orderByNames = orderByListAcsr.get(context);
+            }
+            Map<String, Object> constraintMap = null;
+            if (!mapAcsr.isEmpty()) {
+                constraintMap = mapAcsr.get(context);
+            }
+            try {
+                listNameAcsr.put(context, value.getRelated(relationName, constraintMap, orderByNames, useCache));
+            } catch (GenericEntityException e) {
+                String errMsg = "Problem getting related from entity with name " + value.getEntityName()
+                        + " for the relation-name: " + relationName + ": " + e.getMessage();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+        }
+
+        public FlexibleMapAccessor<List<GenericValue>> getListNameAcsr() {
+            return listNameAcsr;
+        }
+
+        public FlexibleMapAccessor<Map<String, Object>> getMapAcsr() {
+            return mapAcsr;
+        }
+
+        public FlexibleMapAccessor<List<String>> getOrderByListAcsr() {
+            return orderByListAcsr;
+        }
+
+        public boolean getUseCache() {
+            return useCache;
+        }
+
+        public FlexibleMapAccessor<Object> getValueNameAcsr() {
+            return valueNameAcsr;
+        }
+    }
+
+    /**
+     * Models the &lt;get-related-one&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class GetRelatedOne extends AbstractModelAction {
+        private final String relationName;
+        private final FlexibleMapAccessor<Object> toValueNameAcsr;
+        private final boolean useCache;
+        private final FlexibleMapAccessor<Object> valueNameAcsr;
+
+        public GetRelatedOne(ModelWidget modelWidget, Element getRelatedOneElement) {
+            super(modelWidget, getRelatedOneElement);
+            this.valueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("value-field"));
+            this.toValueNameAcsr = FlexibleMapAccessor.getInstance(getRelatedOneElement.getAttribute("to-value-field"));
+            this.relationName = getRelatedOneElement.getAttribute("relation-name");
+            this.useCache = "true".equals(getRelatedOneElement.getAttribute("use-cache"));
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public String getRelationName() {
+            return this.relationName;
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            Object valueObject = valueNameAcsr.get(context);
+            if (valueObject == null) {
+                Debug.logVerbose("Value not found with name: " + valueNameAcsr + ", not getting related...", module);
+                return;
+            }
+            if (!(valueObject instanceof GenericValue)) {
+                String errMsg = "Env variable for value-name " + valueNameAcsr.toString()
+                        + " is not a GenericValue object; for the relation-name: " + relationName + "]";
+                Debug.logError(errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+            GenericValue value = (GenericValue) valueObject;
+            try {
+                toValueNameAcsr.put(context, value.getRelatedOne(relationName, useCache));
+            } catch (GenericEntityException e) {
+                String errMsg = "Problem getting related one from entity with name " + value.getEntityName()
+                        + " for the relation-name: " + relationName + ": " + e.getMessage();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+        }
+
+        public FlexibleMapAccessor<Object> getToValueNameAcsr() {
+            return toValueNameAcsr;
+        }
+
+        public boolean getUseCache() {
+            return useCache;
+        }
+
+        public FlexibleMapAccessor<Object> getValueNameAcsr() {
+            return valueNameAcsr;
+        }
+    }
+
+    /**
+     * Models the &lt;property-map&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class PropertyMap extends AbstractModelAction {
+        private final FlexibleStringExpander globalExdr;
+        private final FlexibleMapAccessor<ResourceBundleMapWrapper> mapNameAcsr;
+        private final FlexibleStringExpander resourceExdr;
+
+        public PropertyMap(ModelWidget modelWidget, Element setElement) {
+            super(modelWidget, setElement);
+            this.resourceExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
+            this.mapNameAcsr = FlexibleMapAccessor.getInstance(setElement.getAttribute("map-name"));
+            this.globalExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            String globalStr = this.globalExdr.expandString(context);
+            // default to false
+            boolean global = "true".equals(globalStr);
+            Locale locale = (Locale) context.get("locale");
+            String resource = this.resourceExdr.expandString(context, locale);
+            ResourceBundleMapWrapper existingPropMap = this.mapNameAcsr.get(context);
+            if (existingPropMap == null) {
+                this.mapNameAcsr.put(context, UtilProperties.getResourceBundleMap(resource, locale, context));
+            } else {
+                try {
+                    existingPropMap.addBottomResourceBundle(resource);
+                } catch (IllegalArgumentException e) {
+                    // log the error, but don't let it kill everything just for a typo or bad char in an l10n file
+                    Debug.logError(e, "Error adding resource bundle [" + resource + "]: " + e.toString(), module);
+                }
+            }
+            if (global) {
+                Map<String, Object> globalCtx = UtilGenerics.checkMap(context.get("globalContext"));
+                if (globalCtx != null) {
+                    ResourceBundleMapWrapper globalExistingPropMap = this.mapNameAcsr.get(globalCtx);
+                    if (globalExistingPropMap == null) {
+                        this.mapNameAcsr.put(globalCtx, UtilProperties.getResourceBundleMap(resource, locale, context));
+                    } else {
+                        // is it the same object? if not add it in here too...
+                        if (existingPropMap != globalExistingPropMap) {
+                            try {
+                                globalExistingPropMap.addBottomResourceBundle(resource);
+                            } catch (IllegalArgumentException e) {
+                                // log the error, but don't let it kill everything just for a typo or bad char in an l10n file
+                                Debug.logError(e, "Error adding resource bundle [" + resource + "]: " + e.toString(), module);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        public FlexibleStringExpander getGlobalExdr() {
+            return globalExdr;
+        }
+
+        public FlexibleMapAccessor<ResourceBundleMapWrapper> getMapNameAcsr() {
+            return mapNameAcsr;
+        }
+
+        public FlexibleStringExpander getResourceExdr() {
+            return resourceExdr;
+        }
+    }
+
+    /**
+     * Models the &lt;property-to-field&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class PropertyToField extends AbstractModelAction {
+        private final FlexibleMapAccessor<List<? extends Object>> argListAcsr;
+        private final FlexibleStringExpander defaultExdr;
+        private final FlexibleMapAccessor<Object> fieldAcsr;
+        private final FlexibleStringExpander globalExdr;
+        private final boolean noLocale;
+        private final FlexibleStringExpander propertyExdr;
+        private final FlexibleStringExpander resourceExdr;
+
+        public PropertyToField(ModelWidget modelWidget, Element setElement) {
+            super(modelWidget, setElement);
+            this.resourceExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("resource"));
+            this.propertyExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("property"));
+            this.fieldAcsr = FlexibleMapAccessor.getInstance(setElement.getAttribute("field"));
+            this.defaultExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("default"));
+            this.noLocale = "true".equals(setElement.getAttribute("no-locale"));
+            this.argListAcsr = FlexibleMapAccessor.getInstance(setElement.getAttribute("arg-list-name"));
+            this.globalExdr = FlexibleStringExpander.getInstance(setElement.getAttribute("global"));
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) {
+            //String globalStr = this.globalExdr.expandString(context);
+            // default to false
+            //boolean global = "true".equals(globalStr);
+            Locale locale = (Locale) context.get("locale");
+            String resource = this.resourceExdr.expandString(context, locale);
+            String property = this.propertyExdr.expandString(context, locale);
+            String value = null;
+            if (noLocale) {
+                value = EntityUtilProperties.getPropertyValue(resource, property, WidgetWorker.getDelegator(context));
+            } else {
+                value = EntityUtilProperties.getMessage(resource, property, locale, WidgetWorker.getDelegator(context));
+            }
+            if (UtilValidate.isEmpty(value)) {
+                value = this.defaultExdr.expandString(context);
+            }
+            // note that expanding the value string here will handle defaultValue and the string from
+            //  the properties file; if we decide later that we don't want the string from the properties
+            //  file to be expanded we should just expand the defaultValue at the beginning of this method.
+            value = FlexibleStringExpander.expandString(value, context);
+            if (!argListAcsr.isEmpty()) {
+                List<? extends Object> argList = argListAcsr.get(context);
+                if (UtilValidate.isNotEmpty(argList)) {
+                    value = MessageFormat.format(value, argList.toArray());
+                }
+            }
+            fieldAcsr.put(context, value);
+        }
+
+        public FlexibleMapAccessor<List<? extends Object>> getArgListAcsr() {
+            return argListAcsr;
+        }
+
+        public FlexibleStringExpander getDefaultExdr() {
+            return defaultExdr;
+        }
+
+        public FlexibleMapAccessor<Object> getFieldAcsr() {
+            return fieldAcsr;
+        }
+
+        public FlexibleStringExpander getGlobalExdr() {
+            return globalExdr;
+        }
+
+        public boolean getNoLocale() {
+            return noLocale;
+        }
+
+        public FlexibleStringExpander getPropertyExdr() {
+            return propertyExdr;
+        }
+
+        public FlexibleStringExpander getResourceExdr() {
+            return resourceExdr;
+        }
+    }
+
+    /**
+     * Models the &lt;script&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class Script extends AbstractModelAction {
+        private final String location;
+        private final String method;
+
+        public Script(ModelWidget modelWidget, Element scriptElement) {
+            super(modelWidget, 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);
+        }
+
+        @Override
+        public void runAction(Map<String, Object> context) throws GeneralException {
+            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 GeneralException("Error running simple method at location [" + location + "]", e);
+                }
+            } else {
+                ScriptUtil.executeScript(this.location, this.method, context);
+            }
+        }
+
+        public String getLocation() {
+            return location;
+        }
+
+        public String getMethod() {
+            return method;
+        }
+    }
+
+    /**
+     * Models the &lt;service&gt; element.
+     * 
+     * @see <code>widget-screen.xsd</code>
+     */
+    public static class Service extends AbstractModelAction {
+        private final FlexibleStringExpander autoFieldMapExdr;
+        private final Map<FlexibleMapAccessor<Object>, Object> fieldMap;
+        private final FlexibleMapAccessor<Map<String, Object>> resultMapNameAcsr;
+        private final FlexibleStringExpander serviceNameExdr;
+
+        public Service(ModelWidget modelWidget, Element serviceElement) {
+            super(modelWidget, 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.fieldMap = EntityFinderUtil.makeFieldMap(serviceElement);
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public FlexibleStringExpander getServiceNameExdr() {
+            return this.serviceNameExdr;
+        }
+
+        @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);
+            try {
+                Map<String, Object> serviceContext = null;
+                if ("true".equals(autoFieldMapString)) {
+                    DispatchContext dc = WidgetWorker.getDispatcher(context).getDispatchContext();
+                    // try a map called "parameters", try it first so values from here are overriden by values in the main context
+                    Map<String, Object> combinedMap = new HashMap<String, Object>();
+                    Map<String, Object> parametersObj = UtilGenerics.toMap(context.get("parameters"));
+                    if (parametersObj != null) {
+                        combinedMap.putAll(parametersObj);
+                    }
+                    combinedMap.putAll(context);
+                    serviceContext = dc.makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, combinedMap);
+                } else if (UtilValidate.isNotEmpty(autoFieldMapString) && !"false".equals(autoFieldMapString)) {
+                    FlexibleMapAccessor<Object> fieldFma = FlexibleMapAccessor.getInstance(autoFieldMapString);
+                    Map<String, Object> autoFieldMap = UtilGenerics.toMap(fieldFma.get(context));
+                    if (autoFieldMap != null) {
+                        serviceContext = WidgetWorker.getDispatcher(context).getDispatchContext()
+                                .makeValidContext(serviceNameExpanded, ModelService.IN_PARAM, autoFieldMap);
+                    }
+                }
+                if (serviceContext == null) {
+                    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);
+                }
+            } catch (GenericServiceException e) {
+                String errMsg = "Error calling service with name " + serviceNameExpanded + ": " + e.toString();
+                Debug.logError(e, errMsg, module);
+                throw new IllegalArgumentException(errMsg);
+            }
+        }
+
+        public FlexibleStringExpander getAutoFieldMapExdr() {
+            return autoFieldMapExdr;
+        }
+
+        public Map<FlexibleMapAccessor<Object>, Object> getFieldMap() {
+            return fieldMap;
+        }
+
+        public FlexibleMapAccessor<Map<String, Object>> getResultMapNameAcsr() {
+            return resultMapNameAcsr;
+        }
+    }
+
+    /**
+     * Models the &lt;set&gt; element.
+     * 
+     * @see <code>widget-common.xsd</code>
+     */
+    public static class SetField extends AbstractModelAction {
+        private final FlexibleStringExpander defaultExdr;
+        private final FlexibleMapAccessor<Object> field;
+        private final FlexibleMapAccessor<Object> fromField;
+        private final String fromScope;
+        private final FlexibleStringExpander globalExdr;
+        private final String toScope;
+        private final String type;
+        private final FlexibleStringExpander valueExdr;
+
+        public SetField(ModelWidget modelWidget, Element setElement) {
+            super(modelWidget, 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 = FlexibleStringExpander.getInstance(setElement.getAttribute("default-value"));
+            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 widget");
+            }
+        }
+
+        @Override
+        public void accept(ModelActionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        public Object getInMemoryPersistedFromField(Object storeAgent, Map<String, Object> context) {
+            Object newValue = null;
+            String originalName = this.fromField.getOriginalName();
+            List<String> currentWidgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
+            List<String> trailList = new ArrayList<String>();
+            if (currentWidgetTrail != null) {
+                trailList.addAll(currentWidgetTrail);
+            }
+            for (int i = trailList.size(); i >= 0; i--) {
+                List<String> subTrail = trailList.subList(0, i);
+                String newKey = null;
+                if (subTrail.size() > 0)
+                    newKey = StringUtil.join(subTrail, "|") + "|" + originalName;
+                else
+                    newKey = originalName;
+                if (storeAgent instanceof ServletContext) {
+                    newValue = ((ServletContext) storeAgent).getAttribute(newKey);
+                } else if (storeAgent instanceof HttpSession) {
+                    newValue = ((HttpSession) storeAgent).getAttribute(newKey);
+                }
+                if (newValue != null) {
+                    break;
+                }
+            }
+            return newValue;
+        }
+
+        @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()) {
+                    HttpSession session = (HttpSession) context.get("session");
+                    newValue = getInMemoryPersistedFromField(session, context);
+                    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.expand(context);
+                }
+            } else if (this.fromScope != null && this.fromScope.equals("application")) {
+                if (!this.fromField.isEmpty()) {
+                    ServletContext servletContext = (ServletContext) context.get("application");
+                    newValue = getInMemoryPersistedFromField(servletContext, context);
+                    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("Getting value for field from [" + this.fromField.getOriginalName() + "]: " + newValue,
+                                module);
+                } else if (!this.valueExdr.isEmpty()) {
+                    newValue = this.valueExdr.expand(context);
+                }
+            }
+            // If newValue is still empty, use the default value
+            if (ObjectType.isEmpty(newValue) && !this.defaultExdr.isEmpty()) {
+                newValue = this.defaultExdr.expand(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();
+                List<String> currentWidgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
+                String newKey = "";
+                if (currentWidgetTrail != null) {
+                    newKey = StringUtil.join(currentWidgetTrail, "|");
+                }
+                if (UtilValidate.isNotEmpty(newKey)) {
+                    newKey += "|";
+                }
+                newKey += 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();
+                List<String> currentWidgetTrail = UtilGenerics.toList(context.get("_WIDGETTRAIL_"));
+                String newKey = "";
+                if (currentWidgetTrail != null) {
+                    newKey = StringUtil.join(currentWidgetTrail, "|");
+                }
+                if (UtilValidate.isNotEmpty(newKey)) {
+                    newKey += "|";
+                }
+                newKey += 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 {
+                // only do this if it is not global, if global ONLY put it in the global context
+                if (!global) {
+                    if (Debug.verboseOn())
+                        Debug.logVerbose("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);
+                } else {
+                    this.field.put(context, 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);
+            }
+        }
+
+        public FlexibleStringExpander getDefaultExdr() {
+            return defaultExdr;
+        }
+
+        public FlexibleMapAccessor<Object> getField() {
+            return field;
+        }
+
+        public FlexibleMapAccessor<Object> getFromField() {
+            return fromField;
+        }
+
+        public String getFromScope() {
+            return fromScope;
+        }
+
+        public FlexibleStringExpander getGlobalExdr() {
+            return globalExdr;
+        }
+
+        public String getToScope() {
+            return toScope;
+        }
+
+        public String getType() {
+            return type;
+        }
+
+        public FlexibleStringExpander getValueExdr() {
+            return valueExdr;
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java b/framework/widget/src/org/ofbiz/widget/model/AbstractModelCondition.java
similarity index 68%
copy from framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.java
copy to framework/widget/src/org/ofbiz/widget/model/AbstractModelCondition.java
index 56feb69..d752f0b 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelWidgetCondition.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;
@@ -56,7 +56,7 @@
  * Abstract base class for the condition models.
  */
 @SuppressWarnings("serial")
-public abstract class ModelWidgetCondition implements Serializable {
+public abstract class AbstractModelCondition implements Serializable, ModelCondition {
 
     /*
      * ----------------------------------------------------------------------- *
@@ -72,33 +72,39 @@
      * 
      */
 
-    public static final String module = ModelWidgetCondition.class.getName();
-    public static final ConditionFactory DEFAULT_CONDITION_FACTORY = new DefaultConditionFactory();
+    public static final String module = AbstractModelCondition.class.getName();
+    public static final ModelConditionFactory DEFAULT_CONDITION_FACTORY = new DefaultConditionFactory();
 
-    private final ModelWidget modelWidget;
-    private final Condition rootCondition;
-
-    protected ModelWidgetCondition(ConditionFactory factory, ModelWidget modelWidget, Element conditionElement) {
-        this.modelWidget = modelWidget;
-        Element firstChildElement = UtilXml.firstChildElement(conditionElement);
-        this.rootCondition = factory.newInstance(modelWidget, firstChildElement);
+    public static List<ModelCondition> readSubConditions(ModelConditionFactory factory, ModelWidget modelWidget,
+            Element conditionElement) {
+        List<? extends Element> subElementList = UtilXml.childElementList(conditionElement);
+        List<ModelCondition> condList = new ArrayList<ModelCondition>(subElementList.size());
+        for (Element subElement : subElementList) {
+            condList.add(factory.newInstance(modelWidget, subElement));
+        }
+        return Collections.unmodifiableList(condList);
     }
 
-    public boolean eval(Map<String, Object> context) {
-        return rootCondition.eval(context);
+    private final ModelWidget modelWidget;
+
+    protected AbstractModelCondition(ModelConditionFactory factory, ModelWidget modelWidget, Element conditionElement) {
+        this.modelWidget = modelWidget;
     }
 
     public ModelWidget getModelWidget() {
         return modelWidget;
     }
 
-    public static List<Condition> readSubConditions(ConditionFactory factory, ModelWidget modelWidget, Element conditionElement) {
-        List<? extends Element> subElementList = UtilXml.childElementList(conditionElement);
-        List<Condition> condList = new ArrayList<Condition>(subElementList.size());
-        for (Element subElement : subElementList) {
-            condList.add(factory.newInstance(modelWidget, subElement));
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        ModelConditionVisitor visitor = new XmlWidgetConditionVisitor(sb);
+        try {
+            accept(visitor);
+        } catch (Exception e) {
+            Debug.logWarning(e, "Exception thrown in XmlWidgetConditionVisitor: ", module);
         }
-        return Collections.unmodifiableList(condList);
+        return sb.toString();
     }
 
     /**
@@ -106,88 +112,98 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class And extends ModelWidgetCondition implements Condition {
-        private final List<Condition> subConditions;
+    public static class And extends AbstractModelCondition {
+        private final List<ModelCondition> subConditions;
 
-        private And(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private And(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             this.subConditions = readSubConditions(factory, modelWidget, condElement);
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             // return false for the first one in the list that is false, basic and algo
-            for (Condition subCondition : this.subConditions) {
+            for (ModelCondition subCondition : this.subConditions) {
                 if (!subCondition.eval(context)) {
                     return false;
                 }
             }
             return true;
         }
-    }
 
-    public static interface Condition {
-        boolean eval(Map<String, Object> context);
+        public List<ModelCondition> getSubConditions() {
+            return subConditions;
+        }
     }
 
     /**
-     * A factory for <code>Condition</code> instances.
+     * A <code>ModelCondition</code> factory. This factory handles elements
+     * common to all widgets that support conditions. Widgets that have
+     * specialized conditions can extend this class.
      *
      */
-    public static interface ConditionFactory {
-        /**
-         * Returns a new <code>Condition</code> instance built from <code>conditionElement</code>.
-         * 
-         * @param modelWidget The <code>ModelWidget</code> that contains the <code>Condition</code> instance.
-         * @param conditionElement The XML element used to build the <code>Condition</code> instance.
-         * @return A new <code>Condition</code> instance built from <code>conditionElement</code>.
-         * @throws IllegalArgumentException if no model was found for the XML element
-         */
-        Condition newInstance(ModelWidget modelWidget, Element conditionElement);
-    }
-
-    public static class DefaultConditionFactory implements ConditionFactory {
-        public static final Condition TRUE = new Condition() {
+    public static class DefaultConditionFactory implements ModelConditionFactory {
+        public static final ModelCondition TRUE = new ModelCondition() {
             @Override
             public boolean eval(Map<String, Object> context) {
                 return true;
             }
+
+            @Override
+            public void accept(ModelConditionVisitor visitor) throws Exception {
+            }
         };
-        public static final Condition FALSE = new Condition() {
+
+        public static final ModelCondition FALSE = new ModelCondition() {
             @Override
             public boolean eval(Map<String, Object> context) {
                 return false;
             }
+
+            @Override
+            public void accept(ModelConditionVisitor visitor) throws Exception {
+            }
         };
 
-        public Condition newInstance(ModelWidget modelWidget, Element conditionElement) {
+        public ModelCondition newInstance(ModelWidget modelWidget, Element conditionElement) {
+            return newInstance(this, modelWidget, conditionElement);
+        }
+
+        // TODO: Test extended factory
+        protected ModelCondition newInstance(ModelConditionFactory factory, ModelWidget modelWidget, Element conditionElement) {
             if (conditionElement == null) {
                 return TRUE;
             }
-            if ("and".equals(conditionElement.getNodeName())) {
-                return new And(this, modelWidget, conditionElement);
-            } else if ("xor".equals(conditionElement.getNodeName())) {
-                return new Xor(this, modelWidget, conditionElement);
-            } else if ("or".equals(conditionElement.getNodeName())) {
-                return new Or(this, modelWidget, conditionElement);
-            } else if ("not".equals(conditionElement.getNodeName())) {
-                return new Not(this, modelWidget, conditionElement);
-            } else if ("if-service-permission".equals(conditionElement.getNodeName())) {
-                return new IfServicePermission(this, modelWidget, conditionElement);
-            } else if ("if-has-permission".equals(conditionElement.getNodeName())) {
-                return new IfHasPermission(this, modelWidget, conditionElement);
-            } else if ("if-validate-method".equals(conditionElement.getNodeName())) {
-                return new IfValidateMethod(this, modelWidget, conditionElement);
-            } else if ("if-compare".equals(conditionElement.getNodeName())) {
-                return new IfCompare(this, modelWidget, conditionElement);
-            } else if ("if-compare-field".equals(conditionElement.getNodeName())) {
-                return new IfCompareField(this, modelWidget, conditionElement);
-            } else if ("if-regexp".equals(conditionElement.getNodeName())) {
-                return new IfRegexp(this, modelWidget, conditionElement);
-            } else if ("if-empty".equals(conditionElement.getNodeName())) {
-                return new IfEmpty(this, modelWidget, conditionElement);
-            } else if ("if-entity-permission".equals(conditionElement.getNodeName())) {
-                return new IfEntityPermission(this, modelWidget, conditionElement);
+            String nodeName = conditionElement.getNodeName();
+            if ("and".equals(nodeName)) {
+                return new And(factory, modelWidget, conditionElement);
+            } else if ("xor".equals(nodeName)) {
+                return new Xor(factory, modelWidget, conditionElement);
+            } else if ("or".equals(nodeName)) {
+                return new Or(factory, modelWidget, conditionElement);
+            } else if ("not".equals(nodeName)) {
+                return new Not(factory, modelWidget, conditionElement);
+            } else if ("if-service-permission".equals(nodeName)) {
+                return new IfServicePermission(factory, modelWidget, conditionElement);
+            } else if ("if-has-permission".equals(nodeName)) {
+                return new IfHasPermission(factory, modelWidget, conditionElement);
+            } else if ("if-validate-method".equals(nodeName)) {
+                return new IfValidateMethod(factory, modelWidget, conditionElement);
+            } else if ("if-compare".equals(nodeName)) {
+                return new IfCompare(factory, modelWidget, conditionElement);
+            } else if ("if-compare-field".equals(nodeName)) {
+                return new IfCompareField(factory, modelWidget, conditionElement);
+            } else if ("if-regexp".equals(nodeName)) {
+                return new IfRegexp(factory, modelWidget, conditionElement);
+            } else if ("if-empty".equals(nodeName)) {
+                return new IfEmpty(factory, modelWidget, conditionElement);
+            } else if ("if-entity-permission".equals(nodeName)) {
+                return new IfEntityPermission(factory, modelWidget, conditionElement);
             } else {
                 throw new IllegalArgumentException("Condition element not supported with name: " + conditionElement.getNodeName());
             }
@@ -199,14 +215,14 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class IfCompare extends ModelWidgetCondition implements Condition {
+    public static class IfCompare extends AbstractModelCondition {
         private final FlexibleMapAccessor<Object> fieldAcsr;
         private final FlexibleStringExpander formatExdr;
         private final String operator;
         private final String type;
         private final FlexibleStringExpander valueExdr;
 
-        private IfCompare(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private IfCompare(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             String fieldAcsr = condElement.getAttribute("field");
             if (fieldAcsr.isEmpty())
@@ -219,6 +235,11 @@
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             String value = this.valueExdr.expandString(context);
             String format = this.formatExdr.expandString(context);
@@ -242,6 +263,26 @@
             }
             return resultBool.booleanValue();
         }
+
+        public FlexibleMapAccessor<Object> getFieldAcsr() {
+            return fieldAcsr;
+        }
+
+        public FlexibleStringExpander getFormatExdr() {
+            return formatExdr;
+        }
+
+        public String getOperator() {
+            return operator;
+        }
+
+        public String getType() {
+            return type;
+        }
+
+        public FlexibleStringExpander getValueExdr() {
+            return valueExdr;
+        }
     }
 
     /**
@@ -249,14 +290,14 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class IfCompareField extends ModelWidgetCondition implements Condition {
+    public static class IfCompareField extends AbstractModelCondition {
         private final FlexibleMapAccessor<Object> fieldAcsr;
         private final FlexibleStringExpander formatExdr;
         private final String operator;
         private final FlexibleMapAccessor<Object> toFieldAcsr;
         private final String type;
 
-        private IfCompareField(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private IfCompareField(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             String fieldAcsr = condElement.getAttribute("field");
             if (fieldAcsr.isEmpty())
@@ -272,6 +313,11 @@
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             String format = this.formatExdr.expandString(context);
             Object fieldVal = this.fieldAcsr.get(context);
@@ -297,6 +343,26 @@
             }
             return resultBool.booleanValue();
         }
+
+        public FlexibleMapAccessor<Object> getFieldAcsr() {
+            return fieldAcsr;
+        }
+
+        public FlexibleStringExpander getFormatExdr() {
+            return formatExdr;
+        }
+
+        public String getOperator() {
+            return operator;
+        }
+
+        public FlexibleMapAccessor<Object> getToFieldAcsr() {
+            return toFieldAcsr;
+        }
+
+        public String getType() {
+            return type;
+        }
     }
 
     /**
@@ -304,10 +370,10 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class IfEmpty extends ModelWidgetCondition implements Condition {
+    public static class IfEmpty extends AbstractModelCondition {
         private final FlexibleMapAccessor<Object> fieldAcsr;
 
-        private IfEmpty(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private IfEmpty(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             String fieldAcsr = condElement.getAttribute("field");
             if (fieldAcsr.isEmpty())
@@ -316,10 +382,20 @@
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             Object fieldVal = this.fieldAcsr.get(context);
             return ObjectType.isEmpty(fieldVal);
         }
+
+        public FlexibleMapAccessor<Object> getFieldAcsr() {
+            return fieldAcsr;
+        }
+
     }
 
     /**
@@ -327,18 +403,27 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class IfEntityPermission extends ModelWidgetCondition implements Condition {
+    public static class IfEntityPermission extends AbstractModelCondition {
         private final EntityPermissionChecker permissionChecker;
 
-        private IfEntityPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private IfEntityPermission(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             this.permissionChecker = new EntityPermissionChecker(condElement);
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             return permissionChecker.runPermissionCheck(context);
         }
+
+        public EntityPermissionChecker getPermissionChecker() {
+            return permissionChecker;
+        }
     }
 
     /**
@@ -346,17 +431,22 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class IfHasPermission extends ModelWidgetCondition implements Condition {
+    public static class IfHasPermission extends AbstractModelCondition {
         private final FlexibleStringExpander actionExdr;
         private final FlexibleStringExpander permissionExdr;
 
-        private IfHasPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private IfHasPermission(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             this.permissionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("permission"));
             this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("action"));
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             // if no user is logged in, treat as if the user does not have permission
             GenericValue userLogin = (GenericValue) context.get("userLogin");
@@ -378,6 +468,14 @@
             }
             return false;
         }
+
+        public FlexibleStringExpander getActionExdr() {
+            return actionExdr;
+        }
+
+        public FlexibleStringExpander getPermissionExdr() {
+            return permissionExdr;
+        }
     }
 
     /**
@@ -385,11 +483,11 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class IfRegexp extends ModelWidgetCondition implements Condition {
+    public static class IfRegexp extends AbstractModelCondition {
         private final FlexibleStringExpander exprExdr;
         private final FlexibleMapAccessor<Object> fieldAcsr;
 
-        private IfRegexp(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private IfRegexp(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             String fieldAcsr = condElement.getAttribute("field");
             if (fieldAcsr.isEmpty())
@@ -399,6 +497,11 @@
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             Object fieldVal = this.fieldAcsr.get(context);
             String expr = this.exprExdr.expandString(context);
@@ -423,6 +526,14 @@
             PatternMatcher matcher = new Perl5Matcher();
             return matcher.matches(fieldString, pattern);
         }
+
+        public FlexibleStringExpander getExprExdr() {
+            return exprExdr;
+        }
+
+        public FlexibleMapAccessor<Object> getFieldAcsr() {
+            return fieldAcsr;
+        }
     }
 
     /**
@@ -430,13 +541,13 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class IfServicePermission extends ModelWidgetCondition implements Condition {
+    public static class IfServicePermission extends AbstractModelCondition {
         private final FlexibleStringExpander actionExdr;
         private final FlexibleStringExpander ctxMapExdr;
         private final FlexibleStringExpander resExdr;
         private final FlexibleStringExpander serviceExdr;
 
-        private IfServicePermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private IfServicePermission(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             this.serviceExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("service-name"));
             this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("main-action"));
@@ -445,6 +556,11 @@
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             // if no user is logged in, treat as if the user does not have permission
             GenericValue userLogin = (GenericValue) context.get("userLogin");
@@ -506,6 +622,22 @@
             }
             return false;
         }
+
+        public FlexibleStringExpander getActionExdr() {
+            return actionExdr;
+        }
+
+        public FlexibleStringExpander getCtxMapExdr() {
+            return ctxMapExdr;
+        }
+
+        public FlexibleStringExpander getResExdr() {
+            return resExdr;
+        }
+
+        public FlexibleStringExpander getServiceExdr() {
+            return serviceExdr;
+        }
     }
 
     /**
@@ -513,12 +645,12 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class IfValidateMethod extends ModelWidgetCondition implements Condition {
+    public static class IfValidateMethod extends AbstractModelCondition {
         private final FlexibleStringExpander classExdr;
         private final FlexibleMapAccessor<Object> fieldAcsr;
         private final FlexibleStringExpander methodExdr;
 
-        private IfValidateMethod(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private IfValidateMethod(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             String fieldAcsr = condElement.getAttribute("field");
             if (fieldAcsr.isEmpty())
@@ -529,6 +661,11 @@
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             String methodName = this.methodExdr.expandString(context);
             String className = this.classExdr.expandString(context);
@@ -570,6 +707,19 @@
             }
             return resultBool.booleanValue();
         }
+
+        public FlexibleStringExpander getClassExdr() {
+            return classExdr;
+        }
+
+        public FlexibleMapAccessor<Object> getFieldAcsr() {
+            return fieldAcsr;
+        }
+
+        public FlexibleStringExpander getMethodExdr() {
+            return methodExdr;
+        }
+
     }
 
     /**
@@ -577,19 +727,28 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class Not extends ModelWidgetCondition implements Condition {
-        private final Condition subCondition;
+    public static class Not extends AbstractModelCondition {
+        private final ModelCondition subCondition;
 
-        private Not(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private Not(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             Element firstChildElement = UtilXml.firstChildElement(condElement);
             this.subCondition = factory.newInstance(modelWidget, firstChildElement);
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             return !this.subCondition.eval(context);
         }
+
+        public ModelCondition getSubCondition() {
+            return subCondition;
+        }
     }
 
     /**
@@ -597,24 +756,33 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class Or extends ModelWidgetCondition implements Condition {
-        private final List<Condition> subConditions;
+    public static class Or extends AbstractModelCondition {
+        private final List<ModelCondition> subConditions;
 
-        private Or(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private Or(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             this.subConditions = readSubConditions(factory, modelWidget, condElement);
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             // return true for the first one in the list that is true, basic or algo
-            for (Condition subCondition : this.subConditions) {
+            for (ModelCondition subCondition : this.subConditions) {
                 if (subCondition.eval(context)) {
                     return true;
                 }
             }
             return false;
         }
+
+        public List<ModelCondition> getSubConditions() {
+            return subConditions;
+        }
     }
 
     /**
@@ -622,19 +790,24 @@
      * 
      * @see <code>widget-common.xsd</code>
      */
-    public static class Xor extends ModelWidgetCondition implements Condition {
-        private final List<Condition> subConditions;
+    public static class Xor extends AbstractModelCondition {
+        private final List<ModelCondition> subConditions;
 
-        private Xor(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
+        private Xor(ModelConditionFactory factory, ModelWidget modelWidget, Element condElement) {
             super(factory, modelWidget, condElement);
             this.subConditions = readSubConditions(factory, modelWidget, condElement);
         }
 
         @Override
+        public void accept(ModelConditionVisitor visitor) throws Exception {
+            visitor.visit(this);
+        }
+
+        @Override
         public boolean eval(Map<String, Object> context) {
             // if more than one is true stop immediately and return false; if all are false return false; if only one is true return true
             boolean foundOneTrue = false;
-            for (Condition subCondition : this.subConditions) {
+            for (ModelCondition subCondition : this.subConditions) {
                 if (subCondition.eval(context)) {
                     if (foundOneTrue) {
                         // now found two true, so return false
@@ -646,5 +819,9 @@
             }
             return foundOneTrue;
         }
+
+        public List<ModelCondition> getSubConditions() {
+            return subConditions;
+        }
     }
 }
diff --git a/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java b/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java
new file mode 100644
index 0000000..b538397
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/CommonWidgetModels.java
@@ -0,0 +1,629 @@
+/*******************************************************************************
+ * 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.math.BigDecimal;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilCodec;
+import org.ofbiz.base.util.UtilDateTime;
+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.Delegator;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelField;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ModelParam;
+import org.ofbiz.service.ModelService;
+import org.w3c.dom.Element;
+
+/**
+ * A collection of shared/reused widget models.
+ *
+ */
+public final class CommonWidgetModels {
+
+    public static final String module = CommonWidgetModels.class.getName();
+
+    private CommonWidgetModels() {
+    }
+
+    public static class AutoEntityParameters {
+        private String entityName;
+        List<String> excludeList = new ArrayList<String>();
+        boolean includeNonPk;
+        boolean includePk;
+        private String includeType;
+        boolean sendIfEmpty;
+
+        public AutoEntityParameters(Element autoElement) {
+            entityName = UtilXml.checkEmpty(autoElement.getAttribute("entity-name"));
+            sendIfEmpty = "true".equals(autoElement.getAttribute("send-if-empty"));
+            includeType = UtilXml.checkEmpty(autoElement.getAttribute("include"));
+            includePk = "pk".equals(includeType) || "all".equals(includeType);
+            includeNonPk = "nonpk".equals(includeType) || "all".equals(includeType);
+            List<? extends Element> excludes = UtilXml.childElementList(autoElement, "exclude");
+            if (excludes != null) {
+                for (Element exclude : excludes) {
+                    if (UtilValidate.isNotEmpty(exclude.getAttribute("field-name"))) {
+                        excludeList.add(exclude.getAttribute("field-name"));
+                    }
+                }
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public Map<String, String> getParametersMap(Map<String, Object> context, String defaultEntityName) {
+            Map<String, String> autEntityParams = new HashMap<String, String>();
+            Delegator delegator = (Delegator) context.get("delegator");
+            if (delegator == null) {
+                Debug.logError(
+                        "We can not append auto entity Parameters since we could not find delegator in the current context",
+                        module);
+                return autEntityParams;
+            }
+            if (UtilValidate.isEmpty(entityName))
+                entityName = defaultEntityName;
+            FlexibleStringExpander toExpand = FlexibleStringExpander.getInstance(entityName);
+            ModelEntity entity = delegator.getModelEntity(toExpand.expandString(context));
+            if (entity == null) {
+                Debug.logError("We can not append auto entity Parameters since we could not find entity with name [" + entityName
+                        + "]", module);
+                return autEntityParams;
+            }
+
+            Iterator<ModelField> fieldsIter = entity.getFieldsIterator();
+            if (fieldsIter != null) {
+                while (fieldsIter.hasNext()) {
+                    ModelField field = fieldsIter.next();
+                    String fieldName = field.getName();
+                    FlexibleMapAccessor<Object> fma = FlexibleMapAccessor.getInstance(fieldName);
+                    boolean shouldExclude = excludeList.contains(fieldName);
+                    if ((!shouldExclude) && (!field.getIsAutoCreatedInternal())
+                            && ((field.getIsPk() && includePk) || (!field.getIsPk() && includeNonPk))) {
+                        Object flexibleValue = fma.get(context);
+                        if (UtilValidate.isEmpty(flexibleValue) && context.containsKey("parameters")) {
+                            flexibleValue = fma.get((Map<String, Object>) context.get("parameters"));
+                        }
+                        if (UtilValidate.isNotEmpty(flexibleValue) || sendIfEmpty) {
+                            autEntityParams.put(fieldName, String.valueOf(flexibleValue));
+                        }
+                    }
+                }
+            }
+            return autEntityParams;
+        }
+    }
+
+    public static class AutoServiceParameters {
+        List<String> excludeList = new ArrayList<String>();
+        boolean includeNonPk;
+        boolean includePk;
+        boolean sendIfEmpty;
+        private String serviceName;
+
+        public AutoServiceParameters(Element autoElement) {
+            serviceName = UtilXml.checkEmpty(autoElement.getAttribute("service-name"));
+            sendIfEmpty = "true".equals(autoElement.getAttribute("send-if-empty"));
+            List<? extends Element> excludes = UtilXml.childElementList(autoElement, "exclude");
+            if (excludes != null) {
+                for (Element exclude : excludes) {
+                    if (UtilValidate.isNotEmpty(exclude.getAttribute("field-name"))) {
+                        excludeList.add(exclude.getAttribute("field-name"));
+                    }
+                }
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public Map<String, String> getParametersMap(Map<String, Object> context, String defaultServiceName) {
+            Map<String, String> autServiceParams = new HashMap<String, String>();
+            LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher");
+            if (dispatcher == null) {
+                Debug.logError(
+                        "We can not append auto service Parameters since we could not find dispatcher in the current context",
+                        module);
+                return autServiceParams;
+            }
+            if (UtilValidate.isEmpty(serviceName))
+                serviceName = defaultServiceName;
+            FlexibleStringExpander toExpand = FlexibleStringExpander.getInstance(serviceName);
+            ModelService service = null;
+            try {
+                service = dispatcher.getDispatchContext().getModelService(toExpand.toString());
+            } catch (GenericServiceException e) {
+                Debug.logError("Resolve service throw an error : " + e, module);
+            }
+            if (service == null) {
+                Debug.logError("We can not append auto service Parameters since we could not find service with name ["
+                        + serviceName + "]", module);
+                return autServiceParams;
+            }
+            Iterator<ModelParam> paramsIter = service.getInModelParamList().iterator();
+            if (paramsIter != null) {
+                while (paramsIter.hasNext()) {
+                    ModelParam param = paramsIter.next();
+                    if (param.getInternal())
+                        continue;
+                    String paramName = param.getName();
+                    FlexibleMapAccessor<Object> fma = FlexibleMapAccessor.getInstance(paramName);
+                    if (!excludeList.contains(paramName)) {
+                        Object flexibleValue = fma.get(context);
+                        if (UtilValidate.isEmpty(flexibleValue) && context.containsKey("parameters")) {
+                            flexibleValue = fma.get((Map<String, ? extends Object>) context.get("parameters"));
+                        }
+                        if (UtilValidate.isNotEmpty(flexibleValue) || sendIfEmpty) {
+                            autServiceParams.put(paramName, String.valueOf(flexibleValue));
+                        }
+                    }
+                }
+            }
+            return autServiceParams;
+        }
+    }
+
+    public static final class Image {
+        private final FlexibleStringExpander alt;
+        private final FlexibleStringExpander borderExdr;
+        private final FlexibleStringExpander heightExdr;
+        private final FlexibleStringExpander idExdr;
+        private final String name;
+        private final FlexibleStringExpander srcExdr;
+        private final FlexibleStringExpander styleExdr;
+        private final FlexibleStringExpander titleExdr;
+        private final String urlMode;
+        private final FlexibleStringExpander widthExdr;
+
+        public Image(Element imageElement) {
+            this.name = imageElement.getAttribute("name");
+            String src = imageElement.getAttribute("image-location");
+            if (src.isEmpty()) {
+                src = imageElement.getAttribute("src");
+            } else {
+                // Form field version, log warning.
+            }
+            this.srcExdr = FlexibleStringExpander.getInstance(src);
+            this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id"));
+            this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style"));
+            this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
+            this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
+            this.borderExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("border"));
+            String alt = imageElement.getAttribute("alternate");
+            if (alt.isEmpty()) {
+                alt = imageElement.getAttribute("alt"); // Common version, no warning.
+            } else {
+                // Form field version, log warning.
+            }
+            this.alt = FlexibleStringExpander.getInstance(alt);
+            String urlMode = imageElement.getAttribute("url-mode");
+            if (urlMode.isEmpty()) {
+                urlMode = "content";
+            }
+            this.urlMode = urlMode;
+            String title = imageElement.getAttribute("image-title");
+            if (title.isEmpty()) {
+                title = imageElement.getAttribute("title");
+            } else {
+                // Form field version, log warning.
+            }
+            this.titleExdr = FlexibleStringExpander.getInstance(title);
+        }
+
+        public FlexibleStringExpander getAlt() {
+            return alt;
+        }
+
+        public String getAlt(Map<String, Object> context) {
+            String alt = this.alt.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) {
+                alt = simpleEncoder.encode(alt);
+            }
+            return alt;
+        }
+
+        public String getBorder(Map<String, Object> context) {
+            return this.borderExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getBorderExdr() {
+            return borderExdr;
+        }
+
+        public String getHeight(Map<String, Object> context) {
+            return this.heightExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getHeightExdr() {
+            return heightExdr;
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getSrc(Map<String, Object> context) {
+            return this.srcExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getSrcExdr() {
+            return srcExdr;
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.styleExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return styleExdr;
+        }
+
+        public FlexibleStringExpander getTitleExdr() {
+            return titleExdr;
+        }
+
+        public String getUrlMode() {
+            return this.urlMode;
+        }
+
+        public String getWidth(Map<String, Object> context) {
+            return this.widthExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getWidthExdr() {
+            return widthExdr;
+        }
+    }
+
+    public static final class Link {
+        // FIXME: This is a bad practice. Client code should not need to "know" what this value is.
+        public static final String DEFAULT_URL_MODE = "intra-app";
+        private final AutoEntityParameters autoEntityParameters;
+        private final AutoServiceParameters autoServiceParameters;
+        private final boolean encode;
+        private final boolean fullPath;
+        private final FlexibleStringExpander idExdr;
+        private final Image image;
+        private final String linkType; // anchor or hidden form
+        private final FlexibleStringExpander nameExdr;
+        private final List<Parameter> parameterList;
+        private final FlexibleStringExpander prefixExdr;
+        private final boolean secure;
+        private final Integer size;
+        private final FlexibleStringExpander styleExdr;
+        private final FlexibleStringExpander targetExdr;
+        private final FlexibleStringExpander targetWindowExdr;
+        private final FlexibleStringExpander textExdr;
+        private final String urlMode;
+        // FIXME: These don't belong in this class
+        private final String height;
+        private final String width;
+
+        public Link(Element linkElement) {
+            this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
+            this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id"));
+            this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style"));
+            this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name"));
+            this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target"));
+            this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window"));
+            this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
+            this.urlMode = linkElement.getAttribute("url-mode");
+            this.fullPath = "true".equals(linkElement.getAttribute("full-path"));
+            this.secure = "true".equals(linkElement.getAttribute("secure"));
+            this.encode = "true".equals(linkElement.getAttribute("encode"));
+            Element imageElement = UtilXml.firstChildElement(linkElement, "image");
+            if (imageElement != null) {
+                this.image = new Image(imageElement);
+            } else {
+                // TODO: Look for ModelFormField attributes
+                this.image = null;
+            }
+            this.linkType = linkElement.getAttribute("link-type");
+            List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
+            if (parameterElementList.isEmpty()) {
+                this.parameterList = Collections.emptyList();
+            } else {
+                List<Parameter> parameterList = new ArrayList<Parameter>(
+                        parameterElementList.size());
+                for (Element parameterElement : parameterElementList) {
+                    parameterList.add(new Parameter(parameterElement));
+                }
+                this.parameterList = Collections.unmodifiableList(parameterList);
+            }
+            Element autoServiceParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-service");
+            if (autoServiceParamsElement != null) {
+                this.autoServiceParameters = new AutoServiceParameters(autoServiceParamsElement);
+            } else {
+                this.autoServiceParameters = null;
+            }
+            Element autoEntityParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-entity");
+            if (autoEntityParamsElement != null) {
+                this.autoEntityParameters = new AutoEntityParameters(autoEntityParamsElement);
+            } else {
+                this.autoEntityParameters = null;
+            }
+            Integer size = null;
+            String sizeAttr = linkElement.getAttribute("size");
+            if (!sizeAttr.isEmpty()) {
+                size = Integer.valueOf(sizeAttr);
+            }
+            this.size = size;
+            this.width = linkElement.getAttribute("width");
+            this.height = linkElement.getAttribute("height");
+        }
+
+        // Portal constructor
+        public Link(GenericValue portalPage, List<Parameter> parameterList, String target, Locale locale) {
+            this.autoEntityParameters = null;
+            this.autoServiceParameters = null;
+            this.encode = false;
+            this.fullPath = false;
+            this.idExdr = FlexibleStringExpander.getInstance("");
+            this.image = null;
+            this.linkType = "";
+            this.nameExdr = FlexibleStringExpander.getInstance("");
+            this.parameterList = Collections.unmodifiableList(parameterList);
+            this.prefixExdr = FlexibleStringExpander.getInstance("");
+            this.secure = false;
+            this.styleExdr = FlexibleStringExpander.getInstance("");
+            this.targetExdr = FlexibleStringExpander.getInstance(target);
+            this.targetWindowExdr = FlexibleStringExpander.getInstance("");
+            this.textExdr = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale));
+            this.urlMode = "intra-app";
+            this.size = null;
+            this.width = "";
+            this.height = "";
+        }
+
+        public AutoEntityParameters getAutoEntityParameters() {
+            return autoEntityParameters;
+        }
+
+        public AutoServiceParameters getAutoServiceParameters() {
+            return autoServiceParameters;
+        }
+
+        public boolean getEncode() {
+            return this.encode;
+        }
+
+        public boolean getFullPath() {
+            return this.fullPath;
+        }
+
+        public String getHeight() {
+            return this.height;
+        }
+
+        public String getId(Map<String, Object> context) {
+            return this.idExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getIdExdr() {
+            return idExdr;
+        }
+
+        public Image getImage() {
+            return this.image;
+        }
+
+        public String getLinkType() {
+            return this.linkType;
+        }
+
+        public String getName() {
+            return nameExdr.getOriginal();
+        }
+
+        public String getName(Map<String, Object> context) {
+            return this.nameExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getNameExdr() {
+            return nameExdr;
+        }
+
+        public List<Parameter> getParameterList() {
+            return parameterList;
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> context) {
+            Map<String, String> fullParameterMap = new HashMap<String, String>();
+            for (Parameter parameter : this.parameterList) {
+                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
+            }
+            if (autoServiceParameters != null) {
+                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, null));
+            }
+            if (autoEntityParameters != null) {
+                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, null));
+            }
+            return fullParameterMap;
+        }
+
+        public String getPrefix(Map<String, Object> context) {
+            return this.prefixExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getPrefixExdr() {
+            return prefixExdr;
+        }
+
+        public boolean getSecure() {
+            return this.secure;
+        }
+
+        public Integer getSize() {
+            return size;
+        }
+
+        public String getStyle(Map<String, Object> context) {
+            return this.styleExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getStyleExdr() {
+            return styleExdr;
+        }
+
+        public String getTarget(Map<String, Object> context) {
+            Map<String, Object> expanderContext = context;
+            UtilCodec.SimpleEncoder simpleEncoder = context == null ? null : (UtilCodec.SimpleEncoder) context
+                    .get("simpleEncoder");
+            if (simpleEncoder != null) {
+                expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
+            }
+            return this.targetExdr.expandString(expanderContext);
+        }
+
+        public FlexibleStringExpander getTargetExdr() {
+            return targetExdr;
+        }
+
+        public String getTargetWindow(Map<String, Object> context) {
+            return this.targetWindowExdr.expandString(context);
+        }
+
+        public FlexibleStringExpander getTargetWindowExdr() {
+            return targetWindowExdr;
+        }
+
+        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 FlexibleStringExpander getTextExdr() {
+            return textExdr;
+        }
+
+        public String getUrlMode() {
+            return this.urlMode;
+        }
+
+        public String getWidth() {
+            return this.width;
+        }
+    }
+
+    /**
+     * Models the &lt;parameter&gt; element.
+     * 
+     * @see <code>widget-form.xsd</code>
+     */
+    public static class Parameter {
+        protected FlexibleMapAccessor<Object> fromField;
+        protected String name;
+        protected FlexibleStringExpander value;
+
+        public Parameter(Element element) {
+            this.name = element.getAttribute("param-name");
+            this.value = UtilValidate.isNotEmpty(element.getAttribute("value")) ? FlexibleStringExpander.getInstance(element
+                    .getAttribute("value")) : null;
+            this.fromField = UtilValidate.isNotEmpty(element.getAttribute("from-field")) ? FlexibleMapAccessor
+                    .getInstance(element.getAttribute("from-field")) : null;
+        }
+
+        public Parameter(String paramName, String paramValue, boolean isField) {
+            this.name = paramName;
+            if (isField) {
+                this.fromField = FlexibleMapAccessor.getInstance(paramValue);
+            } else {
+                this.value = FlexibleStringExpander.getInstance(paramValue);
+            }
+        }
+
+        public FlexibleMapAccessor<Object> getFromField() {
+            return fromField;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public FlexibleStringExpander getValue() {
+            return value;
+        }
+
+        public String getValue(Map<String, Object> context) {
+            if (this.value != null) {
+                return this.value.expandString(context);
+            }
+            Object retVal = null;
+            if (this.fromField != null && this.fromField.get(context) != null) {
+                retVal = this.fromField.get(context);
+            } else {
+                retVal = context.get(this.name);
+            }
+            if (retVal != null) {
+                TimeZone timeZone = (TimeZone) context.get("timeZone");
+                if (timeZone == null)
+                    timeZone = TimeZone.getDefault();
+                String returnValue = null;
+                // format string based on the user's time zone (not locale because these are parameters)
+                if (retVal instanceof Double || retVal instanceof Float || retVal instanceof BigDecimal) {
+                    returnValue = retVal.toString();
+                } else if (retVal instanceof java.sql.Date) {
+                    DateFormat df = UtilDateTime.toDateFormat(UtilDateTime.DATE_FORMAT, timeZone, null);
+                    returnValue = df.format((java.util.Date) retVal);
+                } else if (retVal instanceof java.sql.Time) {
+                    DateFormat df = UtilDateTime.toTimeFormat(UtilDateTime.TIME_FORMAT, timeZone, null);
+                    returnValue = df.format((java.util.Date) retVal);
+                } else if (retVal instanceof java.sql.Timestamp) {
+                    DateFormat df = UtilDateTime.toDateTimeFormat(UtilDateTime.DATE_TIME_FORMAT, timeZone, null);
+                    returnValue = 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);
+                    returnValue = df.format((java.util.Date) retVal);
+                } else {
+                    returnValue = retVal.toString();
+                }
+                return returnValue;
+            } else {
+                return null;
+            }
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/FieldInfo.java b/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
similarity index 89%
rename from framework/widget/src/org/ofbiz/widget/form/FieldInfo.java
rename to framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
index 1231fee..7bc47b3 100644
--- a/framework/widget/src/org/ofbiz/widget/form/FieldInfo.java
+++ b/framework/widget/src/org/ofbiz/widget/model/FieldInfo.java
@@ -16,14 +16,15 @@
  * 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;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.ofbiz.widget.ModelFieldVisitor;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.widget.renderer.FormStringRenderer;
 import org.w3c.dom.Element;
 
 /**
@@ -31,6 +32,8 @@
  */
 public abstract class FieldInfo {
 
+    public static final String module = FieldInfo.class.getName();
+
     public static final int DISPLAY = 1;
     public static final int HYPERLINK = 2;
     public static final int TEXT = 3;
@@ -113,7 +116,7 @@
         this.modelFormField = modelFormField;
     }
 
-    public abstract void accept(ModelFieldVisitor visitor);
+    public abstract void accept(ModelFieldVisitor visitor) throws Exception;
 
     /**
      * Returns a new instance of this object.
@@ -136,4 +139,16 @@
 
     public abstract void renderFieldString(Appendable writer, Map<String, Object> context, FormStringRenderer formStringRenderer)
             throws IOException;
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        ModelFieldVisitor visitor = new XmlWidgetFieldVisitor(sb);
+        try {
+            accept(visitor);
+        } catch (Exception e) {
+            Debug.logWarning(e, "Exception thrown in XmlWidgetFieldVisitor: ", module);
+        }
+        return sb.toString();
+    }
 }
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 95%
rename from framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java
rename to framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java
index 702096a..66bb671 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/model/HtmlWidget.java
@@ -1,299 +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 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 static class HtmlTemplateDecoratorSection extends ModelScreenWidget {
-        protected String name;
-        protected List<ModelScreenWidget> subWidgets;
-
-        public HtmlTemplateDecoratorSection(ModelScreen modelScreen, Element htmlTemplateDecoratorSectionElement) {
-            super(modelScreen, htmlTemplateDecoratorSectionElement);
-            this.name = htmlTemplateDecoratorSectionElement.getAttribute("name");
-            // read sub-widgets
-            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);
-        }
-    }
-
-    @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 96%
rename from framework/widget/src/org/ofbiz/widget/screen/IterateSectionWidget.java
rename to framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java
index 3970cfe..670ca9b 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/IterateSectionWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/model/IterateSectionWidget.java
@@ -1,366 +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);
-    }
-}
-
-
+/*******************************************************************************
+ * 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/PortalPageWorkerInterface.java b/framework/widget/src/org/ofbiz/widget/model/ModelAction.java
similarity index 73%
copy from framework/widget/src/org/ofbiz/widget/PortalPageWorkerInterface.java
copy to framework/widget/src/org/ofbiz/widget/model/ModelAction.java
index 3cc1d87..6503686 100644
--- a/framework/widget/src/org/ofbiz/widget/PortalPageWorkerInterface.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelAction.java
@@ -1,33 +1,36 @@
-/*******************************************************************************
- * 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.model;
+
+import java.util.Map;
+
+import org.ofbiz.base.util.GeneralException;
+
+public interface ModelAction {
+
+    void accept(ModelActionVisitor visitor) throws Exception;
+
+    /**
+     * Executes this action.
+     * 
+     * @param context
+     * @throws GeneralException
+     */
+    void runAction(Map<String, Object> context) throws GeneralException;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java b/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java
new file mode 100644
index 0000000..84085a5
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelActionVisitor.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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 Exception ; 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;
+
+/**
+ *  A <code>ModelAction</code> visitor.
+ */
+public interface ModelActionVisitor {
+
+    void visit(ModelFormAction.CallParentActions callParentActions) throws Exception;
+
+    void visit(AbstractModelAction.EntityAnd entityAnd) throws Exception;
+
+    void visit(AbstractModelAction.EntityCondition entityCondition) throws Exception;
+
+    void visit(AbstractModelAction.EntityOne entityOne) throws Exception;
+
+    void visit(AbstractModelAction.GetRelated getRelated) throws Exception;
+
+    void visit(AbstractModelAction.GetRelatedOne getRelatedOne) throws Exception;
+
+    void visit(AbstractModelAction.PropertyMap propertyMap) throws Exception;
+
+    void visit(AbstractModelAction.PropertyToField propertyToField) throws Exception;
+
+    void visit(AbstractModelAction.Script script) throws Exception;
+
+    void visit(AbstractModelAction.Service service) throws Exception;
+
+    void visit(AbstractModelAction.SetField setField) throws Exception;
+
+    void visit(ModelFormAction.Service service) throws Exception;
+
+    void visit(ModelMenuAction.SetField setField) throws Exception;
+
+    void visit(ModelTreeAction.Script script) throws Exception;
+
+    void visit(ModelTreeAction.Service service) throws Exception;
+
+    void visit(ModelTreeAction.EntityAnd entityAnd) throws Exception;
+
+    void visit(ModelTreeAction.EntityCondition entityCondition) throws Exception;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/PortalPageWorkerInterface.java b/framework/widget/src/org/ofbiz/widget/model/ModelCondition.java
similarity index 70%
copy from framework/widget/src/org/ofbiz/widget/PortalPageWorkerInterface.java
copy to framework/widget/src/org/ofbiz/widget/model/ModelCondition.java
index 3cc1d87..b7f6ff9 100644
--- a/framework/widget/src/org/ofbiz/widget/PortalPageWorkerInterface.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelCondition.java
@@ -1,33 +1,28 @@
-/*******************************************************************************
- * 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.model;
+
+import java.util.Map;
+
+public interface ModelCondition {
+
+    void accept(ModelConditionVisitor visitor) throws Exception;
+
+    boolean eval(Map<String, Object> context);
+}
diff --git a/framework/widget/src/org/ofbiz/widget/model/ModelConditionFactory.java b/framework/widget/src/org/ofbiz/widget/model/ModelConditionFactory.java
new file mode 100644
index 0000000..e47799d
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelConditionFactory.java
@@ -0,0 +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.model;
+
+import org.w3c.dom.Element;
+
+/**
+ * A factory for <code>Condition</code> instances.
+ *
+ */
+public interface ModelConditionFactory {
+    /**
+     * Returns a new <code>ModelCondition</code> instance built from <code>conditionElement</code>.
+     * 
+     * @param modelWidget The <code>ModelWidget</code> that contains the <code>Condition</code> instance.
+     * @param conditionElement The XML element used to build the <code>Condition</code> instance.
+     * @return A new <code>ModelCondition</code> instance built from <code>conditionElement</code>.
+     * @throws IllegalArgumentException if no model was found for the XML element
+     */
+    ModelCondition newInstance(ModelWidget modelWidget, Element conditionElement);
+}
diff --git a/framework/widget/src/org/ofbiz/widget/model/ModelConditionVisitor.java b/framework/widget/src/org/ofbiz/widget/model/ModelConditionVisitor.java
new file mode 100644
index 0000000..a60dd39
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelConditionVisitor.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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 Exception ; 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.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.
+ */
+public interface ModelConditionVisitor {
+
+    void visit(And and) throws Exception;
+
+    void visit(IfCompare ifCompare) throws Exception;
+
+    void visit(IfCompareField ifCompareField) throws Exception;
+
+    void visit(IfEmpty ifEmpty) throws Exception;
+
+    void visit(IfEntityPermission ifEntityPermission) throws Exception;
+
+    void visit(IfHasPermission ifHasPermission) throws Exception;
+
+    void visit(IfRegexp ifRegexp) throws Exception;
+
+    void visit(IfServicePermission ifServicePermission) throws Exception;
+
+    void visit(IfValidateMethod ifValidateMethod) throws Exception;
+
+    void visit(Not not) throws Exception;
+
+    void visit(Or or) throws Exception;
+
+    void visit(Xor xor) throws Exception;
+
+    void visit(ModelMenuCondition modelMenuCondition) throws Exception;
+
+    void visit(ModelTreeCondition modelTreeCondition) throws Exception;
+
+    void visit(IfEmptySection ifEmptySection) throws Exception;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java b/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
new file mode 100644
index 0000000..753971b
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelFieldVisitor.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * 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 Exception ; 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.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.
+ */
+public interface ModelFieldVisitor {
+
+    void visit(CheckField checkField) throws Exception ;
+
+    void visit(ContainerField containerField) throws Exception ;
+
+    void visit(DateFindField dateTimeField) throws Exception ;
+
+    void visit(DateTimeField dateTimeField) throws Exception ;
+
+    void visit(DisplayEntityField displayField) throws Exception ;
+
+    void visit(DisplayField displayField) throws Exception ;
+
+    void visit(DropDownField dropDownField) throws Exception ;
+
+    void visit(FileField textField) throws Exception ;
+
+    void visit(HiddenField hiddenField) throws Exception ;
+
+    void visit(HyperlinkField hyperlinkField) throws Exception ;
+
+    void visit(IgnoredField ignoredField) throws Exception ;
+
+    void visit(ImageField imageField) throws Exception ;
+
+    void visit(LookupField textField) throws Exception ;
+
+    void visit(PasswordField textField) throws Exception ;
+
+    void visit(RadioField radioField) throws Exception ;
+
+    void visit(RangeFindField textField) throws Exception ;
+
+    void visit(ResetField resetField) throws Exception ;
+
+    void visit(SubmitField submitField) throws Exception ;
+
+    void visit(TextareaField textareaField) throws Exception ;
+
+    void visit(TextField textField) throws Exception ;
+
+    void visit(TextFindField textField) throws Exception ;
+}
diff --git a/framework/widget/src/org/ofbiz/widget/form/ModelForm.java b/framework/widget/src/org/ofbiz/widget/model/ModelForm.java
similarity index 97%
rename from framework/widget/src/org/ofbiz/widget/form/ModelForm.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelForm.java
index eda200f..73b87bb 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelForm.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelForm.java
@@ -1,1832 +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.ModelWidget;
-import org.ofbiz.widget.ModelWidgetAction;
-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<ModelWidgetAction> 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<ModelWidgetAction> 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<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>();
-        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<ModelWidgetAction> rowActions = new ArrayList<ModelWidgetAction>();
-        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<ModelWidgetAction> 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<ModelWidgetAction> 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) {
-        ModelWidgetAction.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 WidgetWorker.AutoEntityParameters autoEntityParameters;
-        private final WidgetWorker.AutoEntityParameters autoServiceParameters;
-        private final List<WidgetWorker.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<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>(parameterElementList.size());
-                for (Element parameterElement : parameterElementList) {
-                    parameterList.add(new WidgetWorker.Parameter(parameterElement));
-                }
-                this.parameterList = Collections.unmodifiableList(parameterList);
-            }
-            Element autoServiceParamsElement = UtilXml.firstChildElement(updateAreaElement, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                this.autoServiceParameters = new WidgetWorker.AutoEntityParameters(autoServiceParamsElement);
-            } else {
-                this.autoServiceParameters = null;
-            }
-            Element autoEntityParamsElement = UtilXml.firstChildElement(updateAreaElement, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                this.autoEntityParameters = new WidgetWorker.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 (WidgetWorker.Parameter parameter : this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-            }
-
-            return fullParameterMap;
-        }
-
-        @Override
-        public int hashCode() {
-            return areaId.hashCode();
-        }
-    }
-}
+/*******************************************************************************
+ * 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 88%
rename from framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelFormAction.java
index 303453b..46c60c5 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelFormAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelFormAction.java
@@ -1,250 +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.ModelActionVisitor;
-import org.ofbiz.widget.ModelWidgetAction;
-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<ModelWidgetAction> readSubActions(ModelForm modelForm, Element parentElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
-        List<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>(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(ModelWidgetAction.newInstance(modelForm, actionElement));
-            } else if ("call-parent-actions".equals(actionElement.getNodeName())) {
-                actions.add(new CallParentActions(modelForm, actionElement));
-            } else {
-                actions.add(ModelWidgetAction.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 ModelWidgetAction {
-        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) {
-            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:
-                ModelWidgetAction.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 ModelWidgetAction {
-        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) {
-            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);
-                }
-            }
-        }
-    }
-}
+/*******************************************************************************
+ * 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 90%
rename from framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
index 395ffd9..4e6f3c6 100644
--- a/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelFormField.java
@@ -1,3875 +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.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) {
-            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) {
-            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) {
-            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) {
-            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) {
-            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) {
-            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) {
-            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 isAllowEmpty() {
-            return this.allowEmpty;
-        }
-
-        public boolean isAllowMultiple() {
-            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) {
-            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) {
-            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 {
-        public static String DEFAULT_TARGET_TYPE = "intra-app";
-
-        private final boolean alsoHidden;
-        private final FlexibleStringExpander alternate;
-        private final WidgetWorker.AutoEntityParameters autoEntityParameters;
-        private final WidgetWorker.AutoServiceParameters autoServiceParameters;
-        private final FlexibleStringExpander confirmationMsgExdr;
-        private final FlexibleStringExpander description;
-        private final FlexibleStringExpander imageLocation;
-        private final FlexibleStringExpander imageTitle;
-        private final String linkType;
-        private final List<WidgetWorker.Parameter> parameterList;
-        private final FlexibleMapAccessor<Map<String, String>> parametersMapAcsr;
-        private final boolean requestConfirmation;
-        private final String size;
-        private final FlexibleStringExpander target;
-        private final String targetType;
-        private final FlexibleStringExpander targetWindowExdr;
-
-        public HyperlinkField(Element element, ModelFormField modelFormField) {
-            super(element, modelFormField);
-            this.alsoHidden = !"false".equals(element.getAttribute("also-hidden"));
-            this.alternate = FlexibleStringExpander.getInstance(element.getAttribute("alternate"));
-            Element autoEntityParamsElement = UtilXml.firstChildElement(element, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                this.autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement);
-            } else {
-                this.autoEntityParameters = null;
-            }
-            Element autoServiceParamsElement = UtilXml.firstChildElement(element, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                this.autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement);
-            } else {
-                this.autoServiceParameters = null;
-            }
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message"));
-            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
-            this.imageLocation = FlexibleStringExpander.getInstance(element.getAttribute("image-location"));
-            this.imageTitle = FlexibleStringExpander.getInstance(element.getAttribute("image-title"));
-            this.linkType = element.getAttribute("link-type");
-            List<? extends Element> parameterElementList = UtilXml.childElementList(element, "parameter");
-            if (!parameterElementList.isEmpty()) {
-                List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>(parameterElementList.size());
-                for (Element parameterElement : parameterElementList) {
-                    parameterList.add(new WidgetWorker.Parameter(parameterElement));
-                }
-                this.parameterList = Collections.unmodifiableList(parameterList);
-            } else {
-                this.parameterList = Collections.emptyList();
-            }
-            this.parametersMapAcsr = FlexibleMapAccessor.getInstance(element.getAttribute("parameters-map"));
-            this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation"));
-            this.size = element.getAttribute("size");
-            this.target = FlexibleStringExpander.getInstance(element.getAttribute("target"));
-            this.targetType = element.getAttribute("target-type");
-            this.targetWindowExdr = FlexibleStringExpander.getInstance(element.getAttribute("target-window"));
-        }
-
-        private HyperlinkField(HyperlinkField original, ModelFormField modelFormField) {
-            super(original.getFieldSource(), original.getFieldType(), modelFormField);
-            this.description = original.description;
-            this.alternate = original.alternate;
-            this.imageLocation = original.imageLocation;
-            this.imageTitle = original.imageTitle;
-            this.target = original.target;
-            this.alsoHidden = original.alsoHidden;
-            this.linkType = original.linkType;
-            this.targetType = original.targetType;
-            this.targetWindowExdr = original.targetWindowExdr;
-            this.parametersMapAcsr = original.parametersMapAcsr;
-            this.size = original.size;
-            this.requestConfirmation = original.requestConfirmation;
-            this.confirmationMsgExdr = original.confirmationMsgExdr;
-            this.parameterList = original.parameterList;
-            this.autoEntityParameters = original.autoEntityParameters;
-            this.autoServiceParameters = original.autoServiceParameters;
-        }
-
-        public HyperlinkField(int fieldSource, ModelFormField modelFormField) {
-            super(fieldSource, FieldInfo.HYPERLINK, modelFormField);
-            this.alsoHidden = true;
-            this.alternate = FlexibleStringExpander.getInstance("");
-            this.autoEntityParameters = null;
-            this.autoServiceParameters = null;
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance("");
-            this.description = FlexibleStringExpander.getInstance("");
-            this.imageLocation = FlexibleStringExpander.getInstance("");
-            this.imageTitle = FlexibleStringExpander.getInstance("");
-            this.linkType = "";
-            this.parameterList = Collections.emptyList();
-            this.parametersMapAcsr = FlexibleMapAccessor.getInstance("");
-            this.requestConfirmation = false;
-            this.size = "";
-            this.target = FlexibleStringExpander.getInstance("");
-            this.targetType = "";
-            this.targetWindowExdr = FlexibleStringExpander.getInstance("");
-        }
-
-        public HyperlinkField(ModelFormField modelFormField) {
-            this(FieldInfo.SOURCE_EXPLICIT, modelFormField);
-        }
-
-        @Override
-        public void accept(ModelFieldVisitor visitor) {
-            visitor.visit(this);
-        }
-
-        @Override
-        public FieldInfo copy(ModelFormField modelFormField) {
-            return new HyperlinkField(this, modelFormField);
-        }
-
-        public boolean getAlsoHidden() {
-            return this.alsoHidden;
-        }
-
-        public FlexibleStringExpander getAlternate() {
-            return alternate;
-        }
-
-        public String getAlternate(Map<String, Object> context) {
-            return this.alternate.expandString(context);
-        }
-
-        public WidgetWorker.AutoEntityParameters getAutoEntityParameters() {
-            return autoEntityParameters;
-        }
-
-        public WidgetWorker.AutoServiceParameters getAutoServiceParameters() {
-            return autoServiceParameters;
-        }
-
-        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 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 FlexibleStringExpander getImageLocation() {
-            return imageLocation;
-        }
-
-        public String getImageLocation(Map<String, Object> context) {
-            return this.imageLocation.expandString(context);
-        }
-
-        public FlexibleStringExpander getImageTitle() {
-            return imageTitle;
-        }
-
-        public String getImageTitle(Map<String, Object> context) {
-            return this.imageTitle.expandString(context);
-        }
-
-        public String getLinkType() {
-            return this.linkType;
-        }
-
-        public List<WidgetWorker.Parameter> getParameterList() {
-            return parameterList;
-        }
-
-        public Map<String, String> getParameterMap(Map<String, Object> context) {
-            Map<String, String> fullParameterMap = new HashMap<String, String>();
-
-            Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
-            if (addlParamMap != null) {
-                fullParameterMap.putAll(addlParamMap);
-            }
-
-            for (WidgetWorker.Parameter parameter : this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-            }
-
-            if (autoServiceParameters != null) {
-                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, this.getModelFormField().getModelForm()
-                        .getDefaultServiceName()));
-            }
-
-            if (autoEntityParameters != null) {
-                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, this.getModelFormField().getModelForm()
-                        .getDefaultEntityName()));
-            }
-
-            return fullParameterMap;
-        }
-
-        public FlexibleMapAccessor<Map<String, String>> getParametersMapAcsr() {
-            return parametersMapAcsr;
-        }
-
-        public boolean getRequestConfirmation() {
-            return this.requestConfirmation;
-        }
-
-        public String getSize() {
-            return this.size;
-        }
-
-        public FlexibleStringExpander getTarget() {
-            return target;
-        }
-
-        public String getTarget(Map<String, Object> context) {
-            return this.target.expandString(context);
-        }
-
-        public String getTargetType() {
-            if (UtilValidate.isNotEmpty(this.targetType))
-                return this.targetType;
-            return HyperlinkField.DEFAULT_TARGET_TYPE;
-        }
-
-        public String getTargetWindow(Map<String, Object> context) {
-            String targetWindow = this.targetWindowExdr.expandString(context);
-            return targetWindow;
-        }
-
-        public FlexibleStringExpander getTargetWindowExdr() {
-            return targetWindowExdr;
-        }
-
-        @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) {
-            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) {
-            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) {
-            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) {
-            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) {
-            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) {
-            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) {
-            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 WidgetWorker.AutoEntityParameters autoEntityParameters;
-        private final WidgetWorker.AutoServiceParameters autoServiceParameters;
-        private final FlexibleStringExpander confirmationMsgExdr;
-        private final FlexibleStringExpander description;
-        private final String linkStyle;
-        private final String linkType;
-        private final ModelFormField modelFormField;
-        private final List<WidgetWorker.Parameter> parameterList;
-        private final boolean requestConfirmation;
-        private final FlexibleStringExpander target;
-        private final String targetType;
-        private final FlexibleStringExpander targetWindowExdr;
-        private final FlexibleStringExpander useWhen;
-
-        public SubHyperlink(Element element, ModelFormField modelFormField) {
-            Element autoEntityParamsElement = UtilXml.firstChildElement(element, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                this.autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement);
-            } else {
-                this.autoEntityParameters = null;
-            }
-            Element autoServiceParamsElement = UtilXml.firstChildElement(element, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                this.autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement);
-            } else {
-                this.autoServiceParameters = null;
-            }
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(element.getAttribute("confirmation-message"));
-            this.description = FlexibleStringExpander.getInstance(element.getAttribute("description"));
-            this.linkStyle = element.getAttribute("link-style");
-            this.linkType = element.getAttribute("link-type");
-            this.modelFormField = modelFormField;
-            List<? extends Element> parameterElementList = UtilXml.childElementList(element, "parameter");
-            if (!parameterElementList.isEmpty()) {
-                List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>(parameterElementList.size());
-                for (Element parameterElement : parameterElementList) {
-                    parameterList.add(new WidgetWorker.Parameter(parameterElement));
-                }
-                this.parameterList = Collections.unmodifiableList(parameterList);
-            } else {
-                this.parameterList = Collections.emptyList();
-
-            }
-            this.requestConfirmation = "true".equals(element.getAttribute("request-confirmation"));
-            this.target = FlexibleStringExpander.getInstance(element.getAttribute("target"));
-            this.targetType = element.getAttribute("target-type");
-            this.targetWindowExdr = FlexibleStringExpander.getInstance(element.getAttribute("target-window"));
-            this.useWhen = FlexibleStringExpander.getInstance(element.getAttribute("use-when"));
-        }
-
-        public SubHyperlink(SubHyperlink original, ModelFormField modelFormField) {
-            this.autoEntityParameters = original.autoEntityParameters;
-            this.autoServiceParameters = original.autoServiceParameters;
-            this.confirmationMsgExdr = original.confirmationMsgExdr;
-            this.description = original.description;
-            this.linkStyle = original.linkStyle;
-            this.linkType = original.linkType;
-            this.modelFormField = modelFormField;
-            this.parameterList = original.parameterList;
-            this.requestConfirmation = original.requestConfirmation;
-            this.target = original.target;
-            this.targetType = original.targetType;
-            this.targetWindowExdr = original.targetWindowExdr;
-            this.useWhen = original.useWhen;
-        }
-
-        public WidgetWorker.AutoEntityParameters getAutoEntityParameters() {
-            return autoEntityParameters;
-        }
-
-        public WidgetWorker.AutoServiceParameters getAutoServiceParameters() {
-            return autoServiceParameters;
-        }
-
-        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 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) {
-            if (this.description != null) {
-                return this.description.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        public String getLinkStyle() {
-            return this.linkStyle;
-        }
-
-        public String getLinkType() {
-            return this.linkType;
-        }
-
-        public ModelFormField getModelFormField() {
-            return this.modelFormField;
-        }
-
-        public List<WidgetWorker.Parameter> getParameterList() {
-            return parameterList;
-        }
-
-        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 (WidgetWorker.Parameter parameter : this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-            }
-
-            if (autoServiceParameters != null) {
-                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, getModelFormField().getModelForm()
-                        .getDefaultServiceName()));
-            }
-            if (autoEntityParameters != null) {
-                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, this.getModelFormField().getModelForm()
-                        .getDefaultEntityName()));
-            }
-
-            return fullParameterMap;
-        }
-
-        public boolean getRequestConfirmation() {
-            return this.requestConfirmation;
-        }
-
-        public FlexibleStringExpander getTarget() {
-            return target;
-        }
-
-        public String getTarget(Map<String, Object> context) {
-            if (this.target != null) {
-                return this.target.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        public String getTargetType() {
-            if (UtilValidate.isNotEmpty(this.targetType))
-                return this.targetType;
-            return HyperlinkField.DEFAULT_TARGET_TYPE;
-        }
-
-        public String getTargetWindow(Map<String, Object> context) {
-            String targetWindow = this.targetWindowExdr.expandString(context);
-            return targetWindow;
-        }
-
-        public FlexibleStringExpander getTargetWindowExdr() {
-            return targetWindowExdr;
-        }
-
-        public FlexibleStringExpander getUseWhen() {
-            return useWhen;
-        }
-
-        public String getUseWhen(Map<String, Object> context) {
-            if (this.useWhen != null) {
-                return this.useWhen.expandString(context);
-            } else {
-                return "";
-            }
-        }
-
-        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) {
-            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) {
-            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) {
-            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) {
-            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 86%
rename from framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelMenu.java
index fa28058..7d98c20 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenu.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelMenu.java
@@ -1,552 +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.ModelWidgetAction;
-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<ModelWidgetAction> 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 defaultPermissionStatusId;
-    private final String defaultPrivilegeEnumId;
-    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 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<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>();
-        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 defaultPermissionStatusId = "";
-        String defaultPrivilegeEnumId = "";
-        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
-        String parentResource = menuElement.getAttribute("extends-resource");
-        String parentMenu = menuElement.getAttribute("extends");
-        if (!parentMenu.isEmpty()) {
-            ModelMenu parent = null;
-            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");
-                //Uncomment below to add support for abstract menus
-                //menuElements.addAll(UtilXml.childElementList(rootElement, "abstract-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;
-                defaultPermissionStatusId = parent.defaultPermissionStatusId;
-                defaultPrivilegeEnumId = parent.defaultPrivilegeEnumId;
-                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.hasAttribute("type"))
-            type = menuElement.getAttribute("type");
-        if (menuElement.hasAttribute("target"))
-            target = menuElement.getAttribute("target");
-        if (menuElement.hasAttribute("id"))
-            id = menuElement.getAttribute("id");
-        if (menuElement.hasAttribute("title"))
-            title = FlexibleStringExpander.getInstance(menuElement.getAttribute("title"));
-        if (menuElement.hasAttribute("tooltip"))
-            tooltip = menuElement.getAttribute("tooltip");
-        if (menuElement.hasAttribute("default-entity-name"))
-            defaultEntityName = menuElement.getAttribute("default-entity-name");
-        if (menuElement.hasAttribute("default-title-style"))
-            defaultTitleStyle = menuElement.getAttribute("default-title-style");
-        if (menuElement.hasAttribute("default-selected-style"))
-            defaultSelectedStyle = menuElement.getAttribute("default-selected-style");
-        if (menuElement.hasAttribute("default-widget-style"))
-            defaultWidgetStyle = menuElement.getAttribute("default-widget-style");
-        if (menuElement.hasAttribute("default-tooltip-style"))
-            defaultTooltipStyle = menuElement.getAttribute("default-tooltip-style");
-        if (menuElement.hasAttribute("default-menu-item-name"))
-            defaultMenuItemName = menuElement.getAttribute("default-menu-item-name");
-        if (menuElement.hasAttribute("default-permission-operation"))
-            defaultPermissionOperation = menuElement.getAttribute("default-permission-operation");
-        if (menuElement.hasAttribute("default-permission-entity-action"))
-            defaultPermissionEntityAction = menuElement.getAttribute("default-permission-entity-action");
-        if (menuElement.hasAttribute("defaultPermissionStatusId"))
-            defaultPermissionStatusId = menuElement.getAttribute("default-permission-status-id");
-        if (menuElement.hasAttribute("defaultPrivilegeEnumId"))
-            defaultPrivilegeEnumId = menuElement.getAttribute("default-privilege-enum-id");
-        if (menuElement.hasAttribute("defaultAssociatedContentId"))
-            defaultAssociatedContentId = FlexibleStringExpander.getInstance(menuElement
-                    .getAttribute("default-associated-content-id"));
-        if (menuElement.hasAttribute("orientation"))
-            orientation = menuElement.getAttribute("orientation");
-        if (menuElement.hasAttribute("menu-width"))
-            menuWidth = menuElement.getAttribute("menu-width");
-        if (menuElement.hasAttribute("default-cell-width"))
-            defaultCellWidth = menuElement.getAttribute("default-cell-width");
-        if (menuElement.hasAttribute("default-hide-if-selected"))
-            defaultHideIfSelected = "true".equals(menuElement.getAttribute("default-hide-if-selected"));
-        if (menuElement.hasAttribute("default-disabled-title-style"))
-            defaultDisabledTitleStyle = menuElement.getAttribute("default-disabled-title-style");
-        if (menuElement.hasAttribute("selected-menuitem-context-field-name"))
-            selectedMenuItemContextFieldName = FlexibleMapAccessor.getInstance(menuElement
-                    .getAttribute("selected-menuitem-context-field-name"));
-        if (menuElement.hasAttribute("menu-container-style"))
-            menuContainerStyleExdr = FlexibleStringExpander.getInstance(menuElement.getAttribute("menu-container-style"));
-        if (menuElement.hasAttribute("default-align"))
-            defaultAlign = menuElement.getAttribute("default-align");
-        if (menuElement.hasAttribute("default-align-style"))
-            defaultAlignStyle = menuElement.getAttribute("default-align-style");
-        if (menuElement.hasAttribute("fill-style"))
-            fillStyle = menuElement.getAttribute("fill-style");
-        if (menuElement.hasAttribute("extra-index"))
-            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.defaultPermissionStatusId = defaultPermissionStatusId;
-        this.defaultPrivilegeEnumId = defaultPrivilegeEnumId;
-        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.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<ModelWidgetAction> 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 getDefaultPermissionStatusId() {
-        return this.defaultPermissionStatusId;
-    }
-
-    public String getDefaultPrivilegeEnumId() {
-        return this.defaultPrivilegeEnumId;
-    }
-
-    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 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 {
-        ModelWidgetAction.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) {
-        ModelWidgetAction.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 89%
rename from framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelMenuAction.java
index 6fae76d..7351724 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelMenuAction.java
@@ -1,202 +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.ModelWidgetAction;
-import org.w3c.dom.Element;
-
-/**
- * Abstract menu action.
- */
-public abstract class ModelMenuAction {
-
-    public static final String module = ModelMenuAction.class.getName();
-
-    public static List<ModelWidgetAction> readSubActions(ModelMenu modelMenu, Element parentElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(parentElement);
-        List<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>(actionElementList.size());
-        for (Element actionElement : actionElementList) {
-            if ("set".equals(actionElement.getNodeName())) {
-                actions.add(new SetField(modelMenu, actionElement));
-            } else {
-                actions.add(ModelWidgetAction.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 ModelWidgetAction {
-        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) {
-            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.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 88%
rename from framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelMenuCondition.java
index 721ce77..b9aec8c 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelMenuCondition.java
@@ -1,65 +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.ModelWidgetCondition;
-import org.w3c.dom.Element;
-
-/**
- * Models the &lt;condition&gt; element.
- * 
- * @see <code>widget-menu.xsd</code>
- */
-@SuppressWarnings("serial")
-public class ModelMenuCondition extends ModelWidgetCondition {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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;
-
-    public ModelMenuCondition(ModelMenuItem modelMenuItem, Element conditionElement) {
-        super(ModelWidgetCondition.DEFAULT_CONDITION_FACTORY, modelMenuItem, conditionElement);
-        this.passStyleExdr = FlexibleStringExpander.getInstance(conditionElement.getAttribute("pass-style"));
-        this.failStyleExdr = FlexibleStringExpander.getInstance(conditionElement.getAttribute("disabled-style"));
-    }
-
-    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 60%
rename from framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java
index fcc05a6..2ee5b5a 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/ModelMenuItem.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelMenuItem.java
@@ -1,826 +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 javax.xml.parsers.ParserConfigurationException;
-
-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.base.util.UtilXml;
-import org.ofbiz.base.util.collections.FlexibleMapAccessor;
-import org.ofbiz.base.util.string.FlexibleStringExpander;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.widget.ModelWidget;
-import org.ofbiz.widget.ModelWidgetAction;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.PortalPageWorker;
-import org.ofbiz.widget.WidgetWorker.AutoEntityParameters;
-import org.ofbiz.widget.WidgetWorker.AutoServiceParameters;
-import org.ofbiz.widget.WidgetWorker.Parameter;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-/**
- * 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<ModelWidgetAction> 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 Link 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 ModelMenu 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");
-        Element subMenuElement = UtilXml.firstChildElement(menuItemElement, "sub-menu");
-        if (subMenuElement != null) {
-            String subMenuLocation = subMenuElement.getAttribute("location");
-            String subMenuName = subMenuElement.getAttribute("name");
-            try {
-                this.subMenu = MenuFactory.getMenuFromLocation(subMenuLocation, subMenuName);
-            } catch (IOException e) {
-                String errMsg = "Error getting subMenu in menu named [" + this.modelMenu.getName() + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (SAXException e2) {
-                String errMsg = "Error getting subMenu in menu named [" + this.modelMenu.getName() + "]: " + e2.toString();
-                Debug.logError(e2, errMsg, module);
-                throw new RuntimeException(errMsg);
-            } catch (ParserConfigurationException e3) {
-                String errMsg = "Error getting subMenu in menu named [" + this.modelMenu.getName() + "]: " + e3.toString();
-                Debug.logError(e3, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        } else {
-            this.subMenu = null;
-        }
-        Element linkElement = UtilXml.firstChildElement(menuItemElement, "link");
-        if (linkElement != null) {
-            this.link = new Link(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) {
-            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 = ModelWidgetAction.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 = null;
-        this.title = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale));
-        this.titleStyle = "";
-        this.tooltip = FlexibleStringExpander.getInstance("");
-        this.tooltipStyle = "";
-        this.widgetStyle = "";
-        this.link = new Link(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<ModelWidgetAction> 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 Link 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 ModelMenu 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)) {
-            ModelWidgetAction.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.eval(context);
-        }
-        return true;
-    }
-
-    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, MenuStringRenderer menuStringRenderer)
-                throws IOException {
-            menuStringRenderer.renderImage(writer, context, this);
-        }
-    }
-
-    public static class Link {
-        private final AutoEntityParameters autoEntityParameters;
-        private final AutoServiceParameters autoServiceParameters;
-        private final FlexibleStringExpander confirmationMsgExdr;
-        private final boolean encode;
-        private final boolean fullPath;
-        private final FlexibleStringExpander idExdr;
-        private final Image image;
-        private final ModelMenuItem linkMenuItem;
-        private final String linkType;
-        private final FlexibleStringExpander nameExdr;
-        private final List<Parameter> parameterList;
-        private final FlexibleMapAccessor<Map<String, String>> parametersMapAcsr;
-        private final FlexibleStringExpander prefixExdr;
-        private final boolean requestConfirmation;
-        private final boolean secure;
-        private final FlexibleStringExpander styleExdr;
-        private final FlexibleStringExpander targetExdr;
-        private final FlexibleStringExpander targetWindowExdr;
-        private final FlexibleStringExpander textExdr;
-        private final String urlMode;
-
-        public Link(Element linkElement, ModelMenuItem parentMenuItem) {
-            Element autoEntityParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                this.autoEntityParameters = new AutoEntityParameters(autoEntityParamsElement);
-            } else {
-                this.autoEntityParameters = null;
-            }
-            Element autoServiceParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                this.autoServiceParameters = new AutoServiceParameters(autoServiceParamsElement);
-            } else {
-                this.autoServiceParameters = null;
-            }
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("confirmation-message"));
-            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.linkMenuItem = parentMenuItem;
-            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.parametersMapAcsr = FlexibleMapAccessor.getInstance(linkElement.getAttribute("parameters-map"));
-            this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
-            this.requestConfirmation = "true".equals(linkElement.getAttribute("request-confirmation"));
-            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.urlMode = UtilXml.checkEmpty(linkElement.getAttribute("url-mode"), "intra-app");
-        }
-
-        public Link(GenericValue portalPage, ModelMenuItem parentMenuItem, Locale locale) {
-            this.autoEntityParameters = null;
-            this.autoServiceParameters = null;
-            this.confirmationMsgExdr = FlexibleStringExpander.getInstance("");
-            this.encode = false;
-            this.fullPath = false;
-            this.idExdr = FlexibleStringExpander.getInstance("");
-            this.image = null;
-            this.linkMenuItem = parentMenuItem;
-            this.linkType = "";
-            this.nameExdr = FlexibleStringExpander.getInstance("");
-            ArrayList<Parameter> parameterList = new ArrayList<Parameter>();
-            if (parentMenuItem.link != null) {
-                parameterList.addAll(parentMenuItem.link.parameterList);
-            }
-            parameterList.add(new Parameter("portalPageId", portalPage.getString("portalPageId"), false));
-            parameterList.add(new Parameter("parentPortalPageId", portalPage.getString("parentPortalPageId"), false));
-            parameterList.trimToSize();
-            this.parameterList = Collections.unmodifiableList(parameterList);
-            this.parametersMapAcsr = FlexibleMapAccessor.getInstance("");
-            this.prefixExdr = FlexibleStringExpander.getInstance("");
-            this.requestConfirmation = false;
-            this.secure = false;
-            this.styleExdr = FlexibleStringExpander.getInstance("");
-            if (parentMenuItem.link != null) {
-                this.targetExdr = FlexibleStringExpander.getInstance("");
-            } else {
-                this.targetExdr = FlexibleStringExpander.getInstance("showPortalPage");
-            }
-            this.targetWindowExdr = FlexibleStringExpander.getInstance("");
-            this.textExdr = FlexibleStringExpander.getInstance((String) portalPage.get("portalPageName", locale));
-            this.urlMode = "intra-app";
-        }
-
-        public String getConfirmation(Map<String, Object> context) {
-            String message = getConfirmationMsg(context);
-            if (UtilValidate.isNotEmpty(message)) {
-                return message;
-            } else if (getRequestConfirmation()) {
-                FlexibleStringExpander defaultMessage = FlexibleStringExpander.getInstance(UtilProperties.getPropertyValue(
-                        "general", "default.confirmation.message", "${uiLabelMap.CommonConfirm}"));
-                return defaultMessage.expandString(context);
-            }
-            return "";
-        }
-
-        public String getConfirmationMsg(Map<String, Object> context) {
-            return this.confirmationMsgExdr.expandString(context);
-        }
-
-        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 ModelMenuItem getLinkMenuItem() {
-            return linkMenuItem;
-        }
-
-        public String getLinkType() {
-            return this.linkType;
-        }
-
-        public String getName(Map<String, Object> context) {
-            return this.nameExdr.expandString(context);
-        }
-
-        public List<Parameter> getParameterList() {
-            return this.parameterList;
-        }
-
-        public Map<String, String> getParameterMap(Map<String, Object> context) {
-            Map<String, String> fullParameterMap = new HashMap<String, String>();
-            if (this.parametersMapAcsr != null) {
-                Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
-                if (addlParamMap != null) {
-                    fullParameterMap.putAll(addlParamMap);
-                }
-            }
-            for (Parameter parameter : this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-            }
-            if (autoServiceParameters != null) {
-                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, null));
-            }
-            if (autoEntityParameters != null) {
-                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, linkMenuItem.getModelMenu()
-                        .getDefaultEntityName()));
-            }
-            return fullParameterMap;
-        }
-
-        public String getPrefix(Map<String, Object> context) {
-            return this.prefixExdr.expandString(context);
-        }
-
-        public boolean getRequestConfirmation() {
-            return this.requestConfirmation;
-        }
-
-        public boolean getSecure() {
-            return this.secure;
-        }
-
-        public String getStyle(Map<String, Object> context) {
-            String style = this.styleExdr.expandString(context);
-            if (UtilValidate.isEmpty(style)) {
-                style = this.linkMenuItem.getWidgetStyle();
-            }
-            return style;
-        }
-
-        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 txt = this.textExdr.expandString(context);
-            if (UtilValidate.isEmpty(txt)) {
-                txt = linkMenuItem.getTitle(context);
-            }
-            // FIXME: Encoding should be done by the renderer, not by the model.
-            UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-            if (simpleEncoder != null) {
-                txt = simpleEncoder.encode(txt);
-            }
-            return txt;
-        }
-
-        public String getUrlMode() {
-            return this.urlMode;
-        }
-
-        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 69%
rename from framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java
index f4c6c33..8926f98 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelScreenCondition.java
@@ -1,87 +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.ModelWidget;
-import org.ofbiz.widget.ModelWidgetCondition;
-import org.w3c.dom.Element;
-
-/**
- * Models the &lt;condition&gt; element.
- * 
- * @see <code>widget-screen.xsd</code>
- */
-@SuppressWarnings("serial")
-public class ModelScreenCondition extends ModelWidgetCondition {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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 ConditionFactory SCREEN_CONDITION_FACTORY = new ScreenConditionFactory();
-
-    public ModelScreenCondition(ModelScreen modelScreen, Element conditionElement) {
-        super(SCREEN_CONDITION_FACTORY, modelScreen, conditionElement);
-    }
-
-    public static class IfEmptySection extends ModelWidgetCondition implements Condition {
-        private final FlexibleStringExpander sectionExdr;
-
-        private IfEmptySection(ConditionFactory factory, ModelWidget modelWidget, Element condElement) {
-            super (factory, modelWidget, condElement);
-            this.sectionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("section-name"));
-        }
-
-        @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 static class ScreenConditionFactory extends DefaultConditionFactory {
-
-        @Override
-        public Condition 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(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 88%
rename from framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java
index 1aa2559..f5d1949 100644
--- a/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelScreenWidget.java
@@ -1,1825 +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.ModelWidget;
-import org.ofbiz.widget.ModelWidgetAction;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.PortalPageWorker;
-import org.ofbiz.widget.WidgetFactory;
-import org.ofbiz.widget.WidgetWorker;
-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 ModelScreenCondition condition;
-        private final List<ModelWidgetAction> 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) {
-                this.condition = new ModelScreenCondition(modelScreen, conditionElement);
-            } else {
-                this.condition = null;
-            }
-
-            // read all actions under the "actions" element
-            Element actionsElement = UtilXml.firstChildElement(sectionElement, "actions");
-            if (actionsElement != null) {
-                this.actions = ModelWidgetAction.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
-                ModelWidgetAction.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<ModelWidgetAction> getActions() {
-            return actions;
-        }
-
-        public List<ModelScreenWidget> getSubWidgets() {
-            return subWidgets;
-        }
-
-        public List<ModelScreenWidget> getFailWidgets() {
-            return failWidgets;
-        }
-
-        public boolean isMainSection() {
-            return isMainSection;
-        }
-    }
-
-    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 static final class Column {
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander styleExdr;
-        private final List<ModelScreenWidget> subWidgets;
-
-        public Column(ModelScreen modelScreen, Element 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);
-        }
-    }
-
-    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 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 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 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 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 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 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 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 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 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 static final class Link extends ModelScreenWidget {
-        public static final String TAG_NAME = "link";
-        private final FlexibleStringExpander textExdr;
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander styleExdr;
-        private final FlexibleStringExpander targetExdr;
-        private final FlexibleStringExpander targetWindowExdr;
-        private final FlexibleStringExpander prefixExdr;
-        private final FlexibleStringExpander nameExdr;
-        private final Image image;
-        private final String urlMode;
-        private final boolean fullPath;
-        private final boolean secure;
-        private final boolean encode;
-        private final String linkType;
-        private final String width;
-        private final String height;
-        private final List<WidgetWorker.Parameter> parameterList;
-        private final WidgetWorker.AutoServiceParameters autoServiceParameters;
-        private final WidgetWorker.AutoEntityParameters autoEntityParameters;
-
-        public Link(ModelScreen modelScreen, Element linkElement) {
-            super(modelScreen, linkElement);
-            this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
-            this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id"));
-            this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style"));
-            this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name"));
-            this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target"));
-            this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window"));
-            this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
-            this.urlMode = linkElement.getAttribute("url-mode");
-            this.fullPath = "true".equals(linkElement.getAttribute("full-path"));
-            this.secure = "true".equals(linkElement.getAttribute("secure"));
-            this.encode = "true".equals(linkElement.getAttribute("encode"));
-            Element imageElement = UtilXml.firstChildElement(linkElement, "image");
-            if (imageElement != null) {
-                this.image = new Image(modelScreen, imageElement);
-            } else {
-                this.image = null;
-            }
-            this.linkType = linkElement.getAttribute("link-type");
-            List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
-            if (parameterElementList.isEmpty()) {
-                this.parameterList = Collections.emptyList();
-            } else {
-                List<WidgetWorker.Parameter> parameterList = new ArrayList<WidgetWorker.Parameter>(parameterElementList.size());
-                for (Element parameterElement : parameterElementList) {
-                    parameterList.add(new WidgetWorker.Parameter(parameterElement));
-                }
-                this.parameterList = Collections.unmodifiableList(parameterList);
-            }
-            Element autoServiceParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-service");
-            if (autoServiceParamsElement != null) {
-                this.autoServiceParameters = new WidgetWorker.AutoServiceParameters(autoServiceParamsElement);
-            } else {
-                this.autoServiceParameters = null;
-            }
-            Element autoEntityParamsElement = UtilXml.firstChildElement(linkElement, "auto-parameters-entity");
-            if (autoEntityParamsElement != null) {
-                this.autoEntityParameters = new WidgetWorker.AutoEntityParameters(autoEntityParamsElement);
-            } else {
-                this.autoEntityParameters = null;
-            }
-            this.width = linkElement.getAttribute("width");
-            this.height = linkElement.getAttribute("height");
-        }
-
-        @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 [" + getId(context) + "]: " + 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);
-        }
-
-        public String getTarget(Map<String, Object> context) {
-            Map<String, Object> expanderContext = context;
-            UtilCodec.SimpleEncoder simpleEncoder = context == null ? null : (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-            if (simpleEncoder != null) {
-                expanderContext = UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context, simpleEncoder);
-            }
-            return this.targetExdr.expandString(expanderContext);
-        }
-
-        public String getName(Map<String, Object> context) {
-            return this.nameExdr.expandString(context);
-        }
-
-        public String getTargetWindow(Map<String, Object> context) {
-            return this.targetWindowExdr.expandString(context);
-        }
-
-        public String getUrlMode() {
-            return this.urlMode;
-        }
-
-        public String getPrefix(Map<String, Object> context) {
-            return this.prefixExdr.expandString(context);
-        }
-
-        public boolean getFullPath() {
-            return this.fullPath;
-        }
-
-        public boolean getSecure() {
-            return this.secure;
-        }
-
-        public boolean getEncode() {
-            return this.encode;
-        }
-
-        public Image getImage() {
-            return this.image;
-        }
-
-        public String getLinkType() {
-            return this.linkType;
-        }
-
-        public String getWidth() {
-            return this.width;
-        }
-
-        public String getHeight() {
-            return this.height;
-        }
-
-        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 (WidgetWorker.Parameter parameter: this.parameterList) {
-                fullParameterMap.put(parameter.getName(), parameter.getValue(context));
-            }
-
-            if (autoServiceParameters != null) {
-                fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, null));
-            }
-            if (autoEntityParameters != null) {
-                fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, null));
-            }
-
-            return fullParameterMap;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-    }
-
-    public static final class Image extends ModelScreenWidget {
-        public static final String TAG_NAME = "image";
-        private final FlexibleStringExpander srcExdr;
-        private final FlexibleStringExpander idExdr;
-        private final FlexibleStringExpander styleExdr;
-        private final FlexibleStringExpander widthExdr;
-        private final FlexibleStringExpander heightExdr;
-        private final FlexibleStringExpander borderExdr;
-        private final FlexibleStringExpander alt;
-        private final String urlMode;
-
-        public Image(ModelScreen modelScreen, Element imageElement) {
-            super(modelScreen, imageElement);
-            this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("src"));
-            this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id"));
-            this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style"));
-            this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
-            this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
-            this.borderExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("border"));
-            this.alt = FlexibleStringExpander.getInstance(imageElement.getAttribute("alt"));
-            String urlMode = imageElement.getAttribute("url-mode");
-            if (urlMode.isEmpty()) {
-                urlMode = "content";
-            }
-            this.urlMode = urlMode;
-        }
-
-        @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 [" + getId(context) + "]: " + e.toString();
-                Debug.logError(e, errMsg, module);
-                throw new RuntimeException(errMsg);
-            }
-        }
-
-        public String getSrc(Map<String, Object> context) {
-            return this.srcExdr.expandString(context);
-        }
-
-        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 getWidth(Map<String, Object> context) {
-            return this.widthExdr.expandString(context);
-        }
-
-        public String getHeight(Map<String, Object> context) {
-            return this.heightExdr.expandString(context);
-        }
-
-        public String getBorder(Map<String, Object> context) {
-            return this.borderExdr.expandString(context);
-        }
-
-        public String getAlt(Map<String, Object> context) {
-            String alt = this.alt.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) {
-                alt = simpleEncoder.encode(alt);
-            }
-            return alt;
-        }
-
-        public String getUrlMode() {
-            return this.urlMode;
-        }
-
-        @Override
-        public void accept(ModelWidgetVisitor visitor) throws Exception {
-            visitor.visit(this);
-        }
-    }
-
-    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);
-        }
-    }
-
-}
+/*******************************************************************************
+ * 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 91%
rename from framework/widget/src/org/ofbiz/widget/tree/ModelTree.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelTree.java
index b95a5fd..9a2bf60 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTree.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelTree.java
@@ -1,1017 +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.ModelWidgetAction;
-import org.ofbiz.widget.ModelWidgetVisitor;
-import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.WidgetWorker.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);
-        }
-    }
-
-    /**
-     * Models the &lt;node&gt; element.
-     * 
-     * @see <code>widget-tree.xsd</code>
-     */
-    public static class ModelNode extends ModelWidget {
-
-        private final List<ModelWidgetAction> actions;
-        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<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>();
-            // 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 ModelWidgetAction.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<ModelWidgetAction> subNodeActions = subNode.getActions();
-                //if (Debug.infoOn()) Debug.logInfo(" context.currentValue:" + context.get("currentValue"), module);
-                ModelWidgetAction.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.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;
-        }
-
-        /**
-         * 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);
-                }
-            }
-        }
-
-        /**
-         * 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 (WidgetWorker.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);
-                }
-            }
-        }
-
-        /**
-         * Models the &lt;sub-node&gt; element.
-         * 
-         * @see <code>widget-tree.xsd</code>
-         */
-        public static class ModelSubNode extends ModelWidget {
-
-            private final List<ModelWidgetAction> 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<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>();
-                // 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<ModelWidgetAction> 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 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 94%
rename from framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelTreeAction.java
index 23a9b98..f9734c8 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeAction.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelTreeAction.java
@@ -1,462 +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.ModelActionVisitor;
-import org.ofbiz.widget.ModelWidgetAction;
-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 ModelWidgetAction {
-
-    /*
-     * ----------------------------------------------------------------------- *
-     *                     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<ModelWidgetAction> readNodeActions(ModelNode modelNode, Element actionsElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(actionsElement);
-        List<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>(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(ModelWidgetAction.newInstance(modelNode, actionElement));
-            }
-        }
-        return actions;
-    }
-
-    public static List<ModelWidgetAction> readSubNodeActions(ModelNode.ModelSubNode modelSubNode, Element actionsElement) {
-        List<? extends Element> actionElementList = UtilXml.childElementList(actionsElement);
-        List<ModelWidgetAction> actions = new ArrayList<ModelWidgetAction>(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(ModelWidgetAction.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) {
-            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) {
-            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) {
-            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) {
-            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 80%
rename from framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelTreeCondition.java
index bf2db5b..a225bfc 100644
--- a/framework/widget/src/org/ofbiz/widget/tree/ModelTreeCondition.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelTreeCondition.java
@@ -1,36 +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.ModelWidgetCondition;
-import org.w3c.dom.Element;
-
-/**
- * Models the &lt;condition&gt; element.
- * 
- * @see <code>widget-tree.xsd</code>
- */
-@SuppressWarnings("serial")
-public class ModelTreeCondition extends ModelWidgetCondition {
-    public static final String module = ModelTreeCondition.class.getName();
-
-    public ModelTreeCondition(ModelTree modelTree, Element conditionElement) {
-        super(ModelWidgetCondition.DEFAULT_CONDITION_FACTORY, modelTree, 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 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 91%
rename from framework/widget/src/org/ofbiz/widget/ModelWidget.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelWidget.java
index 1e7aa50..8aec83e 100644
--- a/framework/widget/src/org/ofbiz/widget/ModelWidget.java
+++ b/framework/widget/src/org/ofbiz/widget/model/ModelWidget.java
@@ -1,144 +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.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 {
-
-    /**
-     * 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() {
-        return getClass().getSimpleName() + "[" + getSystemId() + "#" + getName() + "@" + getStartColumn() + "," + getStartLine() + "]";
-    }
-
-    /**
-     * 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 85%
rename from framework/widget/src/org/ofbiz/widget/ModelWidgetVisitor.java
rename to framework/widget/src/org/ofbiz/widget/model/ModelWidgetVisitor.java
index 6ae33ff..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.
@@ -66,13 +59,13 @@
 
     void visit(ModelScreenWidget.HorizontalSeparator horizontalSeparator) throws Exception;
 
-    void visit(ModelScreenWidget.Image image) throws Exception;
+    void visit(ModelScreenWidget.ScreenImage image) throws Exception;
 
     void visit(ModelScreenWidget.IncludeScreen includeScreen) throws Exception;
 
     void visit(ModelScreenWidget.Label label) throws Exception;
 
-    void visit(ModelScreenWidget.Link link) throws Exception;
+    void visit(ModelScreenWidget.ScreenLink link) throws Exception;
 
     void visit(ModelScreenWidget.Menu menu) throws Exception;
 
@@ -91,4 +84,6 @@
     void visit(ModelTree.ModelNode modelNode) throws Exception;
 
     void visit(ModelTree.ModelNode.ModelSubNode modelSubNode) throws Exception;
+
+    void visit(ModelScreenWidget.Column column) throws Exception;
 }
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/model/XmlAbstractWidgetVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java
new file mode 100644
index 0000000..86d6e5d
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlAbstractWidgetVisitor.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * 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.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.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 XmlAbstractWidgetVisitor {
+
+    protected final Appendable writer;
+
+    public XmlAbstractWidgetVisitor(Appendable writer) {
+        Assert.notNull("writer", writer);
+        this.writer = writer;
+    }
+
+    protected void visitAttribute(String attributeName, Boolean attributeValue) throws Exception {
+        if (attributeValue != null) {
+            writer.append(" ").append(attributeName).append("=\"");
+            writer.append(attributeValue.toString());
+            writer.append("\"");
+        }
+    }
+
+    protected void visitAttribute(String attributeName, FlexibleMapAccessor<?> attributeValue) throws Exception {
+        if (attributeValue != null && !attributeValue.isEmpty()) {
+            writer.append(" ").append(attributeName).append("=\"");
+            writer.append(attributeValue.getOriginalName());
+            writer.append("\"");
+        }
+    }
+
+    protected void visitAttribute(String attributeName, FlexibleStringExpander attributeValue) throws Exception {
+        if (attributeValue != null && !attributeValue.isEmpty()) {
+            writer.append(" ").append(attributeName).append("=\"");
+            writer.append(attributeValue.getOriginal());
+            writer.append("\"");
+        }
+    }
+
+    protected void visitAttribute(String attributeName, Integer attributeValue) throws Exception {
+        if (attributeValue != null) {
+            writer.append(" ").append(attributeName).append("=\"");
+            writer.append(attributeValue.toString());
+            writer.append("\"");
+        }
+    }
+
+    protected void visitAttribute(String attributeName, String attributeValue) throws Exception {
+        if (attributeValue != null && !attributeValue.isEmpty()) {
+            writer.append(" ").append(attributeName).append("=\"");
+            writer.append(attributeValue);
+            writer.append("\"");
+        }
+    }
+
+    protected void visitAutoEntityParameters(AutoEntityParameters autoEntityParameters) throws Exception {
+
+    }
+
+    protected void visitAutoServiceParameters(AutoServiceParameters autoServiceParameters) throws Exception {
+
+    }
+
+    protected void visitImage(Image image) throws Exception {
+        if (image != null) {
+            writer.append("<image");
+            visitAttribute("name", image.getName());
+            visitAttribute("alt", image.getAlt());
+            visitAttribute("border", image.getBorderExdr());
+            visitAttribute("height", image.getHeightExdr());
+            visitAttribute("id", image.getIdExdr());
+            visitAttribute("src", image.getSrcExdr());
+            visitAttribute("style", image.getStyleExdr());
+            visitAttribute("title", image.getTitleExdr());
+            visitAttribute("url-mode", image.getUrlMode());
+            visitAttribute("width", image.getWidthExdr());
+            writer.append("/>");
+        }
+    }
+
+    protected void visitLink(Link link) throws Exception {
+        if (link != null) {
+            writer.append("<link");
+            visitLinkAttributes(link);
+            if (link.getImage() != null || link.getAutoEntityParameters() != null || link.getAutoServiceParameters() != null) {
+                writer.append(">");
+                visitImage(link.getImage());
+                visitAutoEntityParameters(link.getAutoEntityParameters());
+                visitAutoServiceParameters(link.getAutoServiceParameters());
+                writer.append("</link>");
+            } else {
+                writer.append("/>");
+            }
+        }
+    }
+
+    protected void visitLinkAttributes(Link link) throws Exception {
+        if (link != null) {
+            visitAttribute("name", link.getName());
+            visitAttribute("encode", link.getEncode());
+            visitAttribute("full-path", link.getFullPath());
+            visitAttribute("id", link.getIdExdr());
+            visitAttribute("height", link.getHeight());
+            visitAttribute("link-type", link.getLinkType());
+            visitAttribute("prefix", link.getPrefixExdr());
+            visitAttribute("secure", link.getSecure());
+            visitAttribute("style", link.getStyleExdr());
+            visitAttribute("target", link.getTargetExdr());
+            visitAttribute("target-window", link.getTargetWindowExdr());
+            visitAttribute("text", link.getTextExdr());
+            visitAttribute("size", link.getSize());
+            visitAttribute("url-mode", link.getUrlMode());
+            visitAttribute("width", link.getWidth());
+        }
+    }
+
+    protected void visitModelWidget(ModelWidget widget) throws Exception {
+        if (widget.getName() != null && !widget.getName().isEmpty()) {
+            writer.append(" name=\"");
+            writer.append(widget.getName());
+            writer.append("\"");
+        }
+    }
+
+    protected void visitParameters(Collection<Parameter> parameters) throws Exception {
+        if (parameters != null) {
+            for (Parameter parameter : parameters) {
+                writer.append("<parameter");
+                visitAttribute("param-name", parameter.getName());
+                visitAttribute("from-field", parameter.getFromField());
+                visitAttribute("value", parameter.getValue());
+                writer.append("/>");
+            }
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java
new file mode 100644
index 0000000..540127e
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetActionVisitor.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * 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.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.
+ * The generated XML is unformatted - if you want to
+ * "pretty print" the XML, then use a transformer.
+ *
+ */
+public class XmlWidgetActionVisitor extends XmlAbstractWidgetVisitor implements ModelActionVisitor {
+
+    public static final String module = XmlWidgetActionVisitor.class.getName();
+
+    public XmlWidgetActionVisitor(Appendable writer) {
+        super(writer);
+    }
+
+    @Override
+    public void visit(CallParentActions callParentActions) throws Exception {
+        writer.append("<call-parent-actions/>");
+    }
+
+    @Override
+    public void visit(EntityAnd entityAnd) throws Exception {
+        writer.append("<entity-and/>");
+        // TODO: Create ByAndFinder visitor
+    }
+
+    @Override
+    public void visit(org.ofbiz.widget.model.ModelTreeAction.EntityAnd entityAnd) throws Exception {
+        writer.append("<entity-and/>");
+        // TODO: Create ByAndFinder visitor
+    }
+
+    @Override
+    public void visit(EntityCondition entityCondition) throws Exception {
+        writer.append("<entity-condition/>");
+        // TODO: Create ByConditionFinder visitor
+    }
+
+    @Override
+    public void visit(org.ofbiz.widget.model.ModelTreeAction.EntityCondition entityCondition) throws Exception {
+        writer.append("<entity-condition/>");
+        // TODO: Create ByConditionFinder visitor
+    }
+
+    @Override
+    public void visit(EntityOne entityOne) throws Exception {
+        writer.append("<entity-one/>");
+        // TODO: Create PrimaryKeyFinder visitor
+    }
+
+    @Override
+    public void visit(GetRelated getRelated) throws Exception {
+        writer.append("<get-related");
+        visitAttribute("value-field", getRelated.getValueNameAcsr());
+        visitAttribute("list", getRelated.getListNameAcsr());
+        visitAttribute("relation-name", getRelated.getRelationName());
+        visitAttribute("map", getRelated.getMapAcsr());
+        visitAttribute("order-by-list", getRelated.getOrderByListAcsr());
+        visitAttribute("use-cache", getRelated.getUseCache());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(GetRelatedOne getRelatedOne) throws Exception {
+        writer.append("<get-related-one");
+        visitAttribute("value-field", getRelatedOne.getValueNameAcsr());
+        visitAttribute("to-value-field", getRelatedOne.getToValueNameAcsr());
+        visitAttribute("relation-name", getRelatedOne.getRelationName());
+        visitAttribute("use-cache", getRelatedOne.getUseCache());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(PropertyMap propertyMap) throws Exception {
+        writer.append("<property-map");
+        visitAttribute("resource", propertyMap.getResourceExdr());
+        visitAttribute("map-name", propertyMap.getMapNameAcsr());
+        visitAttribute("global", propertyMap.getGlobalExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(PropertyToField propertyToField) throws Exception {
+        writer.append("<property-map");
+        visitAttribute("resource", propertyToField.getResourceExdr());
+        visitAttribute("property", propertyToField.getPropertyExdr());
+        visitAttribute("field", propertyToField.getFieldAcsr());
+        visitAttribute("default", propertyToField.getDefaultExdr());
+        visitAttribute("no-locale", propertyToField.getNoLocale());
+        visitAttribute("arg-list-name", propertyToField.getArgListAcsr());
+        visitAttribute("global", propertyToField.getGlobalExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(Script script) throws Exception {
+        writer.append("<script");
+        visitAttribute("location", script.getLocation());
+        visitAttribute("method", script.getMethod());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(org.ofbiz.widget.model.ModelTreeAction.Script script) throws Exception {
+        writer.append("<script");
+        visitAttribute("location", script.getLocation());
+        visitAttribute("method", script.getMethod());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(Service service) throws Exception {
+        writer.append("<service");
+        visitAttribute("service-name", service.getServiceNameExdr());
+        visitAttribute("result-map", service.getResultMapNameAcsr());
+        visitAttribute("auto-field-map", service.getAutoFieldMapExdr());
+        writer.append(">");
+        // TODO: Create Field Map visitor
+        writer.append("<field-map/>");
+        writer.append("</service>");
+    }
+
+    @Override
+    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());
+        visitAttribute("auto-field-map", service.getAutoFieldMapExdr());
+        visitAttribute("result-map-list", service.getResultMapListNameExdr());
+        visitAttribute("ignore-error", service.getIgnoreError());
+        writer.append(">");
+        // TODO: Create Field Map visitor
+        writer.append("<field-map/>");
+        writer.append("</service>");
+    }
+
+    @Override
+    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());
+        visitAttribute("auto-field-map", service.getAutoFieldMapExdr());
+        visitAttribute("result-map-list", service.getResultMapListNameExdr());
+        visitAttribute("result-map-value", service.getResultMapValueNameExdr());
+        visitAttribute("value", service.getValueNameExdr());
+        writer.append(">");
+        // TODO: Create Field Map visitor
+        writer.append("<field-map/>");
+        writer.append("</service>");
+    }
+
+    @Override
+    public void visit(SetField setField) throws Exception {
+        writer.append("<set");
+        visitAttribute("field", setField.getField());
+        visitAttribute("from-field", setField.getFromField());
+        visitAttribute("value", setField.getValueExdr());
+        visitAttribute("default-value", setField.getDefaultExdr());
+        visitAttribute("global", setField.getGlobalExdr());
+        visitAttribute("type", setField.getType());
+        visitAttribute("to-scope", setField.getToScope());
+        visitAttribute("from-scope", setField.getFromScope());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(org.ofbiz.widget.model.ModelMenuAction.SetField setField) throws Exception {
+        writer.append("<set");
+        visitAttribute("field", setField.getField());
+        visitAttribute("from-field", setField.getFromField());
+        visitAttribute("value", setField.getValueExdr());
+        visitAttribute("default-value", setField.getDefaultExdr());
+        visitAttribute("global", setField.getGlobalExdr());
+        visitAttribute("type", setField.getType());
+        visitAttribute("to-scope", setField.getToScope());
+        visitAttribute("from-scope", setField.getFromScope());
+        writer.append("/>");
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java
new file mode 100644
index 0000000..9bd4b89
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetConditionVisitor.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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.Collection;
+
+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.
+ * The generated XML is unformatted - if you want to
+ * "pretty print" the XML, then use a transformer.
+ *
+ */
+public class XmlWidgetConditionVisitor extends XmlAbstractWidgetVisitor implements ModelConditionVisitor {
+
+    public XmlWidgetConditionVisitor(Appendable writer) {
+        super(writer);
+    }
+
+    @Override
+    public void visit(And and) throws Exception {
+        writer.append("<and>");
+        visitSubConditions(and.getSubConditions());
+        writer.append("</and>");
+    }
+
+    @Override
+    public void visit(IfCompare ifCompare) throws Exception {
+        writer.append("<if-compare");
+        visitAttribute("field", ifCompare.getFieldAcsr());
+        visitAttribute("operator", ifCompare.getOperator());
+        visitAttribute("value", ifCompare.getValueExdr());
+        visitAttribute("type", ifCompare.getType());
+        visitAttribute("format", ifCompare.getFormatExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IfCompareField ifCompareField) throws Exception {
+        writer.append("<if-compare-field");
+        visitAttribute("field", ifCompareField.getFieldAcsr());
+        visitAttribute("operator", ifCompareField.getOperator());
+        visitAttribute("to-field", ifCompareField.getToFieldAcsr());
+        visitAttribute("type", ifCompareField.getType());
+        visitAttribute("format", ifCompareField.getFormatExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IfEmpty ifEmpty) throws Exception {
+        writer.append("<if-empty");
+        visitAttribute("field", ifEmpty.getFieldAcsr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IfEmptySection ifEmptySection) throws Exception {
+        writer.append("<if-empty-section");
+        visitAttribute("section-name", ifEmptySection.getSectionExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IfEntityPermission ifEntityPermission) throws Exception {
+        writer.append("<if-entity-permission");
+        // TODO: Create EntityPermissionChecker visitor
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IfHasPermission ifHasPermission) throws Exception {
+        writer.append("<if-has-permission");
+        visitAttribute("permission", ifHasPermission.getPermissionExdr());
+        visitAttribute("action", ifHasPermission.getActionExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IfRegexp ifRegexp) throws Exception {
+        writer.append("<if-regexp");
+        visitAttribute("field", ifRegexp.getFieldAcsr());
+        visitAttribute("expr", ifRegexp.getExprExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IfServicePermission ifServicePermission) throws Exception {
+        writer.append("<if-service-permission");
+        visitAttribute("service-name", ifServicePermission.getServiceExdr());
+        visitAttribute("main-action", ifServicePermission.getActionExdr());
+        visitAttribute("context-map", ifServicePermission.getCtxMapExdr());
+        visitAttribute("resource-description", ifServicePermission.getResExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IfValidateMethod ifValidateMethod) throws Exception {
+        writer.append("<if-validate-method");
+        visitAttribute("field", ifValidateMethod.getFieldAcsr());
+        visitAttribute("method", ifValidateMethod.getMethodExdr());
+        visitAttribute("class", ifValidateMethod.getClassExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(ModelMenuCondition modelMenuCondition) throws Exception {
+        writer.append("<condition");
+        visitAttribute("pass-style", modelMenuCondition.getPassStyleExdr());
+        visitAttribute("disabled-style", modelMenuCondition.getFailStyleExdr());
+        writer.append("/>");
+        modelMenuCondition.getCondition().accept(this);
+        ;
+        writer.append("</condition>");
+    }
+
+    @Override
+    public void visit(ModelTreeCondition modelTreeCondition) throws Exception {
+        writer.append("<condition>");
+        modelTreeCondition.getCondition().accept(this);
+        writer.append("</condition>");
+    }
+
+    @Override
+    public void visit(Not not) throws Exception {
+        writer.append("<not>");
+        not.getSubCondition().accept(this);
+        writer.append("</not>");
+    }
+
+    @Override
+    public void visit(Or or) throws Exception {
+        writer.append("<or>");
+        visitSubConditions(or.getSubConditions());
+        writer.append("</or>");
+    }
+
+    @Override
+    public void visit(Xor xor) throws Exception {
+        writer.append("<xor>");
+        visitSubConditions(xor.getSubConditions());
+        writer.append("</xor>");
+    }
+
+    private void visitSubConditions(Collection<ModelCondition> subConditions) throws Exception {
+        for (ModelCondition subCondition : subConditions) {
+            subCondition.accept(this);
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
new file mode 100644
index 0000000..c56368c
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetFieldVisitor.java
@@ -0,0 +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.model;
+
+import java.util.Collection;
+
+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.
+ * The generated XML is unformatted - if you want to
+ * "pretty print" the XML, then use a transformer.
+ *
+ */
+public class XmlWidgetFieldVisitor extends XmlAbstractWidgetVisitor implements ModelFieldVisitor {
+
+    public XmlWidgetFieldVisitor(Appendable writer) {
+        super(writer);
+    }
+
+    @Override
+    public void visit(CheckField checkField) throws Exception {
+        visitModelField(checkField.getModelFormField());
+        writer.append("<check");
+        visitAttribute("all-checked", checkField.getAllChecked());
+        visitFieldInfoWithOptions(checkField);
+        writer.append("</check></field>");
+    }
+
+    @Override
+    public void visit(ContainerField containerField) throws Exception {
+        visitModelField(containerField.getModelFormField());
+        writer.append("<container/></field>");
+    }
+
+    @Override
+    public void visit(DateFindField dateTimeField) throws Exception {
+        visitModelField(dateTimeField.getModelFormField());
+        writer.append("<date-find");
+        visitDateTimeFieldAttrs(dateTimeField);
+        visitAttribute("default-option-from", dateTimeField.getDefaultOptionFrom());
+        visitAttribute("default-option-thru", dateTimeField.getDefaultOptionThru());
+        writer.append("/></field>");
+    }
+
+    @Override
+    public void visit(DateTimeField dateTimeField) throws Exception {
+        visitModelField(dateTimeField.getModelFormField());
+        writer.append("<date-time");
+        visitDateTimeFieldAttrs(dateTimeField);
+        writer.append("/></field>");
+    }
+
+    @Override
+    public void visit(DisplayEntityField displayField) throws Exception {
+        visitModelField(displayField.getModelFormField());
+        writer.append("<display-entity");
+        visitDisplayFieldAttrs(displayField);
+        visitAttribute("cache", displayField.getCache());
+        visitAttribute("entity-name", displayField.getEntityName());
+        visitAttribute("key-field-name", displayField.getKeyFieldName());
+        writer.append(">");
+        visitInPlaceEditor(displayField.getInPlaceEditor());
+        visitSubHyperlink(displayField.getSubHyperlink());
+        writer.append("</display-entity></field>");
+    }
+
+    @Override
+    public void visit(DisplayField displayField) throws Exception {
+        visitModelField(displayField.getModelFormField());
+        writer.append("<display");
+        visitDisplayFieldAttrs(displayField);
+        writer.append(">");
+        visitInPlaceEditor(displayField.getInPlaceEditor());
+        writer.append("</display></field>");
+    }
+
+    @Override
+    public void visit(DropDownField dropDownField) throws Exception {
+        visitModelField(dropDownField.getModelFormField());
+        writer.append("<drop-down");
+        visitAttribute("allow-empty", dropDownField.getAllowEmpty());
+        visitAttribute("allow-multiple", dropDownField.getAllowMultiple());
+        visitAttribute("current", dropDownField.getCurrent());
+        visitAttribute("current-description", dropDownField.getCurrentDescription());
+        visitAttribute("other-field-size", dropDownField.getOtherFieldSize());
+        visitAttribute("size", dropDownField.getSize());
+        visitAttribute("text-size", dropDownField.getTextSize());
+        visitFieldInfoWithOptions(dropDownField);
+        visitAutoComplete(dropDownField.getAutoComplete());
+        visitSubHyperlink(dropDownField.getSubHyperlink());
+        writer.append("</drop-down></field>");
+    }
+
+    @Override
+    public void visit(FileField textField) throws Exception {
+        visitModelField(textField.getModelFormField());
+        writer.append("<file");
+        visitTextFieldAttrs(textField);
+        writer.append(">");
+        visitSubHyperlink(textField.getSubHyperlink());
+        writer.append("</file></field>");
+    }
+
+    @Override
+    public void visit(HiddenField hiddenField) throws Exception {
+        visitModelField(hiddenField.getModelFormField());
+        writer.append("<hidden");
+        visitAttribute("value", hiddenField.getValue());
+        writer.append("/></field>");
+    }
+
+    @Override
+    public void visit(HyperlinkField hyperlinkField) throws Exception {
+        visitModelField(hyperlinkField.getModelFormField());
+        writer.append("<hyperlink");
+        visitAttribute("also-hidden", hyperlinkField.getAlsoHidden());
+        visitAttribute("confirmation-message", hyperlinkField.getConfirmationMsgExdr());
+        visitAttribute("description", hyperlinkField.getDescription());
+        visitAttribute("request-confirmation", hyperlinkField.getRequestConfirmation());
+        Link link = hyperlinkField.getLink();
+        visitLinkAttributes(link);
+        if (link.getImage() != null || link.getAutoEntityParameters() != null || link.getAutoServiceParameters() != null) {
+            writer.append(">");
+            visitImage(link.getImage());
+            visitAutoEntityParameters(link.getAutoEntityParameters());
+            visitAutoServiceParameters(link.getAutoServiceParameters());
+            writer.append("</hyperlink>");
+        } else {
+            writer.append("/>");
+        }
+        writer.append("</field>");
+    }
+
+    @Override
+    public void visit(IgnoredField ignoredField) throws Exception {
+        visitModelField(ignoredField.getModelFormField());
+        writer.append("<ignored/></field>");
+    }
+
+    @Override
+    public void visit(ImageField imageField) throws Exception {
+        visitModelField(imageField.getModelFormField());
+        writer.append("<image");
+        visitAttribute("alternate", imageField.getAlternate());
+        visitAttribute("default-value", imageField.getDefaultValue());
+        visitAttribute("description", imageField.getDescription());
+        visitAttribute("style", imageField.getStyle());
+        visitAttribute("value", imageField.getValue());
+        writer.append(">");
+        visitSubHyperlink(imageField.getSubHyperlink());
+        writer.append("</image></field>");
+    }
+
+    @Override
+    public void visit(LookupField textField) throws Exception {
+        visitModelField(textField.getModelFormField());
+        writer.append("<lookup");
+        visitTextFieldAttrs(textField);
+        visitAttribute("description-field-name", textField.getDescriptionFieldName());
+        visitAttribute("fade-background", textField.getFadeBackground());
+        visitAttribute("target-form-name", textField.getFormName());
+        visitAttribute("initially-collapsed", textField.getInitiallyCollapsed());
+        visitAttribute("height", textField.getLookupHeight());
+        visitAttribute("position", textField.getLookupPosition());
+        visitAttribute("presentation", textField.getLookupPresentation());
+        visitAttribute("width", textField.getLookupWidth());
+        visitAttribute("show-description", textField.getShowDescription());
+        visitAttribute("target-parameter", textField.getTargetParameter());
+        writer.append(">");
+        visitSubHyperlink(textField.getSubHyperlink());
+        writer.append("</lookup></field>");
+    }
+
+    @Override
+    public void visit(PasswordField textField) throws Exception {
+        visitModelField(textField.getModelFormField());
+        writer.append("<password");
+        visitTextFieldAttrs(textField);
+        writer.append(">");
+        visitSubHyperlink(textField.getSubHyperlink());
+        writer.append("</password></field>");
+    }
+
+    @Override
+    public void visit(RadioField radioField) throws Exception {
+        visitModelField(radioField.getModelFormField());
+        writer.append("<radio");
+        visitFieldInfoWithOptions(radioField);
+        writer.append("</radio></field>");
+    }
+
+    @Override
+    public void visit(RangeFindField textField) throws Exception {
+        visitModelField(textField.getModelFormField());
+        writer.append("<range-find");
+        visitTextFieldAttrs(textField);
+        visitAttribute("default-option-from", textField.getDefaultOptionFrom());
+        visitAttribute("default-option-thru", textField.getDefaultOptionThru());
+        writer.append(">");
+        visitSubHyperlink(textField.getSubHyperlink());
+        writer.append("</range-find></field>");
+    }
+
+    @Override
+    public void visit(ResetField resetField) throws Exception {
+        visitModelField(resetField.getModelFormField());
+        writer.append("<reset/></field>");
+    }
+
+    @Override
+    public void visit(SubmitField submitField) throws Exception {
+        visitModelField(submitField.getModelFormField());
+        writer.append("<submit");
+        visitAttribute("background-submit-refresh-target", submitField.getBackgroundSubmitRefreshTargetExdr());
+        visitAttribute("button-type", submitField.getButtonType());
+        visitAttribute("confirmation-message", submitField.getConfirmationMsgExdr());
+        visitAttribute("image-location", submitField.getImageLocation());
+        visitAttribute("request-confirmation", submitField.getRequestConfirmation());
+        writer.append("/></field>");
+    }
+
+    @Override
+    public void visit(TextareaField textareaField) throws Exception {
+        visitModelField(textareaField.getModelFormField());
+        writer.append("<textarea");
+        visitAttribute("cols", textareaField.getCols());
+        visitAttribute("default-value", textareaField.getDefaultValue());
+        visitAttribute("read-only", textareaField.isReadOnly());
+        visitAttribute("rows", textareaField.getRows());
+        visitAttribute("visual-editor-buttons", textareaField.getVisualEditorButtons());
+        visitAttribute("visual-editor-enable", textareaField.getVisualEditorEnable());
+        writer.append("/></field>");
+    }
+
+    @Override
+    public void visit(TextField textField) throws Exception {
+        visitModelField(textField.getModelFormField());
+        writer.append("<text");
+        visitTextFieldAttrs(textField);
+        writer.append(">");
+        visitSubHyperlink(textField.getSubHyperlink());
+        writer.append("</text></field>");
+    }
+
+    @Override
+    public void visit(TextFindField textField) throws Exception {
+        visitModelField(textField.getModelFormField());
+        writer.append("<text-find");
+        visitTextFieldAttrs(textField);
+        visitAttribute("default-option", textField.getDefaultOption());
+        visitAttribute("hide-options", textField.getHideOptions());
+        visitAttribute("ignore-case", textField.getIgnoreCase());
+        writer.append(">");
+        visitSubHyperlink(textField.getSubHyperlink());
+        writer.append("</text-find></field>");
+    }
+
+    private void visitTextFieldAttrs(TextField field) throws Exception {
+        visitAttribute("client-autocomplete-field", field.getClientAutocompleteField());
+        visitAttribute("default-value", field.getDefaultValue());
+        visitAttribute("disabled", field.getDisabled());
+        visitAttribute("mask", field.getMask());
+        visitAttribute("maxlength", field.getMaxlength());
+        visitAttribute("placeholder", field.getPlaceholder());
+        visitAttribute("read-only", field.getReadonly());
+        visitAttribute("size", field.getSize());
+    }
+
+    private void visitDisplayFieldAttrs(DisplayField field) throws Exception {
+        visitAttribute("also-hidden", field.getAlsoHidden());
+        visitAttribute("currency", field.getCurrency());
+        visitAttribute("date", field.getDate());
+        visitAttribute("default-value", field.getDefaultValue());
+        visitAttribute("description", field.getDescription());
+        visitAttribute("image-location", field.getImageLocation());
+        visitAttribute("size", field.getSize());
+        visitAttribute("type", field.getType());
+    }
+
+    private void visitDateTimeFieldAttrs(DateTimeField field) throws Exception {
+        visitAttribute("default-value", field.getDefaultValue());
+        visitAttribute("type", field.getType());
+        visitAttribute("input-method", field.getInputMethod());
+        visitAttribute("clock", field.getClock());
+        visitAttribute("mask", field.getMask());
+        visitAttribute("step", field.getStep());
+    }
+
+    private void visitFieldInfoWithOptions(FieldInfoWithOptions fieldInfo) throws Exception {
+        visitAttribute("no-current-selected-key", fieldInfo.getNoCurrentSelectedKey());
+        writer.append(">");
+        // TODO: Options
+    }
+
+    private void visitModelField(ModelFormField modelField) throws Exception {
+        writer.append("<field");
+        visitAttribute("name", modelField.getName());
+        visitAttribute("action", modelField.getAction());
+        visitAttribute("attribute-name", modelField.getAttributeName());
+        visitAttribute("encode-output", modelField.getEncodeOutput());
+        visitAttribute("entity-name", modelField.getEntityName());
+        visitAttribute("entry-name", modelField.getEntryName());
+        visitAttribute("event", modelField.getEvent());
+        visitAttribute("field-name", modelField.getFieldName());
+        visitAttribute("header-link", modelField.getHeaderLink());
+        visitAttribute("header-link-style", modelField.getHeaderLinkStyle());
+        visitAttribute("id-name", modelField.getIdName());
+        visitAttribute("map-name", modelField.getMapName());
+        visitAttribute("parameter-name", modelField.getParameterName());
+        visitAttribute("position", modelField.getPosition());
+        visitAttribute("red-when", modelField.getRedWhen());
+        visitAttribute("required-field", modelField.getRequiredField());
+        visitAttribute("required-field-style", modelField.getRequiredFieldStyle());
+        visitAttribute("separate-column", modelField.getSeparateColumn());
+        visitAttribute("service-name", modelField.getServiceName());
+        visitAttribute("sort-field", modelField.getSortField());
+        visitAttribute("sort-field-asc-style", modelField.getSortFieldAscStyle());
+        visitAttribute("sort-field-desc-style", modelField.getSortFieldDescStyle());
+        visitAttribute("sort-field-help-text", modelField.getSortFieldHelpText());
+        visitAttribute("sort-field-style", modelField.getSortFieldStyle());
+        visitAttribute("title", modelField.getTitle());
+        visitAttribute("title-area-style", modelField.getTitleAreaStyle());
+        visitAttribute("title-style", modelField.getTitleStyle());
+        visitAttribute("tooltip", modelField.getTooltip());
+        visitAttribute("tooltip-style", modelField.getTooltipStyle());
+        visitAttribute("use-when", modelField.getUseWhen());
+        visitAttribute("widget-area-style", modelField.getWidgetAreaStyle());
+        visitAttribute("widget-style", modelField.getWidgetStyle());
+        writer.append(">");
+        visitUpdateAreas(modelField.getOnChangeUpdateAreas());
+        visitUpdateAreas(modelField.getOnClickUpdateAreas());
+    }
+
+    private void visitSubHyperlink(SubHyperlink hyperlink) throws Exception {
+        if (hyperlink != null) {
+            writer.append("<sub-hyperlink");
+            Link link = hyperlink.getLink();
+            visitLinkAttributes(link);
+            visitAttribute("description", hyperlink.getDescription());
+            visitAttribute("use-when", hyperlink.getUseWhen());
+            if (link.getImage() != null || link.getAutoEntityParameters() != null || link.getAutoServiceParameters() != null) {
+                writer.append(">");
+                visitImage(link.getImage());
+                visitAutoEntityParameters(link.getAutoEntityParameters());
+                visitAutoServiceParameters(link.getAutoServiceParameters());
+                writer.append("</sub-hyperlink>");
+            } else {
+                writer.append("/>");
+            }
+        }
+    }
+
+    private void visitAutoComplete(AutoComplete autoComplete) throws Exception {
+        if (autoComplete != null) {
+            writer.append("<auto-complete");
+            visitAttribute("auto-select", autoComplete.getAutoSelect());
+            visitAttribute("frequency", autoComplete.getFrequency());
+            visitAttribute("min-chars", autoComplete.getMinChars());
+            visitAttribute("choices", autoComplete.getChoices());
+            visitAttribute("partial-search", autoComplete.getPartialSearch());
+            visitAttribute("partial-chars", autoComplete.getPartialChars());
+            visitAttribute("ignore-case", autoComplete.getIgnoreCase());
+            visitAttribute("full-search", autoComplete.getFullSearch());
+            writer.append("/>");
+        }
+    }
+
+    private void visitInPlaceEditor(InPlaceEditor editor) throws Exception {
+        if (editor != null) {
+            writer.append("<in-place-editor");
+            visitAttribute("cancel-control", editor.getCancelControl());
+            visitAttribute("cancel-text", editor.getCancelText());
+            visitAttribute("click-to-edit-text", editor.getClickToEditText());
+            visitAttribute("field-post-creation", editor.getFieldPostCreation());
+            visitAttribute("form-class-name", editor.getFormClassName());
+            visitAttribute("highlight-color", editor.getHighlightColor());
+            visitAttribute("highlight-end-color", editor.getHighlightEndColor());
+            visitAttribute("hover-class-name", editor.getHoverClassName());
+            visitAttribute("html-response", editor.getHtmlResponse());
+            visitAttribute("loading-class-name", editor.getLoadingClassName());
+            visitAttribute("loading-text", editor.getLoadingText());
+            visitAttribute("ok-control", editor.getOkControl());
+            visitAttribute("ok-text", editor.getOkText());
+            visitAttribute("param-name", editor.getParamName());
+            visitAttribute("saving-class-name", editor.getSavingClassName());
+            visitAttribute("saving-text", editor.getSavingText());
+            visitAttribute("submit-on-blur", editor.getSubmitOnBlur());
+            visitAttribute("text-before-controls", editor.getTextBeforeControls());
+            visitAttribute("text-after-controls", editor.getTextAfterControls());
+            visitAttribute("text-between-controls", editor.getTextBetweenControls());
+            visitAttribute("update-after-request-call", editor.getUpdateAfterRequestCall());
+            visitAttribute("url", editor.getUrl());
+            if (!editor.getCols().isEmpty() || !editor.getRows().isEmpty()) {
+                writer.append(">");
+                writer.append("<simple-editor");
+                visitAttribute("cols", editor.getCols());
+                visitAttribute("rows", editor.getRows());
+                writer.append("/></in-place-editor>");
+            } else {
+                writer.append("/>");
+            }
+        }
+    }
+
+    private void visitUpdateAreas(Collection<ModelForm.UpdateArea> updateAreas) throws Exception {
+        for (ModelForm.UpdateArea updateArea : updateAreas) {
+            writer.append("<on-field-event-update-area");
+            visitAttribute("event-type", updateArea.getEventType());
+            visitAttribute("area-id", updateArea.getAreaId());
+            visitAttribute("area-target", updateArea.getAreaTarget());
+            writer.append(">");
+            visitAutoEntityParameters(updateArea.getAutoEntityParameters());
+            visitAutoServiceParameters(updateArea.getAutoServiceParameters());
+            visitParameters(updateArea.getParameterList());
+            writer.append("</on-field-event-update-area>");
+        }
+    }
+}
diff --git a/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java
new file mode 100644
index 0000000..129eb26
--- /dev/null
+++ b/framework/widget/src/org/ofbiz/widget/model/XmlWidgetVisitor.java
@@ -0,0 +1,645 @@
+/*******************************************************************************
+ * 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.Collection;
+import java.util.Map;
+
+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.
+ * The generated XML is unformatted - if you want to
+ * "pretty print" the XML, then use a transformer.
+ *
+ */
+public class XmlWidgetVisitor extends XmlAbstractWidgetVisitor implements ModelWidgetVisitor {
+
+    private final ModelFieldVisitor fieldVisitor;
+    private final ModelActionVisitor actionVisitor;
+    private final ModelConditionVisitor conditionVisitor;
+
+    public XmlWidgetVisitor(Appendable writer) {
+        super(writer);
+        this.fieldVisitor = new XmlWidgetFieldVisitor(writer);
+        this.actionVisitor = new XmlWidgetActionVisitor(writer);
+        this.conditionVisitor = new XmlWidgetConditionVisitor(writer);
+    }
+
+    @Override
+    public void visit(Column column) throws Exception {
+        writer.append("<column");
+        visitModelWidget(column);
+        visitAttribute("id", column.getIdExdr());
+        visitAttribute("style", column.getStyleExdr());
+        writer.append(">");
+        visitSubWidgets(column.getSubWidgets());
+        writer.append("</column>");
+    }
+
+    @Override
+    public void visit(ColumnContainer columnContainer) throws Exception {
+        writer.append("<column-container");
+        visitModelWidget(columnContainer);
+        visitAttribute("id", columnContainer.getIdExdr());
+        visitAttribute("style", columnContainer.getStyleExdr());
+        writer.append(">");
+        visitSubWidgets(columnContainer.getColumns());
+        writer.append("</column-container>");
+    }
+
+    @Override
+    public void visit(Container container) throws Exception {
+        writer.append("<container");
+        visitModelWidget(container);
+        visitAttribute("auto-update-interval", container.getAutoUpdateInterval());
+        visitAttribute("auto-update-target", container.getAutoUpdateTargetExdr());
+        visitAttribute("id", container.getIdExdr());
+        visitAttribute("style", container.getStyleExdr());
+        writer.append(">");
+        visitSubWidgets(container.getSubWidgets());
+        writer.append("</container>");
+    }
+
+    @Override
+    public void visit(Content content) throws Exception {
+        writer.append("<content");
+        visitModelWidget(content);
+        visitAttribute("border", content.getBorder());
+        visitAttribute("content-id", content.getContentId());
+        visitAttribute("dataresource-id", content.getDataResourceId());
+        visitAttribute("edit-container-style", content.getEditContainerStyle());
+        visitAttribute("edit-request", content.getEditRequest());
+        visitAttribute("enable-edit-name", content.getEnableEditName());
+        visitAttribute("height", content.getHeight());
+        visitAttribute("width", content.getWidth());
+        visitAttribute("xml-escape", content.xmlEscape());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(DecoratorScreen decoratorScreen) throws Exception {
+        writer.append("<decorator-screen");
+        visitModelWidget(decoratorScreen);
+        visitAttribute("location", decoratorScreen.getLocationExdr());
+        writer.append(">");
+        visitSubWidgets(decoratorScreen.getSectionMap().values());
+        writer.append("</decorator-screen>");
+    }
+
+    @Override
+    public void visit(DecoratorSection decoratorSection) throws Exception {
+        writer.append("<decorator-section");
+        visitModelWidget(decoratorSection);
+        writer.append(">");
+        visitSubWidgets(decoratorSection.getSubWidgets());
+        writer.append("</decorator-screen>");
+    }
+
+    @Override
+    public void visit(DecoratorSectionInclude decoratorSectionInclude) throws Exception {
+        writer.append("<decorator-section-include");
+        visitModelWidget(decoratorSectionInclude);
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(Form form) throws Exception {
+        writer.append("<include-form");
+        visitModelWidget(form);
+        visitAttribute("location", form.getLocationExdr());
+        visitAttribute("share-scope", form.getShareScopeExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(HorizontalSeparator horizontalSeparator) throws Exception {
+        writer.append("<horizontal-separator");
+        visitModelWidget(horizontalSeparator);
+        visitAttribute("id", horizontalSeparator.getIdExdr());
+        visitAttribute("style", horizontalSeparator.getStyleExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(HtmlTemplate htmlTemplate) throws Exception {
+        writer.append("<html-template");
+        visitModelWidget(htmlTemplate);
+        visitAttribute("location", htmlTemplate.getLocationExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(HtmlTemplateDecorator htmlTemplateDecorator) throws Exception {
+        writer.append("<html-template-decorator");
+        visitModelWidget(htmlTemplateDecorator);
+        visitAttribute("location", htmlTemplateDecorator.getLocationExdr());
+        writer.append(">");
+        visitSubWidgets(htmlTemplateDecorator.getSectionMap().values());
+        writer.append("</html-template-decorator>");
+    }
+
+    @Override
+    public void visit(HtmlTemplateDecoratorSection htmlTemplateDecoratorSection) throws Exception {
+        writer.append("<html-template-decorator-section");
+        visitModelWidget(htmlTemplateDecoratorSection);
+        writer.append(">");
+        visitSubWidgets(htmlTemplateDecoratorSection.getSubWidgets());
+        writer.append("</html-template-decorator-section>");
+    }
+
+    @Override
+    public void visit(HtmlWidget htmlWidget) throws Exception {
+        visitSubWidgets(htmlWidget.getSubWidgets());
+    }
+
+    @Override
+    public void visit(IncludeScreen includeScreen) throws Exception {
+        writer.append("<include-screen");
+        visitModelWidget(includeScreen);
+        visitAttribute("location", includeScreen.getLocationExdr());
+        visitAttribute("share-scope", includeScreen.getShareScopeExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(IterateSectionWidget iterateSectionWidget) throws Exception {
+        writer.append("<iterate-section");
+        visitModelWidget(iterateSectionWidget);
+        visitAttribute("entry", iterateSectionWidget.getEntryNameExdr());
+        visitAttribute("key", iterateSectionWidget.getKeyNameExdr());
+        visitAttribute("list", iterateSectionWidget.getListNameExdr());
+        visitAttribute("paginate", iterateSectionWidget.getPaginate());
+        visitAttribute("paginate-target", iterateSectionWidget.getPaginateTarget());
+        visitAttribute("view-size", iterateSectionWidget.getViewSize());
+        writer.append(">");
+        visitSubWidgets(iterateSectionWidget.getSectionList());
+        writer.append("</iterate-section>");
+    }
+
+    @Override
+    public void visit(Label label) throws Exception {
+        writer.append("<label");
+        visitModelWidget(label);
+        visitAttribute("id", label.getIdExdr());
+        visitAttribute("style", label.getStyleExdr());
+        writer.append(">");
+        writer.append(label.getTextExdr().getOriginal());
+        writer.append("</label>");
+    }
+
+    @Override
+    public void visit(Menu menu) throws Exception {
+        writer.append("<include-menu");
+        visitModelWidget(menu);
+        visitAttribute("location", menu.getLocationExdr());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(ModelForm modelForm) throws Exception {
+        writer.append("<form");
+        visitModelWidget(modelForm);
+        if (modelForm.getParentModelForm() != null) {
+            visitAttribute("extends", modelForm.getParentModelForm().getName());
+            visitAttribute("extends-resource", modelForm.getParentModelForm().getFormLocation());
+        }
+        visitAttribute("view-size", modelForm.getDefaultViewSize());
+        visitAttribute("type", modelForm.getType());
+        visitAttribute("target", modelForm.getTarget());
+        visitAttribute("id", modelForm.getContainerId());
+        visitAttribute("style", modelForm.getContainerStyle());
+        visitAttribute("title", modelForm.getTitle());
+        visitAttribute("tooltip", modelForm.getTooltip());
+        visitAttribute("list-name", modelForm.getListName());
+        visitAttribute("list-entry-name", modelForm.getListEntryName());
+        visitAttribute("default-entity-name", modelForm.getDefaultEntityName());
+        visitAttribute("default-service-name", modelForm.getDefaultServiceName());
+        visitAttribute("form-title-area-style", modelForm.getFormTitleAreaStyle());
+        visitAttribute("form-widget-area-style", modelForm.getFormWidgetAreaStyle());
+        visitAttribute("default-title-area-style", modelForm.getDefaultTitleAreaStyle());
+        visitAttribute("default-widget-area-style", modelForm.getDefaultWidgetAreaStyle());
+        visitAttribute("odd-row-style", modelForm.getOddRowStyle());
+        visitAttribute("even-row-style", modelForm.getEvenRowStyle());
+        visitAttribute("default-table-style", modelForm.getDefaultTableStyle());
+        visitAttribute("header-row-style", modelForm.getHeaderRowStyle());
+        visitAttribute("default-title-style", modelForm.getDefaultTitleStyle());
+        visitAttribute("default-widget-style", modelForm.getDefaultWidgetStyle());
+        visitAttribute("default-tooltip-style", modelForm.getDefaultTooltipStyle());
+        visitAttribute("item-index-separator", modelForm.getItemIndexSeparator());
+        visitAttribute("separate-columns", modelForm.getSeparateColumns());
+        visitAttribute("group-columns", modelForm.getGroupColumns());
+        visitAttribute("target-type", modelForm.getTargetType());
+        visitAttribute("default-map-name", modelForm.getDefaultMapName());
+        visitAttribute("target-window", modelForm.getTargetWindow());
+        visitAttribute("hide-header", modelForm.getHideHeader());
+        visitAttribute("client-autocomplete-fields", modelForm.getClientAutocompleteFields());
+        visitAttribute("paginate-target", modelForm.getPaginateTarget());
+        visitAttribute("sort-field-parameter-name", modelForm.getSortFieldParameterName());
+        visitAttribute("default-required-field-style", modelForm.getDefaultRequiredFieldStyle());
+        visitAttribute("default-sort-field-style", modelForm.getDefaultSortFieldStyle());
+        visitAttribute("default-sort-field-asc-style", modelForm.getDefaultSortFieldAscStyle());
+        visitAttribute("default-sort-field-desc-style", modelForm.getDefaultSortFieldDescStyle());
+        visitAttribute("paginate-target-anchor", modelForm.getPaginateTargetAnchor());
+        visitAttribute("paginate-index-field", modelForm.getPaginateIndexField());
+        visitAttribute("paginate-size-field", modelForm.getPaginateSizeField());
+        visitAttribute("override-list-size", modelForm.getOverrideListSize());
+        visitAttribute("paginate-first-label", modelForm.getPaginateFirstLabel());
+        visitAttribute("paginate-previous-label", modelForm.getPaginatePreviousLabel());
+        visitAttribute("paginate-next-label", modelForm.getPaginateNextLabel());
+        visitAttribute("paginate-last-label", modelForm.getPaginateLastLabel());
+        visitAttribute("paginate-viewsize-label", modelForm.getPaginateViewSizeLabel());
+        visitAttribute("paginate-style", modelForm.getPaginateStyle());
+        visitAttribute("paginate", modelForm.getPaginate());
+        visitAttribute("skip-start", modelForm.getSkipStart());
+        visitAttribute("skip-end", modelForm.getSkipEnd());
+        visitAttribute("use-row-submit", modelForm.getUseRowSubmit());
+        visitAttribute("row-count", modelForm.getRowCount());
+        visitAttribute("focus-field-name", modelForm.getFocusFieldName());
+        writer.append(">");
+        if (!modelForm.getActions().isEmpty()) {
+            writer.append("<actions>");
+            visitActions(modelForm.getActions());
+            writer.append("</actions>");
+        }
+        if (!modelForm.getRowActions().isEmpty()) {
+            writer.append("<row-actions>");
+            visitActions(modelForm.getRowActions());
+            writer.append("</row-actions>");
+        }
+        for (ModelForm.AltRowStyle rowStyle : modelForm.getAltRowStyles()) {
+            writer.append("<alt-row-style");
+            visitAttribute("use-when", rowStyle.useWhen);
+            visitAttribute("style", rowStyle.style);
+            writer.append("/>");
+        }
+        for (ModelForm.AltTarget target : modelForm.getAltTargets()) {
+            writer.append("<alt-target");
+            visitAttribute("use-when", target.useWhen);
+            visitAttribute("target", target.targetExdr);
+            writer.append("/>");
+        }
+        for (ModelForm.AutoFieldsService service : modelForm.getAutoFieldsServices()) {
+            writer.append("<auto-fields-service");
+            visitAttribute("service-name", service.serviceName);
+            visitAttribute("map-name", service.mapName);
+            visitAttribute("default-field-type", service.defaultFieldType);
+            visitAttribute("default-position", service.defaultPosition);
+            writer.append("/>");
+        }
+        for (ModelForm.AutoFieldsEntity entity : modelForm.getAutoFieldsEntities()) {
+            writer.append("<auto-fields-entity");
+            visitAttribute("entity-name", entity.entityName);
+            visitAttribute("map-name", entity.mapName);
+            visitAttribute("default-field-type", entity.defaultFieldType);
+            visitAttribute("default-position", entity.defaultPosition);
+            writer.append("/>");
+        }
+        for (ModelFormField field : modelForm.getFieldList()) {
+            field.getFieldInfo().accept(fieldVisitor);
+        }
+        visitUpdateAreas(modelForm.getOnPaginateUpdateAreas());
+        visitUpdateAreas(modelForm.getOnSortColumnUpdateAreas());
+        visitUpdateAreas(modelForm.getOnSubmitUpdateAreas());
+        writer.append("</form>");
+    }
+
+    @Override
+    public void visit(ModelMenu modelMenu) throws Exception {
+        writer.append("<menu");
+        visitModelWidget(modelMenu);
+        if (modelMenu.getParentMenu() != null) {
+            visitAttribute("extends", modelMenu.getParentMenu().getName());
+            visitAttribute("extends-resource", modelMenu.getParentMenu().getMenuLocation());
+        }
+        visitAttribute("type", modelMenu.getType());
+        visitAttribute("target", modelMenu.getTarget());
+        visitAttribute("id", modelMenu.getId());
+        visitAttribute("title", modelMenu.getTitle());
+        visitAttribute("tooltip", modelMenu.getTooltip());
+        visitAttribute("default-entity-name", modelMenu.getDefaultEntityName());
+        visitAttribute("default-title-style", modelMenu.getDefaultTitleStyle());
+        visitAttribute("default-selected-style", modelMenu.getDefaultSelectedStyle());
+        visitAttribute("default-widget-style", modelMenu.getDefaultWidgetStyle());
+        visitAttribute("default-tooltip-style", modelMenu.getDefaultTooltipStyle());
+        visitAttribute("default-menu-item-name", modelMenu.getDefaultMenuItemName());
+        visitAttribute("default-permission-operation", modelMenu.getDefaultPermissionOperation());
+        visitAttribute("default-permission-entity-action", modelMenu.getDefaultPermissionEntityAction());
+        visitAttribute("default-associated-content-id", modelMenu.getDefaultAssociatedContentId());
+        visitAttribute("orientation", modelMenu.getOrientation());
+        visitAttribute("menu-width", modelMenu.getMenuWidth());
+        visitAttribute("default-cell-width", modelMenu.getDefaultCellWidth());
+        visitAttribute("default-hide-if-selected", modelMenu.getDefaultHideIfSelected());
+        visitAttribute("default-disabled-title-style", modelMenu.getDefaultDisabledTitleStyle());
+        visitAttribute("selected-menuitem-context-field-name", modelMenu.getSelectedMenuItemContextFieldName());
+        visitAttribute("menu-container-style", modelMenu.getMenuContainerStyleExdr());
+        visitAttribute("default-align", modelMenu.getDefaultAlign());
+        visitAttribute("default-align-style", modelMenu.getDefaultAlignStyle());
+        visitAttribute("fill-style", modelMenu.getFillStyle());
+        visitAttribute("extra-index", modelMenu.getExtraIndex());
+        writer.append(">");
+        if (!modelMenu.getActions().isEmpty()) {
+            writer.append("<actions>");
+            visitActions(modelMenu.getActions());
+            writer.append("</actions>");
+        }
+        for (ModelMenuItem menuItem : modelMenu.getMenuItemList()) {
+            menuItem.accept(this);
+        }
+        writer.append("</menu>");
+    }
+
+    @Override
+    public void visit(ModelMenuItem modelMenuItem) throws Exception {
+        writer.append("<menu-item");
+        visitModelWidget(modelMenuItem);
+        visitAttribute("entity-name", modelMenuItem.getEntityName());
+        visitAttribute("title", modelMenuItem.getTitle());
+        visitAttribute("tooltip", modelMenuItem.getTooltip());
+        visitAttribute("parent-portal-page-value", modelMenuItem.getParentPortalPageId());
+        visitAttribute("title-style", modelMenuItem.getTitleStyle());
+        visitAttribute("disabled-title-style", modelMenuItem.getDisabledTitleStyle());
+        visitAttribute("widget-style", modelMenuItem.getWidgetStyle());
+        visitAttribute("tooltip-style", modelMenuItem.getTooltipStyle());
+        visitAttribute("selected-style", modelMenuItem.getSelectedStyle());
+        visitAttribute("hide-if-selected", modelMenuItem.getHideIfSelected());
+        visitAttribute("disable-if-empty", modelMenuItem.getDisableIfEmpty());
+        visitAttribute("align", modelMenuItem.getAlign());
+        visitAttribute("align-style", modelMenuItem.getAlignStyle());
+        visitAttribute("position", modelMenuItem.getPosition());
+        visitAttribute("associated-content-id", modelMenuItem.getAssociatedContentId());
+        visitAttribute("cell-width", modelMenuItem.getCellWidth());
+        visitAttribute("sub-menu", modelMenuItem.getSubMenu());
+        writer.append(">");
+        if (modelMenuItem.getCondition() != null) {
+            modelMenuItem.getCondition().getCondition().accept(conditionVisitor);
+        }
+        if (!modelMenuItem.getActions().isEmpty()) {
+            writer.append("<actions>");
+            visitActions(modelMenuItem.getActions());
+            writer.append("</actions>");
+        }
+        if (modelMenuItem.getLink() != null) {
+            visitLink(modelMenuItem.getLink().getLink());
+        }
+        for (ModelMenuItem menuItem : modelMenuItem.getMenuItemList()) {
+            menuItem.accept(this);
+            ;
+        }
+        writer.append("</menu-item>");
+    }
+
+    @Override
+    public void visit(ModelNode modelNode) throws Exception {
+        writer.append("<node");
+        visitModelWidget(modelNode);
+        visitAttribute("expand-collapse-style", modelNode.getExpandCollapseStyle());
+        visitAttribute("wrap-style", modelNode.getWrapStyleExdr());
+        visitAttribute("render-style", modelNode.getRenderStyle());
+        visitAttribute("entry-name", modelNode.getEntryName());
+        visitAttribute("entity-name", modelNode.getEntityName());
+        visitAttribute("join-field-name", modelNode.getPkName());
+        writer.append(">");
+        if (modelNode.getCondition() != null) {
+            modelNode.getCondition().getCondition().accept(conditionVisitor);
+        }
+        if (!modelNode.getActions().isEmpty()) {
+            writer.append("<actions>");
+            visitActions(modelNode.getActions());
+            writer.append("</actions>");
+        }
+        if (!modelNode.getScreenNameExdr().isEmpty()) {
+            writer.append("<include-screen");
+            visitAttribute("name", modelNode.getScreenNameExdr());
+            visitAttribute("location", modelNode.getScreenLocationExdr());
+            visitAttribute("share-scope", modelNode.getShareScope());
+            visitAttribute("name", modelNode.getScreenNameExdr());
+            writer.append("/>");
+        }
+        if (modelNode.getLabel() != null) {
+            ModelNode.Label label = modelNode.getLabel();
+            writer.append("<label");
+            visitAttribute("id", label.getIdExdr());
+            visitAttribute("style", label.getStyleExdr());
+            writer.append(">");
+            writer.append(label.getTextExdr().getOriginal());
+            writer.append("</label>");
+        }
+        if (modelNode.getLink() != null) {
+            ModelNode.Link link = modelNode.getLink();
+            writer.append("<link");
+            visitAttribute("encode", link.getEncode());
+            visitAttribute("full-path", link.getFullPath());
+            visitAttribute("id", link.getIdExdr());
+            visitAttribute("link-type", link.getLinkType());
+            visitAttribute("prefix", link.getPrefixExdr());
+            visitAttribute("secure", link.getSecure());
+            visitAttribute("style", link.getStyleExdr());
+            visitAttribute("target", link.getTargetExdr());
+            visitAttribute("target-window", link.getTargetWindowExdr());
+            visitAttribute("text", link.getTextExdr());
+            visitAttribute("url-mode", link.getUrlMode());
+            if (!link.getParameterList().isEmpty()) {
+                writer.append(">");
+                visitParameters(link.getParameterList());
+                writer.append("</link>");
+            } else {
+                writer.append("/>");
+            }
+        }
+        writer.append("</node>");
+    }
+
+    @Override
+    public void visit(ModelScreen modelScreen) throws Exception {
+        writer.append("<screen");
+        visitModelWidget(modelScreen);
+        visitAttribute("transaction-timeout", modelScreen.getTransactionTimeout());
+        visitAttribute("use-transaction", modelScreen.getUseTransaction());
+        visitAttribute("use-cache", modelScreen.getUseCache());
+        writer.append(">");
+        modelScreen.getSection().accept(this);
+        writer.append("</screen>");
+    }
+
+    @Override
+    public void visit(ModelSubNode modelSubNode) throws Exception {
+        writer.append("<sub-node");
+        visitModelWidget(modelSubNode);
+        visitAttribute("node-name", modelSubNode.getNodeNameExdr());
+        writer.append(">");
+        if (!modelSubNode.getActions().isEmpty()) {
+            writer.append("<actions>");
+            visitActions(modelSubNode.getActions());
+            writer.append("</actions>");
+        }
+        writer.append("</sub-node>");
+    }
+
+    @Override
+    public void visit(ModelTree modelTree) throws Exception {
+        writer.append("<tree");
+        visitModelWidget(modelTree);
+        visitAttribute("root-node-name", modelTree.getRootNodeName());
+        visitAttribute("default-render-style", modelTree.getDefaultRenderStyle());
+        visitAttribute("render-style", modelTree.getDefaultRenderStyle());
+        visitAttribute("default-wrap-style", modelTree.getDefaultWrapStyleExdr());
+        visitAttribute("expand-collapse-request", modelTree.getExpandCollapseRequestExdr());
+        visitAttribute("trail-name", modelTree.getTrailNameExdr());
+        visitAttribute("force-child-check", modelTree.getForceChildCheck());
+        visitAttribute("entity-name", modelTree.getDefaultEntityName());
+        visitAttribute("open-depth", modelTree.getOpenDepth());
+        visitAttribute("post-trail-open-depth", modelTree.getPostTrailOpenDepth());
+        writer.append(">");
+        visitSubWidgets(modelTree.getNodeMap().values());
+        writer.append("</tree>");
+    }
+
+    @Override
+    public void visit(PlatformSpecific platformSpecific) throws Exception {
+        writer.append("<platform-specific>");
+        for (Map.Entry<String, ModelScreenWidget> entry : platformSpecific.getSubWidgets().entrySet()) {
+            writer.append("<").append(entry.getKey()).append(">");
+            entry.getValue().accept(this);
+            writer.append("</").append(entry.getKey()).append(">");
+        }
+        writer.append("</platform-specific>");
+    }
+
+    @Override
+    public void visit(PortalPage portalPage) throws Exception {
+        writer.append("<include-portal-page");
+        visitModelWidget(portalPage);
+        visitAttribute("id", portalPage.getIdExdr());
+        visitAttribute("conf-mode", portalPage.getConfModeExdr());
+        visitAttribute("use-private", portalPage.getUsePrivate());
+        writer.append("/>");
+    }
+
+    @Override
+    public void visit(ScreenImage image) throws Exception {
+        visitImage(image.getImage());
+    }
+
+    @Override
+    public void visit(Screenlet screenlet) throws Exception {
+        writer.append("<screenlet");
+        visitModelWidget(screenlet);
+        visitAttribute("id", screenlet.getIdExdr());
+        visitAttribute("collapsible", screenlet.getCollapsible());
+        visitAttribute("initially-collapsed", screenlet.getInitiallyCollapsed());
+        visitAttribute("save-collapsed", screenlet.getSaveCollapsed());
+        visitAttribute("padded", screenlet.getPadded());
+        visitAttribute("title", screenlet.getTitleExdr());
+        writer.append(">");
+        visitSubWidgets(screenlet.getSubWidgets());
+        writer.append("</screenlet>");
+    }
+
+    @Override
+    public void visit(ScreenLink link) throws Exception {
+        visitLink(link.getLink());
+    }
+
+    @Override
+    public void visit(Section section) throws Exception {
+        writer.append("<section");
+        visitModelWidget(section);
+        writer.append(">");
+        if (section.getCondition() != null) {
+            writer.append("<condition>");
+            section.getCondition().accept(conditionVisitor);
+            writer.append("</condition>");
+        }
+        if (!section.getActions().isEmpty()) {
+            writer.append("<actions>");
+            visitActions(section.getActions());
+            writer.append("</actions>");
+        }
+        if (!section.getSubWidgets().isEmpty()) {
+            writer.append("<widgets>");
+            visitSubWidgets(section.getSubWidgets());
+            writer.append("</widgets>");
+        }
+        if (!section.getFailWidgets().isEmpty()) {
+            writer.append("<fail-widgets>");
+            visitSubWidgets(section.getFailWidgets());
+            writer.append("</fail-widgets>");
+        }
+        writer.append("</section>");
+    }
+
+    @Override
+    public void visit(Tree tree) throws Exception {
+        writer.append("<include-tree");
+        visitModelWidget(tree);
+        visitAttribute("location", tree.getLocationExdr());
+        visitAttribute("share-scope", tree.getShareScopeExdr());
+        writer.append("/>");
+    }
+
+    private void visitActions(Collection<? extends ModelAction> actions) throws Exception {
+        for (ModelAction action : actions) {
+            action.accept(actionVisitor);
+        }
+    }
+
+    private void visitSubWidgets(Collection<? extends ModelWidget> subWidgets) throws Exception {
+        for (ModelWidget subWidget : subWidgets) {
+            subWidget.accept(this);
+        }
+    }
+
+    private void visitUpdateAreas(Collection<ModelForm.UpdateArea> updateAreas) throws Exception {
+        for (ModelForm.UpdateArea updateArea : updateAreas) {
+            writer.append("<on-event-update-area");
+            visitAttribute("event-type", updateArea.getEventType());
+            visitAttribute("area-id", updateArea.getAreaId());
+            visitAttribute("area-target", updateArea.getAreaTarget());
+            writer.append(">");
+            visitAutoEntityParameters(updateArea.getAutoEntityParameters());
+            visitAutoServiceParameters(updateArea.getAutoServiceParameters());
+            visitParameters(updateArea.getParameterList());
+            writer.append("</on-event-update-area>");
+        }
+    }
+}
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 9f0fd37..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.ModelWidgetAction;
 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.
@@ -736,7 +739,7 @@
                 previousItem = new HashMap<String, Object>();
                 previousItem.putAll(itemMap);
 
-                ModelWidgetAction.runSubActions(modelForm.getRowActions(), localContext);
+                AbstractModelAction.runSubActions(modelForm.getRowActions(), localContext);
 
                 localContext.put("itemIndex", Integer.valueOf(itemIndex - lowIndex));
                 if (UtilValidate.isNotEmpty(context.get("renderFormSeqNumber"))) {
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 87%
rename from framework/widget/src/org/ofbiz/widget/menu/MenuStringRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/MenuStringRenderer.java
index 95b0990..b1bf5c3 100644
--- a/framework/widget/src/org/ofbiz/widget/menu/MenuStringRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/MenuStringRenderer.java
@@ -1,37 +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;
-
-
-/**
- * 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.Link link) throws IOException ;
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelMenuItem.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 95%
rename from framework/widget/src/org/ofbiz/widget/screen/ScreenStringRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/ScreenStringRenderer.java
index 4b655b2..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.Link link) throws IOException;
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.Image 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 94%
rename from framework/widget/src/org/ofbiz/widget/fo/FoScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/fo/FoScreenRenderer.java
index 3a07244..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.Link link) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.Image 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 95%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
index ad22ced..18998c3 100644
--- a/framework/widget/src/org/ofbiz/widget/html/HtmlFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/html/HtmlFormRenderer.java
@@ -1,2822 +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.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.getTargetType(), 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.getLinkStyle(), subHyperlink.getTargetType(), subHyperlink.getTarget(context),
-                    subHyperlink.getParameterMap(context), description, subHyperlink.getTargetWindow(context), subHyperlink.getConfirmation(context), 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.isAllowMultiple()) {
-                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.isAllowEmpty()) {
-                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 = HyperlinkField.DEFAULT_TARGET_TYPE;
-            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 97%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlMenuRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlMenuRenderer.java
index 59a0527..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.menu.ModelMenuItem.Image;
-import org.ofbiz.widget.menu.ModelMenuItem.Link;
-
-/**
- * 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(">");
-
-        Link 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.Link 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 = link.getConfirmation(context);
-            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, ModelMenuItem.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 92%
rename from framework/widget/src/org/ofbiz/widget/html/HtmlScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/html/HtmlScreenRenderer.java
index 68e8874..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.ColumnContainer;
-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, 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 {
-        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, ModelScreenWidget.Container container) throws IOException {
-        writer.append("</div>");
-        appendWhitespace(writer);
-    }
-
-    public void renderHorizontalSeparator(Appendable writer, Map<String, Object> context, ModelScreenWidget.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, 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);
-        }
-        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);
-        ModelScreenWidget.Menu navMenu = screenlet.getNavigationMenu();
-        ModelScreenWidget.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, 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 = 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, 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");
-                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, ModelScreenWidget.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, 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);
-        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, ModelScreenWidget.Link 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
-        ModelScreenWidget.Image 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, ModelScreenWidget.Image 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, ModelScreenWidget.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, 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 {
-
-                //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, ModelScreenWidget.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, ModelScreenWidget.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, ModelScreenWidget.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, ModelScreenWidget.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, 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.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 97%
rename from framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
index 376b94b..a369bea 100644
--- a/framework/widget/src/org/ofbiz/widget/form/MacroFormRenderer.java
+++ b/framework/widget/src/org/ofbiz/widget/renderer/macro/MacroFormRenderer.java
@@ -1,3121 +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.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.getTargetType(), 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.isAllowMultiple() ? "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.isAllowEmpty()) {
-            allowEmpty = "Y";
-        }
-        List<String> currentValueList = null;
-        if (UtilValidate.isNotEmpty(currentValue) && dropDownField.isAllowMultiple()) {
-            // 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 = HyperlinkField.DEFAULT_TARGET_TYPE;
-                    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.getLinkStyle(), subHyperlink.getTargetType(), subHyperlink.getTarget(context), subHyperlink.getParameterMap(context), subHyperlink.getDescription(context), subHyperlink.getTargetWindow(context), subHyperlink
-                    .getConfirmation(context), 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<WidgetWorker.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 (WidgetWorker.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 3c051ee..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.ModelWidget;
 import org.ofbiz.widget.WidgetWorker;
-import org.ofbiz.widget.menu.ModelMenuItem.Image;
-import org.ofbiz.widget.menu.ModelMenuItem.Link;
+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;
@@ -190,7 +193,7 @@
     }
 
     @Override
-    public void renderLink(Appendable writer, Map<String, Object> context, Link link) throws IOException {
+    public void renderLink(Appendable writer, Map<String, Object> context, MenuLink link) throws IOException {
         Map<String, Object> parameters = new HashMap<String, Object>();
         String target = link.getTarget(context);
         ModelMenuItem menuItem = link.getLinkMenuItem();
@@ -303,7 +306,7 @@
         parameters.put("style", style);
         parameters.put("toolTip", menuItem.getTooltip(context));
         String linkStr = "";
-        Link link = menuItem.getLink();
+        MenuLink link = menuItem.getLink();
         if (link != null) {
             StringWriter sw = new StringWriter();
             renderLink(sw, context, link);
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 97%
rename from framework/widget/src/org/ofbiz/widget/screen/MacroScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/macro/MacroScreenRenderer.java
index cea39e8..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.Link 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.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("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.Image 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 95%
rename from framework/widget/src/org/ofbiz/widget/text/TextScreenRenderer.java
rename to framework/widget/src/org/ofbiz/widget/renderer/text/TextScreenRenderer.java
index a966850..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.Link link) throws IOException {
-        // TODO: not implemented
-    }
-
-    public void renderImage(Appendable writer, Map<String, Object> context, ModelScreenWidget.Image 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/config/EcommerceUiLabels.xml b/specialpurpose/ecommerce/config/EcommerceUiLabels.xml
index fca8c71..50eb273 100644
--- a/specialpurpose/ecommerce/config/EcommerceUiLabels.xml
+++ b/specialpurpose/ecommerce/config/EcommerceUiLabels.xml
@@ -5159,4 +5159,7 @@
         <value xml:lang="zh">浏览询价</value>
         <value xml:lang="zh-TW">檢視報價</value>
     </property>
+    <property key="ThankYouForContactingUs">
+        <value xml:lang="en">Thank You for contacting us.</value>
+    </property>
 </resource>
diff --git a/specialpurpose/ecommerce/script/org/ofbiz/ecommerce/customer/CustomerEvents.xml b/specialpurpose/ecommerce/script/org/ofbiz/ecommerce/customer/CustomerEvents.xml
index 7c1dab1..0ce2137 100644
--- a/specialpurpose/ecommerce/script/org/ofbiz/ecommerce/customer/CustomerEvents.xml
+++ b/specialpurpose/ecommerce/script/org/ofbiz/ecommerce/customer/CustomerEvents.xml
@@ -1308,10 +1308,10 @@
                 <set field="parameters.contactMechIdFrom" from-field="contact.contactMechId"/>
             </else>
         </if-empty>
-        <set-service-fields service-name="createCommunicationEventWithoutPermission" to-map="newComm" map="parameters"/>
-        <set field="newComm.partyIdFrom" from-field="parameters.partyId"/>
-        <call-service service-name="createCommunicationEventWithoutPermission" in-map-name="newComm">
-            <default-message property="CommonGenericServiceSuccessMessage" resource="CommonUiLabels"></default-message>
+        <set-service-fields service-name="sendContactUsEmailToCompany" to-map="newComm" map="parameters"/>
+        <set field="newComm.emailType" value="CONT_NOTI_EMAIL"/>
+        <call-service service-name="sendContactUsEmailToCompany" in-map-name="newComm">
+            <default-message property="ThankYouForContactingUs" resource="EcommerceUiLabels"></default-message>
         </call-service>
     </simple-method>
     <simple-method method-name="fromSetSessionLocale" 
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 a938312..7ebedd9 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.ecommerce.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/ecommerce/webapp/ecommerce/customer/miniSignUpForContactList.ftl b/specialpurpose/ecommerce/webapp/ecommerce/customer/miniSignUpForContactList.ftl
index bd66303..9e67e5b 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/customer/miniSignUpForContactList.ftl
+++ b/specialpurpose/ecommerce/webapp/ecommerce/customer/miniSignUpForContactList.ftl
@@ -65,7 +65,8 @@
             <@contactList publicEmailContactLists=publicEmailContactLists/>
           </div>
           <div>
-            <select name="preferredContactMechId" class="selectBox">
+            <label for="preferredContactMechId">${uiLabelMap.CommonEmail} *</label>
+            <select id="preferredContactMechId" name="preferredContactMechId" class="selectBox">
               <#list partyAndContactMechList as partyAndContactMech>
                 <option value="${partyAndContactMech.contactMechId}"><#if partyAndContactMech.infoString?has_content>${partyAndContactMech.infoString}<#elseif partyAndContactMech.tnContactNumber?has_content>${partyAndContactMech.tnCountryCode!}-${partyAndContactMech.tnAreaCode!}-${partyAndContactMech.tnContactNumber}<#elseif partyAndContactMech.paAddress1?has_content>${partyAndContactMech.paAddress1}, ${partyAndContactMech.paAddress2!}, ${partyAndContactMech.paCity!}, ${partyAndContactMech.paStateProvinceGeoId!}, ${partyAndContactMech.paPostalCode!}, ${partyAndContactMech.paPostalCodeExt!} ${partyAndContactMech.paCountryGeoId!}</#if></option>
               </#list>
@@ -95,7 +96,8 @@
           <@contactList publicEmailContactLists=publicEmailContactLists/>
         </div>
         <div>
-          <input name="email" class="inputBox" type="text"/>
+          <label for="email">${uiLabelMap.CommonEmail} *</label>
+          <input id="email" name="email" class="required" type="text"/>
         </div>
         <div>
           <input type="submit" value="${uiLabelMap.EcommerceSubscribe}"/>
diff --git a/specialpurpose/ecommerce/webapp/ecommerce/order/checkoutshippingoptions.ftl b/specialpurpose/ecommerce/webapp/ecommerce/order/checkoutshippingoptions.ftl
index 237c128..a930b48 100644
--- a/specialpurpose/ecommerce/webapp/ecommerce/order/checkoutshippingoptions.ftl
+++ b/specialpurpose/ecommerce/webapp/ecommerce/order/checkoutshippingoptions.ftl
@@ -59,6 +59,7 @@
 </script>
 
 <form method="post" name="checkoutInfoForm" style="margin:0;">
+  <fieldset>
     <input type="hidden" name="checkoutpage" value="shippingoptions"/>
 
     <div class="screenlet" style="height: 100%;">
@@ -187,6 +188,7 @@
             </table>
         </div>
     </div>
+  </fieldset>
 </form>
 
 <table width="100%">
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/scrum/widget/scrumForms.xml b/specialpurpose/scrum/widget/scrumForms.xml
index 4657bf0..0277550 100644
--- a/specialpurpose/scrum/widget/scrumForms.xml
+++ b/specialpurpose/scrum/widget/scrumForms.xml
@@ -2050,7 +2050,7 @@
         </row-actions>
         <field name="productId" title="${uiLabelMap.PageTitleProduct}" position="1" use-when="showPosition1">
             <display-entity entity-name="Product" description="${internalName} " key-field-name="productId">
-                <sub-hyperlink target="ViewProduc" description="[${productId}]">
+                <sub-hyperlink target="ViewProduct" description="[${productId}]">
                     <parameter param-name="productId"/>
                 </sub-hyperlink>
             </display-entity>
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>
