Keeps in sync with OFBiz trunk HEAD

git-svn-id: https://svn.apache.org/repos/asf/ofbiz/branches/OFBIZ-5312-ofbiz-ecommerce-seo-2013-10-23@1652969 13f79535-47bb-0310-9956-ffa450edef68
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;
-    }
-